@@ -86,18 +86,22 @@ NeuralNetwork::NeuralNetwork(
86
86
// motors, creating the adequate neurons in place as we do so.
87
87
88
88
// Map of ID to neuron element
89
+ // neuron.id ---> sdf_element
89
90
std::map< std::string, sdf::ElementPtr > neuronMap;
91
+ std::map< std::string, std::vector<sdf::ElementPtr> > neuronPartIdMap;
90
92
91
- // List of all hidden neurons for convenience
93
+ // List of all hidden neurons (ids) for convenience
92
94
std::vector< std::string > hiddenNeurons;
93
95
94
- // Set for tracking all collected input/output neurons
96
+ // Set for tracking all collected input/output neurons (ids)
95
97
std::set< std::string > toProcess;
96
98
99
+ auto controller_settings = _settings->GetElement (" rv:controller" );
100
+
97
101
// Fetch the first neuron; note the HasElement call is necessary to
98
102
// prevent SDF from complaining if no neurons are present.
99
- auto neuron = _settings ->HasElement (" rv:neuron" )
100
- ? _settings ->GetElement (" rv:neuron" )
103
+ auto neuron = controller_settings ->HasElement (" rv:neuron" )
104
+ ? controller_settings ->GetElement (" rv:neuron" )
101
105
: sdf::ElementPtr ();
102
106
while (neuron)
103
107
{
@@ -109,8 +113,9 @@ NeuralNetwork::NeuralNetwork(
109
113
}
110
114
auto layer = neuron->GetAttribute (" layer" )->GetAsString ();
111
115
auto neuronId = neuron->GetAttribute (" id" )->GetAsString ();
116
+ auto neuronPartId = neuron->GetAttribute (" part_id" )->GetAsString ();
112
117
113
- if (this ->layerMap_ .count (neuronId))
118
+ if (this ->layerMap_ .count (neuronId) == 1 )
114
119
{
115
120
std::cerr << " Duplicate neuron ID '" << neuronId << " '" << std::endl;
116
121
throw std::runtime_error (" Robot brain error" );
@@ -119,6 +124,12 @@ NeuralNetwork::NeuralNetwork(
119
124
this ->layerMap_ [neuronId] = layer;
120
125
neuronMap[neuronId] = neuron;
121
126
127
+ if (neuronPartIdMap.find (neuronPartId) == neuronPartIdMap.end ()) {
128
+ neuronPartIdMap[neuronPartId] = std::vector<sdf::ElementPtr>();
129
+ }
130
+ neuronPartIdMap[neuronPartId].push_back (neuron);
131
+
132
+ // INPUT LAYER
122
133
if (" input" == layer)
123
134
{
124
135
if (this ->nInputs_ >= MAX_INPUT_NEURONS)
@@ -132,6 +143,7 @@ NeuralNetwork::NeuralNetwork(
132
143
toProcess.insert (neuronId);
133
144
++(this ->nInputs_ );
134
145
}
146
+ // OUTPUT LAYER
135
147
else if (" output" == layer)
136
148
{
137
149
if (this ->nOutputs_ >= MAX_OUTPUT_NEURONS)
@@ -145,6 +157,7 @@ NeuralNetwork::NeuralNetwork(
145
157
toProcess.insert (neuronId);
146
158
++(this ->nOutputs_ );
147
159
}
160
+ // HIDDEN LAYER
148
161
else if (" hidden" == layer)
149
162
{
150
163
if (hiddenNeurons.size () >= MAX_HIDDEN_NEURONS)
@@ -157,7 +170,7 @@ NeuralNetwork::NeuralNetwork(
157
170
}
158
171
159
172
hiddenNeurons.push_back (neuronId);
160
- ++(this ->nHidden_ );
173
+ ++(this ->nHidden_ );
161
174
}
162
175
else
163
176
{
@@ -171,70 +184,80 @@ NeuralNetwork::NeuralNetwork(
171
184
// Create motor output neurons at the correct position
172
185
// We iterate a part's motors and just assign every
173
186
// neuron we find in order.
174
- std::map< std::string, unsigned int > outputCountMap;
175
187
unsigned int outputsIndex = 0 ;
176
188
for (const auto &motor : _motors)
177
189
{
178
- auto partId = motor->PartId ();
179
- if (not outputCountMap.count (partId))
190
+ std::string partId = motor->PartId ();
191
+ auto details = neuronPartIdMap.find (partId);
192
+ if (details == neuronPartIdMap.end ())
180
193
{
181
- outputCountMap[partId] = 0 ;
194
+ std::cerr << " Required output neuron " << partId
195
+ << " for motor could not be located" << std::endl;
196
+ throw std::runtime_error (" Robot brain error" );
182
197
}
183
198
199
+ const auto &neuron_list = details->second ;
200
+ auto neuron_iter = neuron_list.cbegin ();
201
+
184
202
for (unsigned int i = 0 , l = motor->Outputs (); i < l; ++i)
185
203
{
186
- std::stringstream neuronId;
187
- neuronId << partId << " -out- " << outputCountMap[partId];
188
- ++outputCountMap[partId] ;
189
-
190
- auto details = neuronMap. find (neuronId. str ());
191
- if (details == neuronMap. end ())
192
- {
193
- std::cerr << " Required output neuron " << neuronId. str ()
194
- << " for motor could not be located " << std::endl;
195
- throw std::runtime_error ( " Robot brain error " );
196
- }
204
+ while ( not ((*neuron_iter)-> GetAttribute ( " layer " )-> GetAsString () == " output " ))
205
+ {
206
+ ++neuron_iter ;
207
+ if (neuron_iter == neuron_list. cend ())
208
+ {
209
+ std::cerr << " Required input neuron " << partId
210
+ << " for sensor could not be located " << std::endl;
211
+ throw std::runtime_error ( " Robot brain error " );
212
+ }
213
+ }
214
+ std::string neuronId = (*neuron_iter)-> GetAttribute ( " id " )-> GetAsString ();
197
215
198
216
neuronHelper (&this ->params_ [outputsIndex * MAX_NEURON_PARAMS],
199
217
&this ->types_ [outputsIndex],
200
- details-> second );
201
- this ->positionMap_ [neuronId. str () ] = outputsIndex;
202
- toProcess.erase (neuronId. str () );
218
+ *neuron_iter );
219
+ this ->positionMap_ [neuronId] = outputsIndex;
220
+ toProcess.erase (neuronId);
203
221
++outputsIndex;
222
+ ++neuron_iter;
204
223
}
205
224
}
206
225
207
226
// Create sensor input neurons
208
- std::map< std::string, unsigned int > inputCountMap;
209
227
unsigned int inputsIndex = 0 ;
210
228
for (const auto &sensor : _sensors)
211
229
{
212
230
auto partId = sensor->PartId ();
213
-
214
- if (not inputCountMap. count (partId ))
231
+ auto details = neuronPartIdMap. find (partId);
232
+ if (details == neuronPartIdMap. end ( ))
215
233
{
216
- inputCountMap[partId] = 0 ;
234
+ std::cerr << " Required input neuron list " << partId
235
+ << " for sensor could not be located" << std::endl;
236
+ throw std::runtime_error (" Robot brain error" );
217
237
}
238
+ const auto &neuron_list = details->second ;
239
+ auto neuron_iter = neuron_list.cbegin ();
218
240
219
241
for (unsigned int i = 0 , l = sensor->Inputs (); i < l; ++i)
220
242
{
221
- std::stringstream neuronId;
222
- neuronId << partId << " -in-" << inputCountMap[partId];
223
- ++inputCountMap[partId];
224
-
225
- auto details = neuronMap.find (neuronId.str ());
226
- if (details == neuronMap.end ())
243
+ while (not ((*neuron_iter)->GetAttribute (" layer" )->GetAsString () == " input" ))
227
244
{
228
- std::cerr << " Required input neuron " << neuronId.str ()
229
- << " for sensor could not be located" << std::endl;
230
- throw std::runtime_error (" Robot brain error" );
245
+ ++neuron_iter;
246
+ if (neuron_iter == neuron_list.cend ())
247
+ {
248
+ std::cerr << " Required input neuron " << partId
249
+ << " for sensor could not be located" << std::endl;
250
+ throw std::runtime_error (" Robot brain error" );
251
+ }
231
252
}
253
+ std::string neuronId = (*neuron_iter)->GetAttribute (" id" )->GetAsString ();
232
254
233
255
// Input neurons can currently not have a type, so
234
256
// there is no need to process it.
235
- this ->positionMap_ [neuronId. str () ] = inputsIndex;
236
- toProcess.erase (neuronId. str () );
257
+ this ->positionMap_ [neuronId] = inputsIndex;
258
+ toProcess.erase (neuronId);
237
259
++inputsIndex;
260
+ ++neuron_iter;
238
261
}
239
262
}
240
263
0 commit comments