AnimatLab  2
Test
RbXBeeCommander.cpp
1 // RbXBeeCommander.cpp: implementation of the RbXBeeCommander class.
2 //
4 
5 #include "StdAfx.h"
6 #include <stdarg.h>
7 #include "RbMovableItem.h"
8 #include "RbBody.h"
9 #include "RbJoint.h"
10 #include "RbMotorizedJoint.h"
11 #include "RbHingeLimit.h"
12 #include "RbHinge.h"
13 #include "RbRigidBody.h"
14 #include "RbStructure.h"
15 #include "RbXBeeCommander.h"
16 
17 namespace RoboticsAnimatSim
18 {
19  namespace Robotics
20  {
21  namespace RobotIOControls
22  {
23 
25 // Construction/Destruction
27 
28 RbXBeeCommander::RbXBeeCommander()
29 {
30  m_strPort = "";
31  m_iBaudRate = 38400;
32 
33  //m_aryData.RemoveAll();
34 
35  //m_aryData.Add(BUT_ID_WALKV, new RemoteControlData("WalkV", BUT_ID_WALKV, m_iChangeSimStepCount));
36  //m_aryData.Add(BUT_ID_WALKH, new RemoteControlData("WalkH", BUT_ID_WALKH, m_iChangeSimStepCount));
37  //m_aryData.Add(BUT_ID_LOOKV, new RemoteControlData("LookV", BUT_ID_LOOKV, m_iChangeSimStepCount));
38  //m_aryData.Add(BUT_ID_LOOKH, new RemoteControlData("LookH", BUT_ID_LOOKH, m_iChangeSimStepCount));
39  //m_aryData.Add(BUT_ID_PAN, new RemoteControlData("Pan", BUT_ID_PAN, m_iChangeSimStepCount));
40  //m_aryData.Add(BUT_ID_TILT, new RemoteControlData("Tilt", BUT_ID_TILT, m_iChangeSimStepCount));
41  //m_aryData.Add(BUT_ID_R1, new RemoteControlData("R1", BUT_ID_R1, m_iChangeSimStepCount));
42  //m_aryData.Add(BUT_ID_R2, new RemoteControlData("R2", BUT_ID_R2, m_iChangeSimStepCount));
43  //m_aryData.Add(BUT_ID_R3, new RemoteControlData("R3", BUT_ID_R3, m_iChangeSimStepCount));
44  //m_aryData.Add(BUT_ID_L4, new RemoteControlData("L4", BUT_ID_L4, m_iChangeSimStepCount));
45  //m_aryData.Add(BUT_ID_L5, new RemoteControlData("L5", BUT_ID_L5, m_iChangeSimStepCount));
46  //m_aryData.Add(BUT_ID_L6, new RemoteControlData("L6", BUT_ID_L6, m_iChangeSimStepCount));
47  //m_aryData.Add(BUT_ID_RT, new RemoteControlData("RT", BUT_ID_RT, m_iChangeSimStepCount));
48  //m_aryData.Add(BUT_ID_LT, new RemoteControlData("LT", BUT_ID_LT, m_iChangeSimStepCount));
49 
50  ResetData();
51 }
52 
53 RbXBeeCommander::~RbXBeeCommander()
54 {
55  try
56  {
57  }
58  catch(...)
59  {Std_TraceMsg(0, "Caught Error in desctructor of RbXBeeCommander\r\n", "", -1, false, true);}
60 }
61 
62 void RbXBeeCommander::CreateDataIDMap()
63 {
64  m_aryDataIDMap.RemoveAll();
65  m_aryDataIDMap.Add("WalkV", BUT_ID_WALKV);
66  m_aryDataIDMap.Add("WalkH", BUT_ID_WALKH);
67  m_aryDataIDMap.Add("LookV", BUT_ID_LOOKV);
68  m_aryDataIDMap.Add("LookH", BUT_ID_LOOKH);
69  m_aryDataIDMap.Add("Pan", BUT_ID_PAN);
70  m_aryDataIDMap.Add("Tilt", BUT_ID_TILT);
71  m_aryDataIDMap.Add("R1", BUT_ID_R1);
72  m_aryDataIDMap.Add("R2", BUT_ID_R2);
73  m_aryDataIDMap.Add("R3", BUT_ID_R2);
74  m_aryDataIDMap.Add("L4", BUT_ID_L4);
75  m_aryDataIDMap.Add("L5", BUT_ID_L5);
76  m_aryDataIDMap.Add("L6", BUT_ID_L6);
77  m_aryDataIDMap.Add("RT", BUT_ID_RT);
78  m_aryDataIDMap.Add("LT", BUT_ID_LT);
79 }
80 
81 void RbXBeeCommander::Port(std::string strPort)
82 {
83  m_strPort = strPort;
84 }
85 
86 std::string RbXBeeCommander::Port() {return m_strPort;}
87 
88 void RbXBeeCommander::BaudRate(int iRate)
89 {
90  Std_IsAboveMin((int) 0, iRate, true, "BaudRate");
91  m_iBaudRate = iRate;
92 }
93 
94 int RbXBeeCommander::BaudRate() {return m_iBaudRate;}
95 
96 #pragma region DataAccesMethods
97 
98 bool RbXBeeCommander::SetData(const std::string &strDataType, const std::string &strValue, bool bThrowError)
99 {
100  std::string strType = Std_CheckString(strDataType);
101 
102  if(AnimatSim::Robotics::RemoteControl::SetData(strDataType, strValue, false))
103  return true;
104 
105  if(strType == "PORT")
106  {
107  Port(strValue);
108  Initialize();
109  return true;
110  }
111  else if(strType == "BAUDRATE")
112  {
113  BaudRate((int) atoi(strValue.c_str()));
114  return true;
115  }
116 
117  //If it was not one of those above then we have a problem.
118  if(bThrowError)
119  THROW_PARAM_ERROR(Al_Err_lInvalidDataType, Al_Err_strInvalidDataType, "Data Type", strDataType);
120 
121  return false;
122 }
123 
124 void RbXBeeCommander::QueryProperties(CStdPtrArray<TypeProperty> &aryProperties)
125 {
127 
128  aryProperties.Add(new TypeProperty("Port", AnimatPropertyType::String, AnimatPropertyDirection::Set));
129  aryProperties.Add(new TypeProperty("BaudRate", AnimatPropertyType::Integer, AnimatPropertyDirection::Set));
130  aryProperties.Add(new TypeProperty("ChangeSimStepCount", AnimatPropertyType::Integer, AnimatPropertyDirection::Set));
131 
132  aryProperties.Add(new TypeProperty("WalkV", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
133  aryProperties.Add(new TypeProperty("WalkVStart", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
134  aryProperties.Add(new TypeProperty("WalkVStop", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
135 
136  aryProperties.Add(new TypeProperty("WalkH", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
137  aryProperties.Add(new TypeProperty("WalkHStart", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
138  aryProperties.Add(new TypeProperty("WalkHStop", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
139 
140  aryProperties.Add(new TypeProperty("LookV", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
141  aryProperties.Add(new TypeProperty("LookVStart", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
142  aryProperties.Add(new TypeProperty("LookVStop", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
143 
144  aryProperties.Add(new TypeProperty("LookH", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
145  aryProperties.Add(new TypeProperty("LookHStart", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
146  aryProperties.Add(new TypeProperty("LookHStop", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
147 
148  aryProperties.Add(new TypeProperty("Pan", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
149  aryProperties.Add(new TypeProperty("PanStart", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
150  aryProperties.Add(new TypeProperty("PanStop", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
151 
152  aryProperties.Add(new TypeProperty("Tilt", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
153  aryProperties.Add(new TypeProperty("TiltStart", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
154  aryProperties.Add(new TypeProperty("TiltStop", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
155 
156  aryProperties.Add(new TypeProperty("R1", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
157  aryProperties.Add(new TypeProperty("R1Start", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
158  aryProperties.Add(new TypeProperty("R1Stop", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
159 
160  aryProperties.Add(new TypeProperty("R2", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
161  aryProperties.Add(new TypeProperty("R2Start", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
162  aryProperties.Add(new TypeProperty("R2Stop", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
163 
164  aryProperties.Add(new TypeProperty("R3", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
165  aryProperties.Add(new TypeProperty("R3Start", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
166  aryProperties.Add(new TypeProperty("R3Stop", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
167 
168  aryProperties.Add(new TypeProperty("L4", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
169  aryProperties.Add(new TypeProperty("L4Start", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
170  aryProperties.Add(new TypeProperty("L4Stop", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
171 
172  aryProperties.Add(new TypeProperty("L5", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
173  aryProperties.Add(new TypeProperty("L5Start", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
174  aryProperties.Add(new TypeProperty("L5Stop", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
175 
176  aryProperties.Add(new TypeProperty("L6", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
177  aryProperties.Add(new TypeProperty("L6Start", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
178  aryProperties.Add(new TypeProperty("L6Stop", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
179 
180  aryProperties.Add(new TypeProperty("RT", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
181  aryProperties.Add(new TypeProperty("RTStart", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
182  aryProperties.Add(new TypeProperty("RTStop", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
183 
184  aryProperties.Add(new TypeProperty("LT", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
185  aryProperties.Add(new TypeProperty("LTStart", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
186  aryProperties.Add(new TypeProperty("LTStop", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
187 }
188 
189 #pragma endregion
190 
192 {
193  // Open device. Do this before calling the Initialize on the parts so they can have communications.
194  if(m_bEnabled)
195  {
196  //If the thread is running already then shut it down.
197  if(m_bSetupComplete)
198  ShutdownIO();
199 
200  if(!Std_IsBlank(m_strPort))
201  {
202  if(OpenIO())
203  {
204  StartIOThread();
205 
206  int iCount = m_aryLinks.GetSize();
207  for(int iIndex=0; iIndex<iCount; iIndex++)
208  m_aryLinks[iIndex]->Initialize();
209 
210  ResetData();
211  }
212  }
213  }
214 }
215 
216 bool RbXBeeCommander::OpenIO()
217 {
218  bool bOpen = m_Port.setup(m_strPort, m_iBaudRate);
219 
220  if(!m_lpSim->InSimulation() && !bOpen)
221  THROW_PARAM_ERROR(Rb_Err_lFailedUartSBeeConnection, Rb_Err_strFailedUartSBeeConnection, "ComPort", m_strPort);
222 
223  return bOpen;
224  //return false;
225 }
226 
227 void RbXBeeCommander::CloseIO()
228 {
229  m_Port.close();
230 }
231 
232 void RbXBeeCommander::ResetData()
233 {
234  RemoteControl::ResetData();
235 
236  m_iButtons = 0;
237  m_iExt = 0;
238 
239  index = -1;
240  checksum = 0;
241  status = 0;
242 }
243 
245 {
246  //If we have not opened the port yet give it another try.
247  if(!m_Port.isInitialized())
248  Initialize();
249 
250  //Clear out anything that happened the first time we got stuff.
251  m_Port.flush();
252 }
253 
254 void RbXBeeCommander::WaitForThreadNotifyReady()
255 {
256  RobotIOControl::WaitForThreadNotifyReady();
257 
258  //Give it just a bit of time to start waiting if required.
259  boost::this_thread::sleep(boost::posix_time::microseconds(10000));
260 }
261 
263 {
264  if(!m_lpSim->Paused())
265  {
266  bool bFound = false;
267 
269  //m_aryData[BUT_ID_WALKH].m_fltValue = 50;
270 
271  while(m_Port.available() > 0 && !bFound)
272  {
273  if(index == -1)
274  { // looking for new packet
275  if(m_Port.readByte() == 0xff)
276  {
277  index = 0;
278  checksum = 0;
279  }
280  }
281  else if(index == 0)
282  {
283  vals[index] = (unsigned char) m_Port.readByte();
284  if(vals[index] != 0xff)
285  {
286  checksum += (int) vals[index];
287  index++;
288  }
289  else
290  index = -1; //Start over if the second byte is not 0xff
291  }
292  else
293  {
294  vals[index] = (unsigned char) m_Port.readByte();
295  checksum += (int) vals[index];
296  index++;
297  if(index == 7)
298  { // packet complete
299  if(checksum%256 != 255)
300  {
301  // packet error!
302  index = -1;
303  return; // 0
304  }
305  else
306  {
307  if((status&0x01) > 0)
308  { // SouthPaw
309  SetDataValue(BUT_ID_WALKV, (float) ((signed char)( (int)vals[0]-128 )));
310  SetDataValue(BUT_ID_WALKH, (float) ((signed char)( (int)vals[1]-128 ) + 1));
311  SetDataValue(BUT_ID_LOOKV, (float) ((signed char)( (int)vals[2]-128 )));
312  SetDataValue(BUT_ID_LOOKH, (float) ((signed char)( (int)vals[3]-128 )));
313  }
314  else
315  {
316  SetDataValue(BUT_ID_LOOKV, (float) ((signed char)( (int)vals[0]-128 )));
317  SetDataValue(BUT_ID_LOOKH, (float) ((signed char)( (int)vals[1]-128 )));
318  SetDataValue(BUT_ID_WALKV, (float) ((signed char)( (int)vals[2]-128 )));
319  SetDataValue(BUT_ID_WALKH, (float) ((signed char)( (int)vals[3]-128 ) - 1));
320  }
321 
322  SetDataValue(BUT_ID_PAN, (float) ((vals[0]<<8) + vals[1]));
323  SetDataValue(BUT_ID_TILT, (float) ((vals[2]<<8) + vals[3]));
324 
325  m_iButtons = vals[4];
326  m_iExt = vals[5];
327 
328  SetDataValue(BUT_ID_R1, (m_iButtons & BUT_R1));
329  SetDataValue(BUT_ID_R2, (m_iButtons & BUT_R2));
330  SetDataValue(BUT_ID_R3, (m_iButtons & BUT_R3));
331  SetDataValue(BUT_ID_L4, (m_iButtons & BUT_L4));
332  SetDataValue(BUT_ID_L5, (m_iButtons & BUT_L5));
333  SetDataValue(BUT_ID_L6, (m_iButtons & BUT_L6));
334  SetDataValue(BUT_ID_RT, (m_iButtons & BUT_RT));
335  SetDataValue(BUT_ID_LT, (m_iButtons & BUT_LT));
336  }
337 
338  index = -1;
339  m_Port.flush();
340  bFound = true;
341  }
342  }
343 
344  }
345 
346  CheckStartedStopped();
348  }
349 }
350 
352 {
353  AnimatSim::Robotics::RemoteControl::Load(oXml);
354 
355  oXml.IntoElem();
356  Port(oXml.GetChildString("Port", m_strPort));
357  BaudRate(oXml.GetChildInt("BaudRate", m_iBaudRate));
358  oXml.OutOfElem();
359 }
360 
361 
362  } //RobotIOControls
363  } // Robotics
364 } //RoboticsAnimatSim
365 
CStdPtrArray< RemoteControlLinkage > m_aryLinks
Definition: RemoteControl.h:14
virtual bool InSimulation()
Used to determine if we are running in a simulation, or in a real control mode.
Definition: Simulator.cpp:1673
virtual bool SetData(const std::string &strDataType, const std::string &strValue, bool bThrowError=true)
Set a variable based on a string data type name.
virtual void QueryProperties(CStdPtrArray< TypeProperty > &aryProperties)
Queries this object for a list of properties that can be changed using SetData.
virtual void Load(StdUtils::CStdXml &oXml)
Loads the item using an XML data packet.
Simulator * m_lpSim
The pointer to a Simulation.
Definition: AnimatBase.h:43
virtual void StepIO()
This method is called from within the IO thread. It calls StepIO for each part.
virtual bool Paused()
Gets whether the Simulation is paused.
Definition: Simulator.cpp:347
virtual bool IntoElem()
Goes into the next element where the cursor is located.
Definition: StdXml.cpp:42
virtual void ShutdownIO()
This method is called just before the IO thread is closed down. It gives the IO objects a chance to d...
virtual int GetChildInt(std::string strElementName)
Gets an integer value from the element with the specified name.
Definition: StdXml.cpp:456
bool Std_IsAboveMin(int iMinVal, int iVal, bool bThrowError, std::string strParamName, bool bInclusiveLimit)
Tests if a number is above a minimum value.
int m_iBaudRate
The baud rate of communications for this XBee.
Declares the vortex structure class.
Declares the vortex hinge class.
A standard xml manipulation class.
Definition: StdXml.h:19
virtual void StepIO()
This method is called from within the IO thread. It calls StepIO for each part.
virtual std::string GetChildString(std::string strElementName)
Gets a string value from the element with the specified name.
Definition: StdXml.cpp:307
virtual bool SetData(const std::string &strDataType, const std::string &strValue, bool bThrowError=true)
Set a variable based on a string data type name.
void Std_TraceMsg(const int iLevel, std::string strMessage, std::string strSourceFile, int iSourceLine, bool bLogToFile, bool bPrintHeader)
Traces a message to the debugger window.
bool m_bEnabled
Tells if this item is enabled or not. If it is not enabled then it is not run.
Definition: AnimatBase.h:40
virtual bool OutOfElem()
Goes out of the element where the cursor is located.
Definition: StdXml.cpp:56
CStdMap< std::string, int > m_aryDataIDMap
Used to map property names to IDs when UseRemoteDataTypes is true.
Definition: RemoteControl.h:23
bool Std_IsBlank(std::string strVal)
Trims a string and tests if a string is blank.
std::string Std_CheckString(std::string strVal)
Converts a string to upper case and trims it.
virtual void SimStarting()
Called just before the simulation starts.
bool m_bSetupComplete
Set to true once the IO is setup correctly.
Classes for implementing the cm-labs vortex physics engine for AnimatLab.
std::string m_strPort
The serial port this Xbee communicates on.
unsigned char m_iButtons
buttons are 0 or 1 (PRESSED), and bitmapped