RobotUnitSimulation.h
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * ArmarX is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * ArmarX is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * @package ArmarXSimulation::ArmarXObjects::RobotUnitSimulation
17  * @author Raphael Grimm ( raphael dot grimm at kit dot edu )
18  * @date 2017
19  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 
23 #pragma once
24 
25 #include <condition_variable>
26 #include <mutex>
27 #include <thread>
28 
29 #include <VirtualRobot/Robot.h>
30 
32 
36 
37 #include <ArmarXSimulation/interface/RobotUnitSimulationInterface.h>
38 
44 
45 namespace armarx
46 {
47  using ClockT = std::chrono::high_resolution_clock;
48 
49  //we can't store durations in atoms -> store nanoseconds
50  inline std::uintmax_t
52  {
53  return std::chrono::duration_cast<std::chrono::nanoseconds>(
54  ClockT::now().time_since_epoch())
55  .count();
56  }
57 
58  template <class T>
60  {
61  TripleBufferWithGuardAndTime(std::condition_variable* cv) : cv{cv}
62  {
63  }
64 
65  std::unique_lock<std::recursive_mutex>
67  {
68  return std::unique_lock<std::recursive_mutex>{m};
69  }
70 
71  std::size_t
72  getLastWriteT() const
73  {
74  return lastwriteNs;
75  }
76 
77  bool
79  {
80  return (lastwriteNs + 1000000000 < nowNS());
81  }
82 
83  void
84  reinit(const T& i)
85  {
86  tb.reinitAllBuffers(i);
87  }
88 
89  T&
91  {
92  return tb.getWriteBuffer();
93  }
94 
95  const T&
96  getReadBuffer() const
97  {
98  return tb.getReadBuffer();
99  }
100 
101  void
103  {
104  auto g = guard();
105  lastwriteNs = nowNS();
106  tb.commitWrite();
107  cv->notify_all();
108  }
109 
110  void
112  {
113  tb.updateReadBuffer();
114  }
115 
116  private:
117  mutable std::recursive_mutex m;
119  std::atomic<std::uintmax_t> lastwriteNs{0};
120  std::condition_variable* cv;
121  };
122 
123  /**
124  * @class RobotUnitSimulationPropertyDefinitions
125  * @brief
126  */
128  {
129  public:
132  {
133  defineOptionalProperty<std::string>(
134  "SimulatorName",
135  "Simulator",
136  "Name of the simulator component that should be used");
137  defineOptionalProperty<bool>("SynchronizedSimulation",
138  false,
139  "If the simulation should be synchronized",
141  defineOptionalProperty<std::size_t>(
142  "ControlIterationMs", 10, "Time each iteration should take (in ms)");
143  defineOptionalProperty<std::string>(
144  "SimulatorRobotListenerInterfaceTopic",
145  "",
146  "Name of the simulator topic for SimulatorRobotListenerInterface (empty defaults "
147  "to Simulator_Robot_<ROBOTNAME>");
148  defineOptionalProperty<std::string>(
149  "SimulatorForceTorqueListenerInterfaceTopic",
150  "ForceTorqueDynamicSimulationValues",
151  "Name of the simulator topic for SimulatorForceTorqueListenerInterface");
152 
153  defineOptionalProperty<float>("maxLinearPlatformVelocity", 2000, "[mm/s]");
154  defineOptionalProperty<float>("maxAngularPlatformVelocity", 1, "[rad/s]");
155 
156  defineOptionalProperty<std::string>(
157  "ForceTorqueSensorMapping",
158  "",
159  "A list of mappings to modify the forceTorque sensors given in the robot format. "
160  "Syntax (comma SV of colon SV): "
161  "'NameInFile:ReportName[:ReportFrame],NameInFile2:ReportName2[:ReportFrame2]' "
162  "This would cause reporting of the ft sensor called 'NameInFile' under the name "
163  "'ReportName' and optionally change the report frame to 'ReportFrame'. "
164  "IMPORTANT: (1) The original reporting frame of the simulator has to be the parent "
165  "node of 'NameInFile'."
166  " (2) The transformation from the original reporting frame to 'ReportFrame' should "
167  "be fix "
168  "(there should be no joints in the kinematic chain between them),"
169  " since the transformation is done without access to the joint values");
170  }
171  };
172 
173  /**
174  * @defgroup Component-RobotUnitSimulation RobotUnitSimulation
175  * @ingroup ArmarXSimulation-Components
176  * A description of the component RobotUnitSimulation.
177  *
178  * @class RobotUnitSimulation
179  * @ingroup Component-RobotUnitSimulation
180  * @brief Brief description of class RobotUnitSimulation.
181  *
182  * Detailed description of class RobotUnitSimulation.
183  */
185  virtual public RobotUnit,
186  virtual public RobotUnitSimulationSinterface
187  {
188  public:
190  torquesTB{&cvGotSensorData},
191  anglesTB{&cvGotSensorData},
192  velocitiesTB{&cvGotSensorData},
193  robPoseTB{&cvGotSensorData},
194  robVelTB{&cvGotSensorData},
195  forceTorqueTB{&cvGotSensorData}
196  {
197  }
198 
199  /**
200  * @see armarx::ManagedIceObject::getDefaultName()
201  */
202  std::string
203  getDefaultName() const override
204  {
205  return "RobotUnitSimulation";
206  }
207 
208  void componentPropertiesUpdated(const std::set<std::string>& changedProperties) override;
209 
210  protected:
211  /**
212  * @see PropertyUser::createPropertyDefinitions()
213  */
216  {
219  }
220 
221  // RobotUnit interface
222  protected:
223  void onInitRobotUnit() override;
224  void onConnectRobotUnit() override;
225 
226  void joinControlThread() override;
227 
228  void rtTask();
229 
230  std::atomic_bool shutdownRtThread{false};
231  std::thread rtThread;
232  SimulatorInterfacePrx simulatorPrx;
234  std::string simulatorPrxName;
235  std::string robotName;
236 
239 
241 
242  public:
243  void reportState(SimulatedRobotState const& state,
244  const Ice::Current& = Ice::emptyCurrent) override;
245 
246  private:
247  void updateForceTorque(ForceTorqueData const& ftData, IceUtil::Time timestamp);
248  void fillTB(TripleBufferWithGuardAndTime<std::vector<float>>& b,
249  const NameValueMap& nv,
250  const std::string name) const;
251  void rtUpdateSensors(bool wait);
252  void rtSendCommands();
253 
254  bool skipReport() const;
255 
256  const std::string&
257  getMappedFTName(const std::string& name) const
258  {
259  return ftMappings.count(name) ? ftMappings.at(name).sensorName : name;
260  }
261 
262  const std::string&
263  getMappedFTReportingFrame(const std::string& name, const std::string& unmappedFrame) const
264  {
265  return ftMappings.count(name) ? ftMappings.at(name).reportFrame : unmappedFrame;
266  }
267 
269  getMappedFTReportingTransformation(const std::string& name) const
270  {
271  return ftMappings.count(name) ? ftMappings.at(name).reportTransformation
273  }
274 
275  void rtPollRobotState();
276  std::atomic_bool isPolling{false};
277 
278  struct RobVel
279  {
280  Eigen::Vector3f lin{std::nanf(""), std::nanf(""), std::nanf("")};
281  Eigen::Vector3f ang{std::nanf(""), std::nanf(""), std::nanf("")};
282  };
283 
284  struct FT
285  {
286  Eigen::Vector3f force{std::nanf(""), std::nanf(""), std::nanf("")};
287  Eigen::Vector3f torque{std::nanf(""), std::nanf(""), std::nanf("")};
288  };
289 
290  // ////////////////////////////////////////////////////////////////////////////////////////////////// //
291  //devs
292  // ////////////////////////////////////////////////////////////////////////////////////////////////// //
293  std::condition_variable cvGotSensorData;
294  std::atomic<bool> gotSensorData{false};
295  IceUtil::Time sensorValuesTimestamp;
296  //joints
297  KeyValueVector<std::string, JointSimulationDevicePtr> jointDevs;
298  TripleBufferWithGuardAndTime<std::vector<float>> torquesTB;
299  TripleBufferWithGuardAndTime<std::vector<float>> anglesTB;
300  TripleBufferWithGuardAndTime<std::vector<float>> velocitiesTB;
301  NameValueMap velocitiesCtrl;
302  NameValueMap anglesCtrl;
303  NameValueMap torquesCtrl;
304  //platform
305  PlatformSimulationDevicePtr platformDev;
306  //pos/vel
307  TripleBufferWithGuardAndTime<Eigen::Matrix4f> robPoseTB;
308  TripleBufferWithGuardAndTime<RobVel> robVelTB;
309  //sensor
310  KeyValueVector<std::string, ForceTorqueSimulationSensorDevicePtr> forceTorqueDevs;
311  TripleBufferWithGuardAndTime<std::vector<FT>> forceTorqueTB;
312  std::vector<AtomicWrapper<std::uintmax_t>> forceTorqueTimes;
313 
314  struct FTMappingData
315  {
316  std::string sensorName;
317  std::string originalReportFrame;
318  std::string reportFrame;
319  Eigen::Matrix3f reportTransformation;
320  };
321 
322  std::map<std::string, FTMappingData> ftMappings;
323  //pose
324  // GlobalRobotPoseSimulationSensorDevicePtr globalPoseDevice;
325  ///TODO IMU
326  // ////////////////////////////////////////////////////////////////////////////////////////////////// //
327  //other
328  // ////////////////////////////////////////////////////////////////////////////////////////////////// //
329  //settings
330  std::atomic_bool synchronizedSimulation;
331  IceUtil::Time controlIterationMs;
332  std::string simulatorRobotListenerInterfaceTopic;
333  std::string simulatorForceTorqueListenerInterfaceTopic;
334  //metadata
335  std::atomic<std::uintmax_t> iterationCount{0};
336 
337  // RobotUnit interface
338  public:
341  {
342  return controlIterationMs;
343  }
344 
345  // RobotUnitManagementInterface interface
346  public:
347  bool
348  isSimulation(const Ice::Current&) const override
349  {
350  return true;
351  }
352  };
353 } // namespace armarx
armarx::TripleBufferWithGuardAndTime::getReadBuffer
const T & getReadBuffer() const
Definition: RobotUnitSimulation.h:96
armarx::RobotUnitSimulation::getDefaultName
std::string getDefaultName() const override
Definition: RobotUnitSimulation.h:203
armarx::RobotUnitSimulation::createPropertyDefinitions
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
Definition: RobotUnitSimulation.h:215
armarx::nowNS
std::uintmax_t nowNS()
Definition: RobotUnitSimulation.h:51
armarx::RobotUnitSimulation::rtThread
std::thread rtThread
Definition: RobotUnitSimulation.h:231
armarx::RobotUnitSimulation::RobotUnitSimulation
RobotUnitSimulation()
Definition: RobotUnitSimulation.h:189
RobotUnit.h
armarx::RobotUnitSimulation::simulatorPrxName
std::string simulatorPrxName
Definition: RobotUnitSimulation.h:234
armarx::TripleBufferWithGuardAndTime::write
void write()
Definition: RobotUnitSimulation.h:102
armarx::RobotUnitSimulation::reportState
void reportState(SimulatedRobotState const &state, const Ice::Current &=Ice::emptyCurrent) override
Definition: RobotUnitSimulation.cpp:389
Pose.h
armarx::TripleBufferWithGuardAndTime::guard
std::unique_lock< std::recursive_mutex > guard()
Definition: RobotUnitSimulation.h:66
armarx::PropertyDefinitionContainer::prefix
std::string prefix
Prefix of the properties such as namespace, domain, component name, etc.
Definition: PropertyDefinitionContainer.h:345
armarx::RobotUnitSimulation::maxAngularPlatformVelocity
float maxAngularPlatformVelocity
Definition: RobotUnitSimulation.h:238
armarx::TripleBufferWithGuardAndTime::TripleBufferWithGuardAndTime
TripleBufferWithGuardAndTime(std::condition_variable *cv)
Definition: RobotUnitSimulation.h:61
armarx::TripleBufferWithGuardAndTime::isLastWrite1SecondAgo
bool isLastWrite1SecondAgo() const
Definition: RobotUnitSimulation.h:78
GfxTL::Identity
void Identity(MatrixXX< N, N, T > *a)
Definition: MatrixXX.h:570
IMUSimulationSensorDevice.h
armarx::RobotUnitSimulation::robot
VirtualRobot::RobotPtr robot
Definition: RobotUnitSimulation.h:240
armarx::TripleBufferWithGuardAndTime::reinit
void reinit(const T &i)
Definition: RobotUnitSimulation.h:84
armarx::RobotUnitSimulationPropertyDefinitions
Definition: RobotUnitSimulation.h:127
armarx::RobotUnitSimulation::onConnectRobotUnit
void onConnectRobotUnit() override
called in onConnectComponent
Definition: RobotUnitSimulation.cpp:132
ForceTorqueSimulationSensorDevice.h
armarx::RobotUnitSimulation::robotName
std::string robotName
Definition: RobotUnitSimulation.h:235
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
Component.h
armarx::TripleBufferWithGuardAndTime
Definition: RobotUnitSimulation.h:59
armarx::ClockT
std::chrono::high_resolution_clock ClockT
Definition: RobotUnitSimulation.h:47
armarx::RobotUnitSimulation::isSimulation
bool isSimulation(const Ice::Current &) const override
Definition: RobotUnitSimulation.h:348
armarx::TripleBufferWithGuardAndTime::getWriteBuffer
T & getWriteBuffer()
Definition: RobotUnitSimulation.h:90
armarx::control::njoint_controller::platform::platform_follower_controller::NameValueMap
std::map< std::string, float > NameValueMap
Definition: PlatformFollowerController.h:88
NJointController.h
armarx::Component::getConfigIdentifier
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition: Component.cpp:79
armarx::RobotUnitSimulationPropertyDefinitions::RobotUnitSimulationPropertyDefinitions
RobotUnitSimulationPropertyDefinitions(std::string prefix)
Definition: RobotUnitSimulation.h:130
armarx::RobotUnitSimulation::joinControlThread
void joinControlThread() override
Implementations have to join their ControlThread in this hook. (used by RobotUnit::finishRunning())
Definition: RobotUnitSimulation.cpp:142
IceUtil::Handle< class PropertyDefinitionContainer >
armarx::RobotUnit
The RobotUnit class manages a robot and its controllers.
Definition: RobotUnit.h:180
armarx::RobotUnitSimulation::rtTask
void rtTask()
Definition: RobotUnitSimulation.cpp:149
armarx::WriteBufferedTripleBuffer
Same as the TripleBuffer, but partial writes of the data structure are ok. The write operation may be...
Definition: TripleBuffer.h:312
PlatformSimulationDevice.h
armarx::RobotUnitSimulation::simulatorPrx
SimulatorInterfacePrx simulatorPrx
Definition: RobotUnitSimulation.h:232
cv
Definition: helper.h:34
JointSimulationDevice.h
armarx::TripleBufferWithGuardAndTime::read
void read()
Definition: RobotUnitSimulation.h:111
GfxTL::Matrix3f
MatrixXX< 3, 3, float > Matrix3f
Definition: MatrixXX.h:649
T
float T
Definition: UnscentedKalmanFilterTest.cpp:38
armarx::RobotUnitSimulation
Brief description of class RobotUnitSimulation.
Definition: RobotUnitSimulation.h:184
armarx::RobotUnitPropertyDefinitions
Definition: RobotUnit.h:45
armarx::RobotUnitSimulation::simulationDataTimestampInMicroSeconds
std::atomic< long > simulationDataTimestampInMicroSeconds
Definition: RobotUnitSimulation.h:233
armarx::PropertyDefinitionsPtr
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
Definition: forward_declarations.h:35
armarx::RobotUnitSimulation::getControlThreadTargetPeriod
IceUtil::Time getControlThreadTargetPeriod() const override
The ControlThread's period.
Definition: RobotUnitSimulation.h:340
armarx::RobotUnitSimulation::maxLinearPlatformVelocity
float maxLinearPlatformVelocity
Definition: RobotUnitSimulation.h:237
armarx::PropertyDefinitionBase::eModifiable
@ eModifiable
Definition: PropertyDefinitionInterface.h:57
armarx::RobotUnitSimulation::onInitRobotUnit
void onInitRobotUnit() override
called in onInitComponent
Definition: RobotUnitSimulation.cpp:39
GlobalRobotPoseSimulationSensorDevice.h
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
armarx::RobotUnitSimulation::shutdownRtThread
std::atomic_bool shutdownRtThread
Definition: RobotUnitSimulation.h:230
VirtualRobot::RobotPtr
std::shared_ptr< class Robot > RobotPtr
Definition: Bus.h:19
armarx::TripleBufferWithGuardAndTime::getLastWriteT
std::size_t getLastWriteT() const
Definition: RobotUnitSimulation.h:72
armarx::RobotUnitSimulation::componentPropertiesUpdated
void componentPropertiesUpdated(const std::set< std::string > &changedProperties) override
Definition: RobotUnitSimulation.cpp:670