ANNarchy iCub Interface 1.1.1
Loading...
Searching...
No Matches
VisionPopulation.py
1"""
2 Copyright (C) 2021-2022 Torsten Fietzek; Helge Ülo Dinkelbach
3
4 VisionPopulation.py is part of the ANNarchy iCub interface
5
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 The ANNarchy iCub interface is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this headers. If not, see [http://www.gnu.org/licenses/].
18 """
19import ANN_iCub_Interface
20from ANNarchy.core.Neuron import Neuron
21from ANNarchy.core.Global import dt
22try:
23 from ANNarchy.intern.SpecificPopulation import SpecificPopulation
24 from ANNarchy.intern.Messages import _error
25
26except:
27 from ANNarchy.core.SpecificPopulation import SpecificPopulation
28 from ANNarchy.core.Global import _error
29
30
31class VisionPopulation(SpecificPopulation):
32 """
33 ANNarchy population class to connect with the iCub cameras.
34 Read the camera images from the iCub, preprocess the images and set it as activation for the ANNarchy population.
35 """
36
37 def __init__(self, geometry=(320, 240), ip_address="0.0.0.0", port=50000, copied=False, name=None):
38 """Init the VisionPopulation.
39
40 Args:
41 geometry (tuple, optional): ANNarchy population geometry. Defaults to (320,240).
42 ip_address (str, optional): ip-address of the gRPC connection. Need to fit with the respective visual reader module. Defaults to "0.0.0.0".
43 port (int, optional): port of the gRPC connection. Need to fit with the respective visual reader module. Defaults to 50000.
44 copied (bool, optional): ANNarchy specific parameter. Defaults to False.
45 name (str, optional): individiual name for the population. Defaults to None.
46 """
47 SpecificPopulation.__init__(self, geometry=geometry, neuron=Neuron(equations="r = 0.0"), copied=copied, name=name)
48
49 self._ip_address = ip_address
50 self._port = port
51 self._period = 1
52 self._offset = 0
53
55 SpecificPopulation._init_attributes(self)
56
57 self.cyInstance.set_ip_address(self._ip_address)
58 self.cyInstance.set_port(self._port)
59 self.cyInstance.set_offset(self._offset)
60 self.cyInstance.set_period(self._period)
61
62 def _copy(self):
63 return VisionPopulation(geometry=self.geometry, ip_address=self._ip_address, port=self._port, copied=True, name=self.name)
64
65 @property
66 def ip_address(self):
67 if self.initialized:
68 return self.cyInstance.get_ip_address()
69 else:
70 _error("Read-out IP address is only valid after compile().")
71
72 @ip_address.setter
73 def ip_address(self, value):
74 if self.initialized:
75 self.cyInstance.set_ip_address(value)
76 else:
77 _error("Changing IP address is only valid after compile() or constructor.")
78
79 @property
80 def port(self):
81 if self.initialized:
82 return self.cyInstance.get_port()
83 else:
84 _error("Read-out port is only valid after compile().")
85
86 @port.setter
87 def port(self, value):
88 if self.initialized:
89 self.cyInstance.set_port(value)
90 else:
91 _error("Changing port is only valid after compile() or constructor.")
92
93 @property
94 def period(self):
95 if self.initialized:
96 return self.cyInstance.get_period()*dt()
97 else:
98 _error("Read-out period is only valid after compile().")
99
100 @period.setter
101 def period(self, value):
102 if self.initialized:
103 self.cyInstance.set_period(value/dt())
104 else:
105 _error("Changing period is only valid after compile() or constructor.")
106
107 @property
108 def offset(self):
109 if self.initialized:
110 return self.cyInstance.get_offset()
111 else:
112 _error("Read-out offset is only valid after compile().")
113
114 @offset.setter
115 def offset(self, value):
116 if self.initialized:
117 self.cyInstance.set_offset(value)
118 else:
119 _error("Changing offset is only valid after compile() or constructor.")
120
121 def _generate(self):
122 """
123 read out code for iCub through gRPC
124 """
125 include_paths = ANN_iCub_Interface.__path__[0]+"/grpc/"
126
127 self._specific_template['include_additional'] = """// grpc stuff
128#include "ANN_iCub_Interface/grpc/ProvideInputClient.h"
129"""
130 self._specific_template['declare_additional'] = """
131 std::string ip_address;
132 unsigned int port;
133 unsigned int period;
134 unsigned int offset;
135
136 ClientInstance* image_source=nullptr;
137 """
138 self._specific_template['access_additional'] = """
139 // Image Source ip address
140 void set_ip_address(std::string value) {
141 ip_address = value;
142 }
143 std::string get_ip_address() {
144 return ip_address;
145 }
146
147 // Image Source port
148 void set_port(unsigned int value) {
149 port = value;
150 }
151 unsigned int get_port() {
152 return port;
153 }
154
155 // Image Source period
156 void set_period(unsigned int value) {
157 period = value;
158 }
159 unsigned int get_period() {
160 return period;
161 }
162
163 // Image Source offset
164 void set_offset(unsigned int value) {
165 offset = value;
166 }
167 unsigned int get_offset() {
168 return offset;
169 }
170
171 void connect() {
172 if (image_source == nullptr) {
173 image_source = new ClientInstance(ip_address, port);
174 } else {
175 std::cerr << "Population %(name)s already connected" << std::endl;
176 }
177 }
178 """ % {'name': self.name}
179 self._specific_template['export_additional'] = """
180 # IP Address and port
181 void set_ip_address(string)
182 string get_ip_address()
183 void set_port(unsigned int)
184 unsigned int get_port()
185
186 void set_period(unsigned int value)
187 unsigned int get_period()
188 void set_offset(unsigned int value)
189 unsigned int get_offset()
190
191 void connect()
192"""
193 self._specific_template['wrapper_access_additional'] = """
194 # IP Address and port
195 def set_ip_address(self, value):
196 pop%(id)s.set_ip_address(value.encode('utf-8'))
197 def get_ip_address(self):
198 return pop%(id)s.get_ip_address()
199 def set_port(self, value):
200 pop%(id)s.set_port(value)
201 def get_port(self):
202 return pop%(id)s.get_port()
203
204 def set_period(self, value):
205 pop%(id)s.set_period(value)
206 def get_period(self):
207 return pop%(id)s.get_period()
208 def set_offset(self, value):
209 pop%(id)s.set_offset(value)
210 def get_offset(self):
211 return pop%(id)s.get_offset()
212
213 def connect(self):
214 pop%(id)s.connect()
215""" %{'id': self.id}
216
217 self._specific_template['update_variables'] = """
218 #pragma omp single
219 {
220 if((t%period==offset) && _active){
221 r = image_source->retrieve_image();
222 }
223 }
224 """
225
226 def _instantiate(self, cython_module):
227 # initializes cython wrapper
228 SpecificPopulation._instantiate(self, cython_module)
229
230 def connect(self):
231 """Connect the population to the gRPC socket. Need to be called once after compile."""
232 # create socket and connect
233 if self.initialized:
234 self.cyInstance.connect()
__init__(self, geometry=(320, 240), ip_address="0.0.0.0", port=50000, copied=False, name=None)