AnimatLab  2
Test
RbFirmataHingeServo.cpp
1 // RbFirmataHingeServo.cpp: implementation of the RbFirmataHingeServo 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 "RbFirmataPart.h"
16 #include "RbFirmataHingeServo.h"
17 #include "RbFirmataController.h"
18 
19 namespace RoboticsAnimatSim
20 {
21  namespace Robotics
22  {
23  namespace RobotIOControls
24  {
25  namespace Firmata
26  {
27 
29 // Construction/Destruction
31 
32 RbFirmataHingeServo::RbFirmataHingeServo()
33 {
34  m_lpJoint = NULL;
35  m_iMaxPulse = 2400;
36  m_iMinPulse = 544;
37  m_bResetToStartPos = false;
38 
39  m_iMaxAngle = 179;
40  m_iMinAngle = 0;
41  m_iCenterAngle = 90;
42 
43  m_fltMaxAngle = RB_PI/2;
44  m_fltMinAngle = -RB_PI/2;
45 
46  m_fltPosFloatToFPSlope = (m_iMaxAngle-m_iMinAngle+1)/(m_fltMaxAngle-m_fltMinAngle);
47  m_fltPosFloatToFPIntercept = m_iCenterAngle;
48 
49  m_fltPosFPToFloatSlope = 1/m_fltPosFloatToFPSlope;
50  m_fltPosFPToFloatIntercept = -(m_fltPosFPToFloatSlope*m_iCenterAngle);
51 
52  m_iLastGoalPos = -1;
53 }
54 
55 RbFirmataHingeServo::~RbFirmataHingeServo()
56 {
57  try
58  {
59  //Do not delete because we do not own it.
60  m_lpJoint = NULL;
61  }
62  catch(...)
63  {Std_TraceMsg(0, "Caught Error in desctructor of RbFirmataHingeServo\r\n", "", -1, false, true);}
64 }
65 
66 int RbFirmataHingeServo::MaxPulse() {return m_iMaxPulse;}
67 
68 void RbFirmataHingeServo::MaxPulse(int iPulse)
69 {
70  Std_IsAboveMin(m_iMinPulse, iPulse, true, "MaxPulse");
71  m_iMaxPulse = iPulse;
72 }
73 
74 int RbFirmataHingeServo::MinPulse() {return m_iMinPulse;}
75 
76 void RbFirmataHingeServo::MinPulse(int iPulse)
77 {
78  Std_IsAboveMin(0, iPulse, true, "MinPulse");
79  Std_IsBelowMax(m_iMaxPulse, iPulse, true, "MinPulse");
80  m_iMinPulse = iPulse;
81 }
82 
83 bool RbFirmataHingeServo::ResetToStartPos() {return m_bResetToStartPos;}
84 
85 void RbFirmataHingeServo::ResetToStartPos(bool bVal) {m_bResetToStartPos = bVal;}
86 
87 float RbFirmataHingeServo::ConvertPosFPToRad(int iPos)
88 {
89  float fltPos = (m_fltPosFPToFloatSlope*iPos) + m_fltPosFPToFloatIntercept;
90  return fltPos;
91 }
92 
93 int RbFirmataHingeServo::ConvertPosRadToFP(float fltPos)
94 {
95  int iPos = (m_fltPosFloatToFPSlope*fltPos) + m_fltPosFloatToFPIntercept;
96  return iPos;
97 }
107 {
108  //Verify we are not putting invalid values in.
109  if(iPos < m_iMinAngle) iPos = m_iMinAngle;
110  if(iPos > m_iMaxAngle) iPos = m_iMaxAngle;
111 
112  //If the position we are setting is the same as we just set then no point sending it.
113  if(m_iLastGoalPos == iPos)
114  return;
115 
116  m_iLastGoalPos = iPos;
117 
118  std::cout << "Servo: " << iPos << "\r\n";
119 
120  m_lpFirmata->sendServo(m_iIOComponentID, iPos, true);
121 }
122 
134 {
135  int iPos = ConvertPosRadToFP(fltPos);
136 
137  SetGoalPosition_FP(iPos);
138 }
139 
140 #pragma region DataAccesMethods
141 
142 float *RbFirmataHingeServo::GetDataPointer(const std::string &strDataType)
143 {
144  //std::string strType = Std_CheckString(strDataType);
145 
146  //if(strType == "IOVALUE")
147  // return &m_fltIOValue;
148  //else
149  return RobotPartInterface::GetDataPointer(strDataType);
150 }
151 
152 bool RbFirmataHingeServo::SetData(const std::string &strDataType, const std::string &strValue, bool bThrowError)
153 {
154  std::string strType = Std_CheckString(strDataType);
155 
156  if(strType == "MAXPULSE")
157  {
158  MaxPulse((int) atoi(strValue.c_str()));
159  return true;
160  }
161 
162  if(strType == "MINPULSE")
163  {
164  MinPulse((int) atoi(strValue.c_str()));
165  return true;
166  }
167 
168  if(strType == "RESETTOSTARTPOS")
169  {
170  ResetToStartPos(Std_ToBool(strValue));
171  return true;
172  }
173 
174  return RobotPartInterface::SetData(strDataType, strValue, bThrowError);
175 }
176 
177 void RbFirmataHingeServo::QueryProperties(CStdPtrArray<TypeProperty> &aryProperties)
178 {
179  RobotPartInterface::QueryProperties(aryProperties);
180 
181  aryProperties.Add(new TypeProperty("MaxPulse", AnimatPropertyType::Integer, AnimatPropertyDirection::Set));
182  aryProperties.Add(new TypeProperty("MinPulse", AnimatPropertyType::Integer, AnimatPropertyDirection::Set));
183  aryProperties.Add(new TypeProperty("ResetToStartPos", AnimatPropertyType::Boolean, AnimatPropertyDirection::Set));
184 }
185 
186 #pragma endregion
187 
189 {
190  RobotPartInterface::Initialize();
191 
192  m_lpJoint = dynamic_cast<MotorizedJoint *>(m_lpPart);
193 }
194 
196 {
197  if(!m_lpSim->InSimulation())
198  {
199  m_lpFirmata->sendServoAttach(m_iIOComponentID);
200 
201  if(m_bResetToStartPos)
202  {
203  SetGoalPosition_FP(m_iCenterAngle);
204  IOValue(m_iCenterAngle);
205  }
206  }
207 }
208 
209 void RbFirmataHingeServo::StepIO(int iPartIdx)
210 {
211  if(!m_lpSim->InSimulation() && m_iIOValue != m_iLastGoalPos)
213 }
214 
216 {
217  RobotPartInterface::StepSimulation();
218 
219  if(m_lpJoint)
220  {
221  //Here we need to get the set velocity for this motor that is coming from the neural controller, and then make the real motor go that speed.
222  float fltSetPosition = m_lpJoint->JointPosition();
223  m_iIOValue = ConvertPosRadToFP(fltSetPosition);
224 
225  //if(m_iIOValue > 179)
226  // m_iIOValue = m_iIOValue;
227 
229  }
230 }
231 
232 void RbFirmataHingeServo::Load(CStdXml &oXml)
233 {
234  RobotPartInterface::Load(oXml);
235 
236  oXml.IntoElem(); //Into RigidBody Element
237  MinPulse(oXml.GetChildInt("MinPulse", m_iMinPulse));
238  MaxPulse(oXml.GetChildInt("MaxPulse", m_iMaxPulse));
239  ResetToStartPos(oXml.GetChildBool("ResetToStartPos", m_bResetToStartPos));
240  oXml.OutOfElem(); //OutOf RigidBody Element
241 }
242 
243  } //Firmata
244  } //RobotIOControls
245  } // Robotics
246 } //RoboticsAnimatSim
247 
virtual void StepSimulation()
Step the simulation for this object.
virtual bool InSimulation()
Used to determine if we are running in a simulation, or in a real control mode.
Definition: Simulator.cpp:1673
virtual void StepIO(int iPartIdx)
This method is used to send/recieve the actual IO. This will often be in a seperate thread than the S...
Simulator * m_lpSim
The pointer to a Simulation.
Definition: AnimatBase.h:43
virtual void SetupIO()
This method is called after all connections to whatever control board have been made. It is meant to be used to setup connection information specific to this part. For example, We connect to a Firmata microcontroller like an Arduino, and then do a setup that could take some time. We should not attempt to setup any of the pins until after the board itself has been setup. After that we need to loop through and setup all the parts. That is what this method is for.
bool Std_IsAboveMin(int iMinVal, int iVal, bool bThrowError, std::string strParamName, bool bInclusiveLimit)
Tests if a number is above a minimum value.
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 SetGoalPosition_FP(int iPos)
Sets the fixed point value of the servo goal position. This is the exact value that will be sent to t...
Declares the vortex structure class.
Declares the vortex hinge class.
float m_fltPosFPToFloatSlope
The conversion factor to convert radians to FP angle position.
bool Std_ToBool(int iVal)
Converts a value toa bool.
bool Std_IsBelowMax(int iMaxVal, int iVal, bool bThrowError, std::string strParamName, bool bInclusiveLimit)
Tests if a number is below a maximum value.
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.
std::string Std_CheckString(std::string strVal)
Converts a string to upper case and trims it.
virtual float * GetDataPointer(const std::string &strDataType)
Returns a float pointer to a data item of interest in this object.
int m_iIOValue
This stores the temporary IO value to be used later in IO calculations.
virtual void SetGoalPosition(float fltPos)
Sets the floating point value of the servo goal position. This is the position in radians...
Classes for implementing the cm-labs vortex physics engine for AnimatLab.