Main Page · Modules · All Classes · Class Hierarchy
MARobotState.cpp
1 /*
2  * This file is part of the AiBO+ project
3  *
4  * Copyright (C) 2005-2016 Csaba Kertész (csaba.kertesz@gmail.com)
5  *
6  * AiBO+ 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 2 of the License, or
9  * (at your option) any later version.
10  *
11  * AiBO+ 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 program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
19  *
20  */
21 
22 #include "MARobotState.hpp"
23 
24 #include "core/MANum.hpp"
25 #include "ml/MAClassifierModels.hpp"
26 #include "MAAudio.hpp"
27 #include "MABodyMotion.hpp"
28 #include "MAComplexIndicators.hpp"
29 #include "MAEmotions.hpp"
30 #include "MAGoals.hpp"
31 #include "MAHead.hpp"
32 #include "MAHri.hpp"
33 #include "MATorso.hpp"
34 #include "MATypeRanges.hpp"
35 
36 #include <MCBinaryData.hpp>
37 #include <MCContainers.hpp>
38 #include <MCLog.hpp>
39 
40 #include <boost/algorithm/string.hpp>
41 
42 #define BIND_VARIABLE(_group, _variable, _display_name) \
43  BindVariable(#_group "::" #_variable, _group->_variable, _display_name);
44 
45 #define BIND_VARIABLE_WITH_NAME(_group, _variable, _variable_name, _display_name) \
46  BindVariable(#_group "::" #_variable_name, _group->_variable, _display_name);
47 
48 namespace MA
49 {
50 MCThreadLocalData<MARobotState> RobotState(true);
51 }
52 
53 namespace
54 {
55 // Maximum number elements for the string cache
56 static const int MaxSize = 1000;
57 
58 // Wrapper class to avoid using thread local data in the string query
59 struct CacheWrapper
60 {
61  ~CacheWrapper()
62  {
63  for (auto str : Strs)
64  delete str;
65  }
66 
67  MC::StringPtrList Strs;
68 };
69 // Variable names
70 MCThreadLocalData<CacheWrapper> StringCache(true);
71 
72 void CheckStaticStringCache()
73 {
74  if (unlikely(!StringCache.get()))
75  {
76  StringCache.reset(new CacheWrapper);
77  StringCache->Strs.reserve(MaxSize);
78  StringCache->Strs.push_back(new std::string(""));
79  }
80 }
81 
82 int16_t GetStrIndex(const std::string& new_string)
83 {
84  auto& Strs = StringCache->Strs;
85 
86  foreach_i (i, str, Strs)
87  {
88  if (**str == new_string)
89  return (int16_t)i;
90  }
91  Strs.push_back(new std::string(new_string));
92  if (unlikely(MaxSize < Strs.size()))
93  {
94  MC_WARNING("The robot state string cache is over its limit\n");
95  }
96  return (int16_t)(Strs.size()-1);
97 }
98 }
99 
100 MARobotState::MARobotState(bool static_instance, bool updates) : SignalConnections()
101 {
102  CheckStaticStringCache();
103  StrBasePtr = &StringCache->Strs[0];
104  Init(static_instance, updates);
105 }
106 
107 
108 MARobotState::MARobotState(const MARobotState& other) : SignalConnections()
109 {
110  Init(false, false);
111  operator=(other);
112 }
113 
114 
115 MARobotState::~MARobotState()
116 {
117  if (MA::RobotState.get() == this)
118  {
119  MA::RobotState.release();
120  }
122 }
123 
124 
125 void MARobotState::Init(bool static_instance, bool updates)
126 {
127  if (static_instance)
128  {
129  if (MA::RobotState.get())
130  {
131  MC_WARNING("The global robot state is overridden.");
132  }
133  MA::RobotState.reset(this);
134  }
135  Torso.reset(new MATorso);
136  LegLF.reset(new MALeg);
137  LegLF->Type = MA::Leg::LF;
138  LegLH.reset(new MALeg);
139  LegLH->Type = MA::Leg::LH;
140  LegRF.reset(new MALeg);
141  LegRF->Type = MA::Leg::RF;
142  LegRH.reset(new MALeg);
143  LegRH->Type = MA::Leg::RH;
144  Head.reset(new MAHead);
145  BodyMotion.reset(new MABodyMotion);
146  Audio.reset(new MAAudio);
147  Emotions.reset(new MAEmotions);
149  Goals.reset(new MAGoals);
150  Hri.reset(new MAHri);
151  if (updates)
152  {
164  }
165  // Bind the variables
166  std::string SubOpen = "<sub>";
167  std::string SubClose = "</sub>";
168 
169  // Torso
170  BIND_VARIABLE(Torso, BuildID, "BuildID"+SubOpen+"ID"+SubClose);
171  BIND_VARIABLE(Torso, SessionID, "SessionID"+SubOpen+"ID"+SubClose);
172  BIND_VARIABLE(Torso, CycleID, "Cycle"+SubOpen+"ID"+SubClose);
173  BIND_VARIABLE(Torso, CycleTime, "Cycle"+SubOpen+"time"+SubClose);
174  BIND_VARIABLE(Torso, FreeMemory, "Memory"+SubOpen+"free"+SubClose);
175  BIND_VARIABLE(Torso, Timestamp.Seconds, "Timestamp"+SubOpen+"sec"+SubClose);
176  BIND_VARIABLE(Torso, Timestamp.Milliseconds, "msec"+SubClose);
177  BIND_VARIABLE(Torso, Timestamp.Microseconds, "Timestamp"+SubOpen+"µsec"+SubClose);
178  BIND_VARIABLE(Torso, BatteryCapacity, "Battery"+SubOpen+"capacity"+SubClose+" (mAh)");
179  BIND_VARIABLE(Torso, BatteryLevel, "Battery"+SubOpen+"level"+SubClose+" (%)");
180  BIND_VARIABLE(Torso, PowerConsumption, "Power usage (mW)");
181  BIND_VARIABLE(Torso, EstimatedSessionPowerConsumption, "PC"+SubOpen+"estimated"+SubClose+" (mWh)");
182  BIND_VARIABLE(Torso, RealSessionPowerConsumption, "PC"+SubOpen+"real"+SubClose+" (mWh)");
183  BIND_VARIABLE(Torso, CpuLoad.All, "CPU"+SubOpen+"all"+SubClose+" (%)");
184  BIND_VARIABLE(Torso, CpuLoad.Behaviors, "CPU"+SubOpen+"behaviors"+SubClose+" (%)");
185  BIND_VARIABLE(Torso, CpuLoad.Camera, "CPU"+SubOpen+"camera"+SubClose+" (%)");
186  BIND_VARIABLE(Torso, CpuLoad.Network, "CPU"+SubOpen+"network"+SubClose+" (%)");
187  BIND_VARIABLE(Torso, CpuLoad.Audio, "CPU"+SubOpen+"audio"+SubClose+" (%)");
188  BIND_VARIABLE(Torso, WlanStats.Link, "WLAN"+SubOpen+"link"+SubClose+" (%)");
189  BIND_VARIABLE(Torso, WlanStats.Signal, "WLAN"+SubOpen+"signal"+SubClose+" (%)");
190  BIND_VARIABLE(Torso, WlanStats.Noise, "WLAN"+SubOpen+"noise"+SubClose+" (%)");
191  BIND_VARIABLE(Torso, Temperature, "Temperature (°C)");
192  BIND_VARIABLE(Torso, Vibration, "Vibration");
193  BIND_VARIABLE(Torso, DataUpload, "DataUpload (bytes)");
194  BIND_VARIABLE(Torso, TailPan, "Tail"+SubOpen+"pan"+SubClose);
195  BIND_VARIABLE(Torso, TailPanForce, "Tail"+SubOpen+"pan,force"+SubClose);
196  BIND_VARIABLE(Torso, TailTilt, "Tail"+SubOpen+"tilt"+SubClose);
197  BIND_VARIABLE(Torso, TailTiltForce, "Tail"+SubOpen+"tile,force"+SubClose);
198  BIND_VARIABLE(Torso, BackButtonF, "Button"+SubOpen+"back,fore"+SubClose);
199  BIND_VARIABLE(Torso, BackButtonM, "Button"+SubOpen+"back,middle"+SubClose);
200  BIND_VARIABLE(Torso, BackButtonR, "Button"+SubOpen+"back,rear"+SubClose);
201  BIND_VARIABLE(Torso, ChestIR, "IR"+SubOpen+"chest"+SubClose);
202  BIND_VARIABLE(Torso, NearIR, "IR"+SubOpen+"near"+SubClose);
203  BIND_VARIABLE(Torso, FarIR, "IR"+SubOpen+"far"+SubClose);
204  BIND_VARIABLE(Torso, BackStroked, "Back"+SubOpen+"stroked"+SubClose);
205  BIND_VARIABLE(Torso, BackGrabbed, "Back"+SubOpen+"grabbed"+SubClose);
206  BIND_VARIABLE(Torso, BackFButtonPressed, "Button"+SubOpen+"bf,pressed"+SubClose);
207  BIND_VARIABLE(Torso, BackMButtonPressed, "Button"+SubOpen+"bm,pressed"+SubClose);
208  BIND_VARIABLE(Torso, BackRButtonPressed, "Button"+SubOpen+"br,pressed"+SubClose);
209  BIND_VARIABLE(Torso, NightTime, "NightTime");
210  BIND_VARIABLE(Torso, NetworkConnection, "NetworkConnection");
211  BIND_VARIABLE(Torso, ConnectedClients, "Clients");
212  BIND_VARIABLE(Torso, Debug, "Debug");
213  // Body motion
214  BIND_VARIABLE(BodyMotion, OnStation, "OnStation");
215  BIND_VARIABLE(BodyMotion, AccelX.Raw, "Accel"+SubOpen+"x,raw"+SubClose);
216  BIND_VARIABLE(BodyMotion, AccelX.Degree, "Accel"+SubOpen+"x,degree"+SubClose);
217  BIND_VARIABLE(BodyMotion, AccelY.Raw, "Accel"+SubOpen+"y,raw"+SubClose);
218  BIND_VARIABLE(BodyMotion, AccelY.Degree, "Accel"+SubOpen+"y,degree"+SubClose);
219  BIND_VARIABLE(BodyMotion, AccelZ.Raw, "Accel"+SubOpen+"z,raw"+SubClose);
220  BIND_VARIABLE(BodyMotion, AccelZ.Degree, "Accel"+SubOpen+"z,degree"+SubClose);
221  BIND_VARIABLE(BodyMotion, BodyPitch, "Body"+SubOpen+"pitch"+SubClose);
222  BIND_VARIABLE(BodyMotion, BodyRoll, "Body"+SubOpen+"roll"+SubClose);
223  BIND_VARIABLE(BodyMotion, UpsideDown, "UpsideDown");
224  BIND_VARIABLE(BodyMotion, LateralPosition, "LateralPosition");
225  BIND_VARIABLE(BodyMotion, HeadStand, "HeadStand");
226  BIND_VARIABLE(BodyMotion, LyingOnBack, "Lying"+SubOpen+"onback"+SubClose);
227  BIND_VARIABLE(BodyMotion, LyingOnBackLeftSide, "Lying"+SubOpen+"onback,left"+SubClose);
228  BIND_VARIABLE(BodyMotion, LyingOnBackRightSide, "Lying"+SubOpen+"onback,right"+SubClose);
229  BIND_VARIABLE(BodyMotion, BodyOnLeftSide, "BodyOnLeftSide");
230  BIND_VARIABLE(BodyMotion, BodyOnRightSide, "BodyOnRightSide");
231  BIND_VARIABLE(BodyMotion, Lying, "Lying");
232  BIND_VARIABLE(BodyMotion, LyingOnLeftSide, "Lying"+SubOpen+"onleftside"+SubClose);
233  BIND_VARIABLE(BodyMotion, LyingOnRightSide, "Lying"+SubOpen+"onrightside"+SubClose);
234  BIND_VARIABLE(BodyMotion, Sitting, "Sitting");
235  BIND_VARIABLE(BodyMotion, Flying, "Flying");
236  BIND_VARIABLE(BodyMotion, Poked, "Poked");
237  BIND_VARIABLE(BodyMotion, SkitterPlayback, "SkitterPlayback");
238  BIND_VARIABLE(BodyMotion, Floor.Surface, "Flooring"+SubOpen+"surface"+SubClose);
239  BIND_VARIABLE(BodyMotion, Floor.CurrentSurface, "Flooring"+SubOpen+"currentsurface"+SubClose);
240  BIND_VARIABLE(BodyMotion, Floor.OwnerFeedback, "Flooring"+SubOpen+"ownerfeedback"+SubClose);
241  BIND_VARIABLE(BodyMotion, BodyState, "Body"+SubOpen+"state"+SubClose);
242  BIND_VARIABLE(BodyMotion, InMotion, "Body"+SubOpen+"inmotion"+SubClose);
243  BIND_VARIABLE(BodyMotion, SkitPlayback, "SkitPlayback");
244  BIND_VARIABLE(BodyMotion, MotionControlAge, "MotionControl"+SubOpen+"age"+SubClose);
245  // LegLF
246  BIND_VARIABLE(LegLF, Paw, "Paw"+SubOpen+"LF"+SubClose);
247  BIND_VARIABLE(LegLF, Joint1, "Joint1"+SubOpen+"LF"+SubClose);
248  BIND_VARIABLE(LegLF, Force1, "Force1"+SubOpen+"LF"+SubClose);
249  BIND_VARIABLE(LegLF, Joint2, "Joint2"+SubOpen+"LF"+SubClose);
250  BIND_VARIABLE(LegLF, Force2, "Force2"+SubOpen+"LF"+SubClose);
251  BIND_VARIABLE(LegLF, Joint3, "Joint3"+SubOpen+"LF"+SubClose);
252  BIND_VARIABLE(LegLF, Force3, "Force3"+SubOpen+"LF"+SubClose);
253  BIND_VARIABLE(LegLF, PoweredJoints, "Powered joints"+SubOpen+"LF"+SubClose);
254  BIND_VARIABLE(LegLF, ForeBack, "ForeBack"+SubOpen+"LF"+SubClose);
255  BIND_VARIABLE(LegLF, UpDown, "UpDown"+SubOpen+"LF"+SubClose);
256  BIND_VARIABLE(LegLF, Sidelong, "Sidelong"+SubOpen+"LF"+SubClose);
257  BIND_VARIABLE(LegLF, BentStretched, "BentStretched"+SubOpen+"LF"+SubClose);
258  BIND_VARIABLE(LegLF, Stopped, "Stopped"+SubOpen+"LF"+SubClose);
259  BIND_VARIABLE(LegLF, Overloaded, "Overloaded"+SubOpen+"LF"+SubClose);
260  BIND_VARIABLE(LegLF, Moving, "Moving"+SubOpen+"LF"+SubClose);
261  BIND_VARIABLE(LegLF, InMotion, "InMotion"+SubOpen+"LF"+SubClose);
262  BIND_VARIABLE(LegLF, IsLyingPosition, "IsLyingPosition"+SubOpen+"LF"+SubClose);
263  BIND_VARIABLE(LegLF, IsStandingPosition, "IsStandingPosition"+SubOpen+"LF"+SubClose);
264  BIND_VARIABLE(LegLF, IsSittingPosition, "IsSittingPosition"+SubOpen+"LF"+SubClose);
265  // LegLH
266  BIND_VARIABLE(LegLH, Paw, "Paw"+SubOpen+"LH"+SubClose);
267  BIND_VARIABLE(LegLH, Joint1, "Joint1"+SubOpen+"LH"+SubClose);
268  BIND_VARIABLE(LegLH, Force1, "Force1"+SubOpen+"LH"+SubClose);
269  BIND_VARIABLE(LegLH, Joint2, "Joint2"+SubOpen+"LH"+SubClose);
270  BIND_VARIABLE(LegLH, Force2, "Force2"+SubOpen+"LH"+SubClose);
271  BIND_VARIABLE(LegLH, Joint3, "Joint3"+SubOpen+"LH"+SubClose);
272  BIND_VARIABLE(LegLH, Force3, "Force3"+SubOpen+"LH"+SubClose);
273  BIND_VARIABLE(LegLH, PoweredJoints, "Powered joints"+SubOpen+"LH"+SubClose);
274  BIND_VARIABLE(LegLH, ForeBack, "ForeBack"+SubOpen+"LH"+SubClose);
275  BIND_VARIABLE(LegLH, UpDown, "UpDown"+SubOpen+"LH"+SubClose);
276  BIND_VARIABLE(LegLH, Sidelong, "Sidelong"+SubOpen+"LH"+SubClose);
277  BIND_VARIABLE(LegLH, BentStretched, "BentStretched"+SubOpen+"LH"+SubClose);
278  BIND_VARIABLE(LegLH, Stopped, "Stopped"+SubOpen+"LH"+SubClose);
279  BIND_VARIABLE(LegLH, Overloaded, "Overloaded"+SubOpen+"LH"+SubClose);
280  BIND_VARIABLE(LegLH, Moving, "Moving"+SubOpen+"LH"+SubClose);
281  BIND_VARIABLE(LegLH, InMotion, "InMotion"+SubOpen+"LH"+SubClose);
282  BIND_VARIABLE(LegLH, IsLyingPosition, "IsLyingPosition"+SubOpen+"LH"+SubClose);
283  BIND_VARIABLE(LegLH, IsStandingPosition, "IsStandingPosition"+SubOpen+"LH"+SubClose);
284  BIND_VARIABLE(LegLH, IsSittingPosition, "IsSittingPosition"+SubOpen+"LH"+SubClose);
285  // LegRF
286  BIND_VARIABLE(LegRF, Paw, "Paw"+SubOpen+"RF"+SubClose);
287  BIND_VARIABLE(LegRF, Joint1, "Joint1"+SubOpen+"RF"+SubClose);
288  BIND_VARIABLE(LegRF, Force1, "Force1"+SubOpen+"RF"+SubClose);
289  BIND_VARIABLE(LegRF, Joint2, "Joint2"+SubOpen+"RF"+SubClose);
290  BIND_VARIABLE(LegRF, Force2, "Force2"+SubOpen+"RF"+SubClose);
291  BIND_VARIABLE(LegRF, Joint3, "Joint3"+SubOpen+"RF"+SubClose);
292  BIND_VARIABLE(LegRF, Force3, "Force3"+SubOpen+"RF"+SubClose);
293  BIND_VARIABLE(LegRF, PoweredJoints, "Powered joints"+SubOpen+"RF"+SubClose);
294  BIND_VARIABLE(LegRF, ForeBack, "ForeBack"+SubOpen+"RF"+SubClose);
295  BIND_VARIABLE(LegRF, UpDown, "UpDown"+SubOpen+"RF"+SubClose);
296  BIND_VARIABLE(LegRF, Sidelong, "Sidelong"+SubOpen+"RF"+SubClose);
297  BIND_VARIABLE(LegRF, BentStretched, "BentStretched"+SubOpen+"RF"+SubClose);
298  BIND_VARIABLE(LegRF, Stopped, "Stopped"+SubOpen+"RF"+SubClose);
299  BIND_VARIABLE(LegRF, Overloaded, "Overloaded"+SubOpen+"RF"+SubClose);
300  BIND_VARIABLE(LegRF, Moving, "Moving"+SubOpen+"RF"+SubClose);
301  BIND_VARIABLE(LegRF, InMotion, "InMotion"+SubOpen+"RF"+SubClose);
302  BIND_VARIABLE(LegRF, IsLyingPosition, "IsLyingPosition"+SubOpen+"RF"+SubClose);
303  BIND_VARIABLE(LegRF, IsStandingPosition, "IsStandingPosition"+SubOpen+"RF"+SubClose);
304  BIND_VARIABLE(LegRF, IsSittingPosition, "IsSittingPosition"+SubOpen+"RF"+SubClose);
305  // LegRH
306  BIND_VARIABLE(LegRH, Paw, "Paw"+SubOpen+"RH"+SubClose);
307  BIND_VARIABLE(LegRH, Joint1, "Joint1"+SubOpen+"RH"+SubClose);
308  BIND_VARIABLE(LegRH, Force1, "Force1"+SubOpen+"RH"+SubClose);
309  BIND_VARIABLE(LegRH, Joint2, "Joint2"+SubOpen+"RH"+SubClose);
310  BIND_VARIABLE(LegRH, Force2, "Force2"+SubOpen+"RH"+SubClose);
311  BIND_VARIABLE(LegRH, Joint3, "Joint3"+SubOpen+"RH"+SubClose);
312  BIND_VARIABLE(LegRH, Force3, "Force3"+SubOpen+"RH"+SubClose);
313  BIND_VARIABLE(LegRH, PoweredJoints, "Powered joints"+SubOpen+"RH"+SubClose);
314  BIND_VARIABLE(LegRH, ForeBack, "ForeBack"+SubOpen+"RH"+SubClose);
315  BIND_VARIABLE(LegRH, UpDown, "UpDown"+SubOpen+"RH"+SubClose);
316  BIND_VARIABLE(LegRH, Sidelong, "Sidelong"+SubOpen+"RH"+SubClose);
317  BIND_VARIABLE(LegRH, BentStretched, "BentStretched"+SubOpen+"RH"+SubClose);
318  BIND_VARIABLE(LegRH, Stopped, "Stopped"+SubOpen+"RH"+SubClose);
319  BIND_VARIABLE(LegRH, Overloaded, "Overloaded"+SubOpen+"RH"+SubClose);
320  BIND_VARIABLE(LegRH, Moving, "Moving"+SubOpen+"RH"+SubClose);
321  BIND_VARIABLE(LegRH, InMotion, "InMotion"+SubOpen+"RH"+SubClose);
322  BIND_VARIABLE(LegRH, IsLyingPosition, "IsLyingPosition"+SubOpen+"RH"+SubClose);
323  BIND_VARIABLE(LegRH, IsStandingPosition, "IsStandingPosition"+SubOpen+"RH"+SubClose);
324  BIND_VARIABLE(LegRH, IsSittingPosition, "IsSittingPosition"+SubOpen+"RH"+SubClose);
325  // Head
326  BIND_VARIABLE(Head, Pan, "Neck"+SubOpen+"pan"+SubClose);
327  BIND_VARIABLE(Head, PanForce, "Neck"+SubOpen+"pan,force"+SubClose);
328  BIND_VARIABLE(Head, Tilt1, "Neck"+SubOpen+"tilt1"+SubClose);
329  BIND_VARIABLE(Head, Tilt1Force, "Nec"+SubOpen+"tilt1,force"+SubClose);
330  BIND_VARIABLE(Head, Tilt2, "Neck"+SubOpen+"tilt2"+SubClose);
331  BIND_VARIABLE(Head, Tilt2Force, "Neck"+SubOpen+"tilt2,force"+SubClose);
332  BIND_VARIABLE(Head, Moving, "Head"+SubOpen+"moving"+SubClose);
333  BIND_VARIABLE(Head, InMotion, "Head"+SubOpen+"inmotion"+SubClose);
334  BIND_VARIABLE(Head, Mouth, "Mouth");
335  BIND_VARIABLE(Head, MouthForce, "Mouth"+SubOpen+"force"+SubClose);
336  BIND_VARIABLE(Head, MouthMoving, "Mouth"+SubOpen+"moving"+SubClose);
337  BIND_VARIABLE(Head, MouthClosed, "Mouth"+SubOpen+"closed"+SubClose);
338  BIND_VARIABLE(Head, MouthStopped, "Mouth"+SubOpen+"stopped"+SubClose);
339  BIND_VARIABLE(Head, CameraBrightness, "Camera"+SubOpen+"brightness"+SubClose);
340  BIND_VARIABLE(Head, LeftRight, "Head"+SubOpen+"left,right"+SubClose);
341  BIND_VARIABLE(Head, ChinButton, "Chin"+SubOpen+"button"+SubClose);
342  BIND_VARIABLE(Head, CrownButton, "Crown"+SubOpen+"button"+SubClose);
343  BIND_VARIABLE(Head, ForeBack, "Head"+SubOpen+"fore,back"+SubClose);
344  BIND_VARIABLE(Head, UpDown, "Head"+SubOpen+"up,down"+SubClose);
345  BIND_VARIABLE(Head, CrownPressed, "Crown"+SubOpen+"pressed"+SubClose);
346  BIND_VARIABLE(Head, ChinStroked, "Chin"+SubOpen+"stroked"+SubClose);
347  BIND_VARIABLE(Head, CrownStroked, "Crown"+SubOpen+"stroked"+SubClose);
348  BIND_VARIABLE(Head, PushedLeft, "Head"+SubOpen+"pushed,left"+SubClose);
349  BIND_VARIABLE(Head, PushedRight, "Head"+SubOpen+"pushed,right"+SubClose);
350  BIND_VARIABLE(Head, DaylightLevel, "DaylightLevel");
351  BIND_VARIABLE(Head, SleptAwaken, "SleptAwaken");
352  BIND_VARIABLE(Head, EyePupilSize, "EyePupilSize");
353  // Audio
354  BIND_VARIABLE(Audio, FullVolume, "FullVolume");
355  BIND_VARIABLE(Audio, SpeakerVolume, "Speaker volume");
356  BIND_VARIABLE(Audio, RemainingPlaybackTime, "Remaining playback time (msec)");
357  BIND_VARIABLE(Audio, LeftMicrophonePower, "Microphone"+SubOpen+"left,power"+SubClose);
358  BIND_VARIABLE(Audio, RightMicrophonePower, "Microphone"+SubOpen+"right,power"+SubClose);
359  BIND_VARIABLE(Audio, BackgroundSoundPower, "Sound"+SubOpen+"background,power"+SubClose);
360  BIND_VARIABLE(Audio, CurrentSoundEvent, "Sound"+SubOpen+"event,current"+SubClose);
361  BIND_VARIABLE_WITH_NAME(Audio, SoundEventVotes[1], SoundEventVotes1, "Sound"+SubOpen+"votes,ambient_noise"+SubClose);
362  BIND_VARIABLE_WITH_NAME(Audio, SoundEventVotes[2], SoundEventVotes2, "Sound"+SubOpen+"votes,baby_cry"+SubClose);
363  BIND_VARIABLE_WITH_NAME(Audio, SoundEventVotes[3], SoundEventVotes3, "Sound"+SubOpen+"votes,bell"+SubClose);
364  BIND_VARIABLE_WITH_NAME(Audio, SoundEventVotes[4], SoundEventVotes4, "Sound"+SubOpen+"votes,cat_meow"+SubClose);
365  BIND_VARIABLE_WITH_NAME(Audio, SoundEventVotes[5], SoundEventVotes5, "Sound"+SubOpen+"votes,cicada"+SubClose);
366  BIND_VARIABLE_WITH_NAME(Audio, SoundEventVotes[6], SoundEventVotes6, "Sound"+SubOpen+"votes,dog_bark"+SubClose);
367  BIND_VARIABLE_WITH_NAME(Audio, SoundEventVotes[7], SoundEventVotes7, "Sound"+SubOpen+"votes,fart"+SubClose);
368  BIND_VARIABLE_WITH_NAME(Audio, SoundEventVotes[8], SoundEventVotes8, "Sound"+SubOpen+"votes,guitar"+SubClose);
369  BIND_VARIABLE_WITH_NAME(Audio, SoundEventVotes[9], SoundEventVotes9, "Sound"+SubOpen+"votes,laugh"+SubClose);
370  BIND_VARIABLE_WITH_NAME(Audio, SoundEventVotes[10], SoundEventVotes10, "Sound"+SubOpen+"votes,parrot"+SubClose);
371  BIND_VARIABLE_WITH_NAME(Audio, SoundEventVotes[11], SoundEventVotes11, "Sound"+SubOpen+"votes,piano"+SubClose);
372  BIND_VARIABLE_WITH_NAME(Audio, SoundEventVotes[12], SoundEventVotes12, "Sound"+SubOpen+"votes,speech"+SubClose);
373  BIND_VARIABLE_WITH_NAME(Audio, SoundEventVotes[13], SoundEventVotes13, "Sound"+SubOpen+"votes,traffic"+SubClose);
374  BIND_VARIABLE_WITH_NAME(Audio, SoundEventVotes[14], SoundEventVotes14, "Sound"+SubOpen+"votes,vacuum_cleaner"+SubClose);
375  BIND_VARIABLE(Audio, Deafness, "Deafness");
376  BIND_VARIABLE(Audio, EffectsPlayed, "EffectsPlayed");
377  // Emotions
378  BIND_VARIABLE(Emotions, Happy, "Emotion"+SubOpen+"happy"+SubClose);
379  BIND_VARIABLE(Emotions, Angry, "Emotion"+SubOpen+"angry"+SubClose);
380  BIND_VARIABLE(Emotions, Sad, "Emotion"+SubOpen+"sad"+SubClose);
381  BIND_VARIABLE(Emotions, Bored, "Emotion"+SubOpen+"bored"+SubClose);
382  // Complex indicators
383  BIND_VARIABLE(ComplexIndicators, IsLyingPosture, "IsLyingPosture");
384  BIND_VARIABLE(ComplexIndicators, IsStandingPosture, "IsStandingPosture");
385  BIND_VARIABLE(ComplexIndicators, IsSittingPosture, "IsSittingPosture");
386  BIND_VARIABLE(ComplexIndicators, WalkPeriod, "WalkPeriod");
387  BIND_VARIABLE(ComplexIndicators, ElapsedForwardWalkTime, "ElapsedForwardWalkTime");
388  BIND_VARIABLE(ComplexIndicators, ElapsedBackwardWalkTime, "ElapsedBackwardWalkTime");
389  BIND_VARIABLE(ComplexIndicators, ElapsedLeftTurnTime, "ElapsedLeftTurnTime");
390  BIND_VARIABLE(ComplexIndicators, ElapsedRightTurnTime, "ElapsedRightTurnTime");
391  BIND_VARIABLE(ComplexIndicators, NearObjectForward, "Object"+SubOpen+"near"+SubClose);
392  BIND_VARIABLE(ComplexIndicators, AbyssWhileWalking, "Abyss"+SubOpen+"walking"+SubClose);
393  BIND_VARIABLE(ComplexIndicators, AbyssWhileLying, "Abyss"+SubOpen+"lying"+SubClose);
394  BIND_VARIABLE(ComplexIndicators, BodyOutOfWalkingRange, "Body"+SubOpen+"notwalking"+SubClose);
395  BIND_VARIABLE(ComplexIndicators, OverloadDangerWhileSitting, "Sitting"+SubOpen+"legoverload"+SubClose);
396  BIND_VARIABLE(ComplexIndicators, PoseTransition, "PoseTransition");
397  BIND_VARIABLE(ComplexIndicators, ListenWithEars, "ListenWithEars");
398  BIND_VARIABLE(ComplexIndicators, LeftMicrophoneDominance, "Microphone"+SubOpen+"left,dom"+SubClose);
399  BIND_VARIABLE(ComplexIndicators, RightMicrophoneDominance, "Microphone"+SubOpen+"right,dom"+SubClose);
400  BIND_VARIABLE(ComplexIndicators, MicrophoneChannelsBalance, "Microphone"+SubOpen+"bal,dom"+SubClose);
401  // Goals
402  BIND_VARIABLE(Goals, SitPostureDesire, "Desire"+SubOpen+"sit"+SubClose);
403  BIND_VARIABLE(Goals, StandPostureDesire, "Desire"+SubOpen+"stand"+SubClose);
404  BIND_VARIABLE(Goals, LiePostureDesire, "Desire"+SubOpen+"lie"+SubClose);
405  BIND_VARIABLE(Goals, DesiredForwardWalkDuration, "Desire"+SubOpen+"walk,forward"+SubClose);
406  BIND_VARIABLE(Goals, DesiredBackwardWalkDuration, "Desire"+SubOpen+"walk,backward"+SubClose);
407  BIND_VARIABLE(Goals, DesiredLeftTurnDuration, "Desire"+SubOpen+"walk,left"+SubClose);
408  BIND_VARIABLE(Goals, DesiredRightTurnDuration, "Desire"+SubOpen+"walk,right"+SubClose);
409  BIND_VARIABLE(Goals, DesireLyingOnTheFloor, "Desire"+SubOpen+"turnover"+SubClose);
410  BIND_VARIABLE(Goals, ArousalFeedbackNeeded, "ArousalFeedback"+SubOpen+"needed"+SubClose);
411  BIND_VARIABLE(Goals, ListenToAudioDesire, "Desire"+SubOpen+"listen audio"+SubClose);
412  BIND_VARIABLE(Goals, DiscoverSoundSource, "Discover"+SubOpen+"sound,source"+SubClose);
413  BIND_VARIABLE(Goals, HappyOnCarpetFeedback, "HappyFeedback"+SubOpen+"carpet"+SubClose);
414  BIND_VARIABLE(Goals, TurnHeadToLeft, "Head"+SubOpen+"turnleft"+SubClose);
415  BIND_VARIABLE(Goals, TurnHeadToRight, "Head"+SubOpen+"turnright"+SubClose);
416  BIND_VARIABLE(Goals, MotionControl, "MotionControl");
417  // Human-robot interaction data
418  BIND_VARIABLE(Hri, GambledNumber, "Number"+SubOpen+"gambled"+SubClose);
419  BIND_VARIABLE(Hri, GuessedNumber, "Number"+SubOpen+"guessed"+SubClose);
420 
421  // Value notes for floor surface
422  MA::ValueNoteList FloorSurfaceNotes;
423 
424  FloorSurfaceNotes.push_back(MA::ValueNoteType((int)MA::UnknownFloor, *(StrBasePtr+(int)GetStrIndex("Unknown"))));
425  FloorSurfaceNotes.push_back(MA::ValueNoteType((int)MA::WoodFlooring, *(StrBasePtr+(int)GetStrIndex("Wood"))));
426  FloorSurfaceNotes.push_back(MA::ValueNoteType((int)MA::Field, *(StrBasePtr+(int)GetStrIndex("Field"))));
427  FloorSurfaceNotes.push_back(MA::ValueNoteType((int)MA::Carpet, *(StrBasePtr+(int)GetStrIndex("Carpet"))));
428  FloorSurfaceNotes.push_back(MA::ValueNoteType((int)MA::Vinyl, *(StrBasePtr+(int)GetStrIndex("Vinyl"))));
429  FloorSurfaceNotes.push_back(MA::ValueNoteType((int)MA::Tiles, *(StrBasePtr+(int)GetStrIndex("Tiles"))));
430  FloorSurfaceNotes.push_back(MA::ValueNoteType((int)MA::CarpetedFloor, *(StrBasePtr+(int)GetStrIndex("Carpeted floor"))));
431  FloorSurfaceNotes.push_back(MA::ValueNoteType((int)MA::UserDefinedFloor, *(StrBasePtr+(int)GetStrIndex("User defined"))));
432  VariableValueNotes.insert(std::make_pair(&BodyMotion->Floor.Surface, FloorSurfaceNotes));
433  VariableValueNotes.insert(std::make_pair(&BodyMotion->Floor.CurrentSurface, FloorSurfaceNotes));
434  // Safety limit for LF1/RF1 joints while sitting (?)
435  MA::ValueNoteList SafetyLimitForce1;
436 
437  SafetyLimitForce1.push_back(MA::ValueNoteType(MA::ForeLegForce1SittingLimit, *(StrBasePtr+(int)GetStrIndex("Limit"))));
438  SafetyLimitForce1.push_back(MA::ValueNoteType(MA::ForeLegForce1SittingEmergencyLimit,
439  *(StrBasePtr+(int)GetStrIndex("Emergency"))));
440  VariableValueNotes.insert(std::make_pair(&LegLF->Force1, SafetyLimitForce1));
441  VariableValueNotes.insert(std::make_pair(&LegRF->Force1, SafetyLimitForce1));
442  // Safety limit for LF3/RF3 joints while sitting (?)
443  MA::ValueNoteList SafetyLimitForce3;
444 
445  SafetyLimitForce3.push_back(MA::ValueNoteType(MA::ForeLegForce3SittingLimit, *(StrBasePtr+(int)GetStrIndex("Limit"))));
446  VariableValueNotes.insert(std::make_pair(&LegLF->Force3, SafetyLimitForce3));
447  VariableValueNotes.insert(std::make_pair(&LegRF->Force3, SafetyLimitForce3));
448  // Value notes for body state
449  MA::ValueNoteList BodyStateNotes;
450 
451  BodyStateNotes.push_back(MA::ValueNoteType((int)MA::UnknownBodyState, *(StrBasePtr+(int)GetStrIndex("Unknown"))));
452  BodyStateNotes.push_back(MA::ValueNoteType((int)MA::NormalBodyState, *(StrBasePtr+(int)GetStrIndex("Normal"))));
453  BodyStateNotes.push_back(MA::ValueNoteType((int)MA::PickupMode, *(StrBasePtr+(int)GetStrIndex("Pick-up"))));
454  BodyStateNotes.push_back(MA::ValueNoteType((int)MA::FallingOver, *(StrBasePtr+(int)GetStrIndex("Falling over"))));
455  BodyStateNotes.push_back(MA::ValueNoteType((int)MA::Poked, *(StrBasePtr+(int)GetStrIndex("Poked"))));
456  VariableValueNotes.insert(std::make_pair(&BodyMotion->BodyState, BodyStateNotes));
457  // Value notes for sound events
458  MA::ValueNoteList SoundEventNotes;
459 
460  for (unsigned int i = 0; i < MA::SoundEventTypeStrs.size(); ++i)
461  {
462  SoundEventNotes.push_back(MA::ValueNoteType(i+1, *(StrBasePtr+(int)GetStrIndex(MA::SoundEventTypeStrs[i]))));
463  }
464  VariableValueNotes.insert(std::make_pair(&Audio->CurrentSoundEvent, SoundEventNotes));
465 }
466 
467 
468 MALeg& MARobotState::GetLeg(MA::Leg::LegTypes leg) const
469 {
470  if (leg == MA::Leg::LF)
471  return *LegLF;
472  if (leg == MA::Leg::LH)
473  return *LegLH;
474  if (leg == MA::Leg::RF)
475  return *LegRF;
476  return *LegRH;
477 }
478 
479 
481 {
482  return DecodedVariableMap;
483 }
484 
485 
486 const MANum<int>* MARobotState::GetVariable(const std::string& variable_name) const
487 {
488  for (unsigned int i = 0; i < VariableNames.size(); ++i)
489  {
490  if (**(StrBasePtr+(int)VariableNames[i]) == variable_name)
491  return Variables[i];
492  }
493  return nullptr;
494 }
495 
496 
497 std::string MARobotState::GetDisplayName(const std::string& variable_name) const
498 {
499  for (unsigned int i = 0; i < VariableNames.size(); ++i)
500  {
501  if (**(StrBasePtr+(int)VariableNames[i]) == variable_name)
502  {
503  if ((*(StrBasePtr+(int)VariableDisplayNames[i]))->empty())
504  return variable_name;
505  else
506  return **(StrBasePtr+(int)VariableDisplayNames[i]);
507  }
508  }
509  return "";
510 }
511 
512 
513 MC::StringList MARobotState::GetVariableNames() const
514 {
515  MC::StringList Strs;
516 
517  for (unsigned int i = 0; i < VariableNames.size(); ++i)
518  {
519  Strs.push_back(**(StrBasePtr+(int)VariableNames[i]));
520  }
521  return Strs;
522 }
523 
524 
525 MA::ValueNoteList MARobotState::GetValueNotes(const std::string& variable_name) const
526 {
527  const MANum<int>* VariablePtr = GetVariable(variable_name);
528 
529  if (VariablePtr)
530  {
531  const auto Iter = VariableValueNotes.find(VariablePtr);
532 
533  if (Iter != VariableValueNotes.end())
534  return Iter->second;
535  }
536  return MA::ValueNoteList();
537 }
538 
539 
540 std::string MARobotState::GetAsRichText(const MC::StringList& highlighted_variables) const
541 {
542  std::string ContentStr = "<b><u>Robot State</u></b><br>";
543  std::string GroupName;
544 
545  for (unsigned int i = 0; i < VariableNames.size(); ++i)
546  {
547  MC::StringList NameElements;
548 
549  boost::algorithm::split(NameElements, **(StrBasePtr+(int)VariableNames[i]),
550  boost::algorithm::is_any_of("::"));
551  if (GroupName.empty() || GroupName != NameElements[0])
552  {
553  GroupName = NameElements[0];
554  ContentStr += "<b>"+GroupName+"</b><br>";
555  }
556  MANum<int>* VariablePtr = Variables[i];
557  const MC::IntList& HighResValues = VariablePtr->GetHighResolutionValues();
558  std::string HighResValuesStr;
559 
560  if (HighResValues.size() > 0)
561  {
562  HighResValuesStr = " (";
563  for (unsigned int i1 = 0; i1 < HighResValues.size(); ++i1)
564  {
565  HighResValuesStr += MCToStr(HighResValues[i1]);
566  if (i1 < HighResValues.size()-1)
567  {
568  HighResValuesStr += ',';
569  }
570  }
571  HighResValuesStr += ')';
572  }
573  const auto Iter = std::find(highlighted_variables.begin(), highlighted_variables.end(),
574  **(StrBasePtr+(int)VariableNames[i]));
575 
576  if (Iter != highlighted_variables.end())
577  {
578  ContentStr += "<span style=\"color:#7777ee\">"+NameElements[2]+": "+MCToStr(*VariablePtr)+
579  HighResValuesStr+"</span><br>";
580  } else {
581  ContentStr += NameElements[2]+": "+MCToStr((int)*VariablePtr, NameElements[2] == "BuildID")+HighResValuesStr+"<br>";
582  }
583  }
584  return ContentStr;
585 }
586 
587 
588 std::string MARobotState::GetAsNormalText() const
589 {
590  std::string RobotStateStr = GetAsRichText();
591 
592  boost::replace_all(RobotStateStr, "<br>", "\n");
593  boost::replace_all(RobotStateStr, "<b><u>", " ++++ ");
594  boost::replace_all(RobotStateStr, "</u></b>", " ++++ ");
595  boost::replace_all(RobotStateStr, "<b>", " ++ ");
596  boost::replace_all(RobotStateStr, "</b>", " ++ ");
597  return RobotStateStr;
598 }
599 
600 
602 {
603  if (&other == this)
604  return *this;
605 
606  SignalConnections = other.SignalConnections;
607  CheckStaticStringCache();
608  StrBasePtr = &StringCache->Strs[0];
609  *LegLF = *other.LegLF;
610  *LegLH = *other.LegLH;
611  *LegRF = *other.LegRF;
612  *LegRH = *other.LegRH;
613  *Torso = *other.Torso;
614  *Head = *other.Head;
615  *Audio = *other.Audio;
616  *BodyMotion = *other.BodyMotion;
617  *Emotions = *other.Emotions;
619  *Goals = *other.Goals;
620  *Hri = *other.Hri;
621  // Remove the old custom variables
623  for (auto& variable : other.DecodedCustomVariables)
624  {
625  MANum<int>* NewVariable = new MANum<int>(*variable);
626 
627  DecodedCustomVariables.push_back(NewVariable);
628  Variables.push_back(NewVariable);
629  // Lookup the variable from the other robot state instance
630  auto NameIter = other.VariableNames.begin();
631  auto DisplayNameIter = other.VariableDisplayNames.begin();
632  auto VariableIter = other.Variables.begin();
633 
634  for (unsigned int i = 0; i < other.Variables.size(); ++i)
635  {
636  if (variable == *VariableIter)
637  {
638  VariableNames.push_back(GetStrIndex(**(other.StrBasePtr+(int)*NameIter)));
639  VariableDisplayNames.push_back(GetStrIndex(**(other.StrBasePtr+(int)*DisplayNameIter)));
640  break;
641  }
642  ++NameIter;
643  ++DisplayNameIter;
644  ++VariableIter;
645  }
646  }
647  return *this;
648 }
649 
650 
651 MCBinaryData* MARobotState::Encode(bool encode_variable_map) const
652 {
653  std::string VariableMap;
654 
655  if (encode_variable_map)
656  {
657  for (unsigned int i = 0; i < VariableNames.size(); ++i)
658  {
659  VariableMap += **(StrBasePtr+(int)VariableNames[i])+'|';
660  if (Variables[i]->IsUchar())
661  {
662  VariableMap += "u8,";
663  } else
664  if (Variables[i]->IsInt16())
665  {
666  VariableMap += "i16,";
667  } else
668  if (Variables[i]->IsInt32())
669  {
670  VariableMap += "i32,";
671  } else {
672  MC_ERROR("Variable %s cannot be mapped to uchar, int16 or int32 ranges.",
673  (*(StrBasePtr+(int)VariableNames[i]))->c_str());
674  }
675  }
676  }
677  MCBinaryData* BinaryData = nullptr;
678 
679  if (encode_variable_map)
680  {
681  BinaryData = new MCBinaryData(GetBinarySize()+2+VariableMap.size()+1);
682  BinaryData->AddInt16(VariableMap.size()+1);
683  memcpy(&BinaryData->GetData()[2], VariableMap.c_str(), VariableMap.size()+1);
684  BinaryData->IncrementPosition(VariableMap.size()+1);
685  } else {
686  BinaryData = new MCBinaryData(GetBinarySize()+2);
687  BinaryData->AddInt16(0);
688  }
689  for (auto& variable : Variables)
690  {
691  const MC::IntList& HighResValues = variable->GetHighResolutionValues();
692 
693  if (variable->IsUchar())
694  {
695  BinaryData->AddUChar(*variable);
696  BinaryData->AddUChar(HighResValues.size());
697  for (auto& value : HighResValues)
698  {
699  BinaryData->AddUChar(value);
700  }
701  } else
702  if (variable->IsInt16())
703  {
704  BinaryData->AddInt16(*variable);
705  BinaryData->AddUChar(HighResValues.size());
706  for (auto& value : HighResValues)
707  {
708  BinaryData->AddInt16(value);
709  }
710  } else {
711  BinaryData->AddInt32(*variable);
712  BinaryData->AddUChar(HighResValues.size());
713  for (auto& value : HighResValues)
714  {
715  BinaryData->AddInt32(value);
716  }
717  }
718  }
719  return BinaryData;
720 }
721 
722 
723 MARobotState* MARobotState::Decode(const MCBinaryData& data, const std::string& variable_map)
724 {
725  MCBinaryData& BinaryData = const_cast<MCBinaryData&>(data);
726  int OldPosition = BinaryData.GetPosition();
727  MARobotState* NewRobotState = new MARobotState;
728  int VariableMapSize;
729 
730  BinaryData.SetPosition(0);
731  VariableMapSize = BinaryData.GetInt16();
732  if (VariableMapSize < 1 && variable_map.empty())
733  {
734  MC_WARNING("No variable map in the packet or cached during robot state decoding.");
735  delete NewRobotState;
736  BinaryData.SetPosition(OldPosition);
737  return nullptr;
738  }
739  std::string VariableMap;
740  MA::Int16List& DisplayNames = NewRobotState->VariableDisplayNames;
741  MA::Int16List& Names = NewRobotState->VariableNames;
742  MA::MANumIntPtrList& Variables = NewRobotState->Variables;
743  MA::MANumIntPtrList& DecodedVariables = NewRobotState->DecodedCustomVariables;
744 
745  if (VariableMapSize > 0)
746  {
747  if (BinaryData.GetSize() < 2+VariableMapSize+1 || BinaryData.GetData()[2+VariableMapSize-1] != 0)
748  {
749  MC_WARNING("No space for variable map or it is invalid.");
750  delete NewRobotState;
751  BinaryData.SetPosition(OldPosition);
752  return nullptr;
753  }
754  VariableMap = BinaryData.GetString(VariableMapSize-1, "|,:.");
755  if ((int)VariableMap.size() != VariableMapSize-1)
756  {
757  MC_WARNING("The variable map is invalid.");
758  delete NewRobotState;
759  BinaryData.SetPosition(OldPosition);
760  return nullptr;
761  }
762  // Jump other the string closing '\0'
763  BinaryData.IncrementPosition(1);
764  NewRobotState->DecodedVariableMap = VariableMap;
765  } else {
766  VariableMap = variable_map;
767  }
768  int VariableIndex = -1;
769  auto NameIter = Names.end();
770  auto VariableIter = Variables.end();
771 
772  while (VariableMap.size() > 2)
773  {
774  const int VariableSectionSize = VariableMap.find(',');
775  std::string VariableSection = VariableMap.substr(0, VariableSectionSize);
776  const int VariableNameSize = VariableSection.find('|');
777  const std::string VariableName = VariableSection.substr(0, VariableNameSize);
778 
779  if (VariableIndex != -1)
780  {
781  ++NameIter;
782  ++VariableIter;
783 
784  if (NameIter != Names.end() && **(NewRobotState->StrBasePtr+(int)*NameIter) == VariableName)
785  {
786  VariableIndex++;
787  goto continue_decoding;
788  }
789  VariableIndex = -1;
790  }
791  NameIter = Names.begin();
792  VariableIter = Variables.begin();
793  for (unsigned int i = 0; i < Names.size(); ++i)
794  {
795  if (**(NewRobotState->StrBasePtr+(int)*NameIter) == VariableName)
796  {
797  VariableIndex = i;
798  break;
799  }
800  ++NameIter;
801  ++VariableIter;
802  }
803 continue_decoding:
804  VariableMap.erase(0, VariableSectionSize+1);
805  VariableSection.erase(0, VariableNameSize+1);
806  // Non-existing variable -> add as a new custom variable
807  if (VariableIndex == -1)
808  {
809  MANum<int>* NewVariable = new MANum<int>;
810 
811  // Set the minimum and maximum integer values since it real limits are not known
812  // for an unknown variable.
813  NewVariable->SetMinMax(std::numeric_limits<int>::min(), std::numeric_limits<int>::max());
814  DecodedVariables.push_back(NewVariable);
815  Variables.push_back(NewVariable);
816  VariableIter = --Variables.end();
817  Names.push_back(GetStrIndex(VariableName));
818  NameIter = --Names.end();
819  DisplayNames.push_back(GetStrIndex(""));
820  }
821  int WordSize;
822  bool IsUChar = VariableSection == "u8" || VariableSection == "uchar";
823  bool IsInt16 = VariableSection == "i16" || VariableSection == "int16";
824 
825  if (IsUChar)
826  {
827  WordSize = 1;
828  } else
829  if (IsInt16)
830  {
831  WordSize = 2;
832  } else {
833  WordSize = 4;
834  }
835  if ((int)BinaryData.GetRemainingCapacity(WordSize) < WordSize)
836  {
837  MC_WARNING("No remaining binary data size. Invalid binary BinaryData supplied!?");
838  delete NewRobotState;
839  return nullptr;
840  }
841  if (IsUChar)
842  {
843  int TempInt = (int)BinaryData.GetUChar();
844 
845  // Assign the value twice to reset the changed variable to false
846  **VariableIter = TempInt;
847  **VariableIter = TempInt;
848  } else
849  if (IsInt16)
850  {
851  int TempInt = (int)BinaryData.GetInt16();
852 
853  // Assign the value twice to reset the changed variable to false
854  **VariableIter = TempInt;
855  **VariableIter = TempInt;
856  } else {
857  int TempInt = (int)BinaryData.GetInt32();
858 
859  // Assign the value twice to reset the changed variable to false
860  **VariableIter = TempInt;
861  **VariableIter = TempInt;
862  }
863  if (BinaryData.GetRemainingCapacity(1) == 0)
864  {
865  MC_WARNING("No remaining binary data size. Invalid binary BinaryData supplied!?");
866  delete NewRobotState;
867  return nullptr;
868  }
869  int HighResValueNumber = BinaryData.GetUChar();
870 
871  if (HighResValueNumber > 0)
872  {
873  MC::IntList HighResValues;
874 
875  for (int i = 0; i < HighResValueNumber; ++i)
876  {
877  if ((int)BinaryData.GetRemainingCapacity(WordSize) < WordSize)
878  {
879  MC_WARNING("No remaining binary data size. Invalid binary BinaryData supplied!?");
880  delete NewRobotState;
881  return nullptr;
882  }
883  if (IsUChar)
884  {
885  HighResValues.push_back((int)BinaryData.GetUChar());
886  } else
887  if (IsInt16)
888  {
889  HighResValues.push_back((int)BinaryData.GetInt16());
890  } else {
891  HighResValues.push_back((int)BinaryData.GetInt32());
892  }
893  }
894  (*VariableIter)->SetHighResolutionValues(HighResValues);
895  }
896  }
897  BinaryData.SetPosition(OldPosition);
898  return NewRobotState;
899 }
900 
901 
902 void MARobotState::BindVariable(const std::string& name, MANum<int>& variable,
903  const std::string& display_name)
904 {
905  Variables.push_back(&variable);
906  VariableNames.push_back(GetStrIndex(name));
907  VariableDisplayNames.push_back(GetStrIndex(display_name));
908 }
909 
910 
912 {
913  for (auto& variable : DecodedCustomVariables)
914  {
915  // Remove custom variable references (name, display name, variable pointer)
916  auto NameIter = VariableNames.begin();
917  auto DisplayNameIter = VariableDisplayNames.begin();
918  auto VariableIter = Variables.begin();
919 
920  for (unsigned int i = 0; i < VariableNames.size(); ++i)
921  {
922  if (variable == *VariableIter)
923  {
924  VariableNames.erase(NameIter);
925  VariableDisplayNames.erase(DisplayNameIter);
926  Variables.erase(VariableIter);
927  break;
928  }
929  ++NameIter;
930  ++DisplayNameIter;
931  ++VariableIter;
932  }
933  delete variable;
934  }
935  DecodedCustomVariables.clear();
936 }
937 
938 
940 {
941  int BinaryStorageSize = 0;
942 
943  for (auto& variable : Variables)
944  {
945  const MC::IntList& HighResValues = variable->GetHighResolutionValues();
946 
947  // Add the high resolution number byte
948  BinaryStorageSize++;
949  // Add the actual storage requirements for the new item
950  if (variable->IsUchar())
951  {
952  BinaryStorageSize++;
953  BinaryStorageSize += HighResValues.size()*1;
954  } else
955  if (variable->IsInt16())
956  {
957  BinaryStorageSize += 2;
958  BinaryStorageSize += HighResValues.size()*2;
959  } else {
960  BinaryStorageSize += 4;
961  BinaryStorageSize += HighResValues.size()*4;
962  }
963  }
964  return BinaryStorageSize;
965 }
std::string GetAsNormalText() const
Get robot state printed in normal text format.
int16_t GetInt16(bool reverse_order=false)
Get a 16 bit integer from the current position.
MARobotState & operator=(const MARobotState &other)
Assignment operator.
Goals.
Definition: MAGoals.hpp:35
Torso states.
Definition: MATorso.hpp:97
void AddInt16(int16_t new_int, bool reverse_order=false)
Add a 16 bit integer at the current position.
Binary data class.
MA::MANumIntPtrValueNotesMap VariableValueNotes
Notes for variable values.
MALeg & GetLeg(MA::Leg::LegTypes leg) const
Get a leg by its type.
std::string DecodedVariableMap
Decoded variable map from the network decoder.
virtual void SetMinMax(T min_value, T max_value)
Set the minimal and maximal values.
Definition: MANum.hpp:235
unsigned char GetUChar()
Get an unsigned char from the current position.
#define MC_ERROR(...)
Error macro.
Definition: MCLog.hpp:45
#define MC_WARNING(...)
Warning macro.
Definition: MCLog.hpp:43
std::string MCToStr(const T value, bool hex_manipulator=false)
Convert an other type to string with std::stringstream.
Definition: MCDefs.hpp:360
std::string GetString(unsigned int length, const std::string &additional_chars="")
Get a string from the current position.
#define foreach_i(_i, _iter, _container)
For each cycle with auto keyword and index values.
Definition: MCDefs.hpp:63
boost::scoped_ptr< MAComplexIndicators > ComplexIndicators
Complex indicators.
boost::scoped_ptr< MALeg > LegRH
LegRH.
const std::vector< T > & GetHighResolutionValues() const
Get high resolution values.
Definition: MANum.hpp:183
MA::Int16List VariableNames
Variable names.
void AddInt32(int32_t new_int, bool reverse_order=false)
Add a 32 bit integer at the current position.
int GetBinarySize() const
Get size in binary form.
unsigned int GetRemainingCapacity(unsigned int capacity) const
Check if the binary data has enough remaining capacity.
MA::Int16List VariableDisplayNames
Variable display names.
static void RegisterUpdater(MARobotStateUpdater &updater)
Register a robot state updater.
void SetPosition(unsigned int position)
Set the cursor position.
void IncrementPosition(unsigned int position=1)
Increment the cursor position.
MA::ValueNoteList GetValueNotes(const std::string &variable_name) const
Get value notes of a variable.
std::string GetDecodedVariableMap() const
Get the decoded variable map.
std::string GetDisplayName(const std::string &variable_name) const
Get display name of a variable.
boost::scoped_ptr< MAGoals > Goals
Goals.
Audio input/output state.
Definition: MAAudio.hpp:63
MC::StringList GetVariableNames() const
Get variable names.
void RemoveCustomVariables()
Remove the custom variables.
boost::scoped_ptr< MABodyMotion > BodyMotion
Body motion.
boost::scoped_ptr< MALeg > LegLF
LegLF.
void Init(bool static_instance, bool updates)
Construct a new instance.
MA::MANumIntPtrList DecodedCustomVariables
Decoded custom variable pointers.
boost::scoped_ptr< MAEmotions > Emotions
Emotions.
std::string ** StrBasePtr
Variable names.
boost::scoped_ptr< MALeg > LegRF
LegRF.
void AddUChar(unsigned char new_char)
Add an unsigned char at the current position.
State indicators.
Definition: MAEmotions.hpp:62
const MANum< int > * GetVariable(const std::string &variable_name) const
Get variable pointer by name.
MA::MANumIntPtrList Variables
Variable pointers.
unsigned char * GetData() const
Get direct access to the binary data.
boost::scoped_ptr< MAAudio > Audio
Audio input/output.
Body motion states.
int32_t GetInt32(bool reverse_order=false)
Get a 32 bit integer from the current position.
A wrapper class to cover boost::thread_specific_ptr/folly::ThreadLocal API on certain targets...
boost::scoped_ptr< MAHri > Hri
Human-robot interaction data.
A leg class.
Definition: MALeg.hpp:71
MA_SLOT_CLASS MARobotState(bool static_instance=false, bool updates=false)
Struct constructor.
static MARobotState * Decode(const MCBinaryData &data, const std::string &variable_map="")
Decode from binary data form.
boost::scoped_ptr< MATorso > Torso
Torso.
Human-robot interaction data.
Definition: MAHri.hpp:34
std::string GetAsRichText(const MC::StringList &highlighted_variables=MC::StringList()) const
Get robot state printed in html rich text format.
Head state.
Definition: MAHead.hpp:55
boost::scoped_ptr< MALeg > LegLH
LegLH.
Robot state.
Complex state indicators.
int GetPosition() const
Get the current position in the binary data.
MCBinaryData * Encode(bool encode_variable_map=true) const
Encode into binary data form.
void BindVariable(const std::string &name, MANum< int > &variable, const std::string &display_name)
Bind a variable.
boost::scoped_ptr< MAHead > Head
Head.
int GetSize() const
Get binary data size.