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 <thread>
26 #include <mutex>
27 #include <condition_variable>
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 nowNS()
51  {
52  return std::chrono::duration_cast<std::chrono::nanoseconds>(ClockT::now().time_since_epoch()).count();
53  }
54 
55  template<class T>
57  {
58  TripleBufferWithGuardAndTime(std::condition_variable* cv): cv {cv} {}
59 
60  std::unique_lock<std::recursive_mutex> guard()
61  {
62  return std::unique_lock<std::recursive_mutex> {m};
63  }
64 
65  std::size_t getLastWriteT() const
66  {
67  return lastwriteNs;
68  }
69  bool isLastWrite1SecondAgo() const
70  {
71  return (lastwriteNs + 1000000000 < nowNS());
72  }
73 
74  void reinit(const T& i)
75  {
76  tb.reinitAllBuffers(i);
77  }
78 
80  {
81  return tb.getWriteBuffer();
82  }
83  const T& getReadBuffer() const
84  {
85  return tb.getReadBuffer();
86  }
87  void write()
88  {
89  auto g = guard();
90  lastwriteNs = nowNS();
91  tb.commitWrite();
92  cv->notify_all();
93  }
94  void read()
95  {
96  tb.updateReadBuffer();
97  }
98 
99  private:
100  mutable std::recursive_mutex m;
102  std::atomic<std::uintmax_t> lastwriteNs {0};
103  std::condition_variable* cv;
104  };
105 
106 
107 
108  /**
109  * @class RobotUnitSimulationPropertyDefinitions
110  * @brief
111  */
114  {
115  public:
118  {
119  defineOptionalProperty<std::string>("SimulatorName", "Simulator", "Name of the simulator component that should be used");
120  defineOptionalProperty<bool>("SynchronizedSimulation", false, "If the simulation should be synchronized", PropertyDefinitionBase::eModifiable);
121  defineOptionalProperty<std::size_t>("ControlIterationMs", 10, "Time each iteration should take (in ms)");
122  defineOptionalProperty<std::string>("SimulatorRobotListenerInterfaceTopic", "", "Name of the simulator topic for SimulatorRobotListenerInterface (empty defaults to Simulator_Robot_<ROBOTNAME>");
123  defineOptionalProperty<std::string>("SimulatorForceTorqueListenerInterfaceTopic", "ForceTorqueDynamicSimulationValues", "Name of the simulator topic for SimulatorForceTorqueListenerInterface");
124 
125  defineOptionalProperty<float>("maxLinearPlatformVelocity", 2000, "[mm/s]");
126  defineOptionalProperty<float>("maxAngularPlatformVelocity", 1, "[rad/s]");
127 
128  defineOptionalProperty<std::string>(
129  "ForceTorqueSensorMapping", "",
130  "A list of mappings to modify the forceTorque sensors given in the robot format. "
131  "Syntax (comma SV of colon SV): 'NameInFile:ReportName[:ReportFrame],NameInFile2:ReportName2[:ReportFrame2]' "
132  "This would cause reporting of the ft sensor called 'NameInFile' under the name 'ReportName' and optionally change the report frame to 'ReportFrame'. "
133  "IMPORTANT: (1) The original reporting frame of the simulator has to be the parent node of 'NameInFile'."
134  " (2) The transformation from the original reporting frame to 'ReportFrame' should be fix "
135  "(there should be no joints in the kinematic chain between them),"
136  " since the transformation is done without access to the joint values"
137  );
138  }
139  };
140 
141 
142  /**
143  * @defgroup Component-RobotUnitSimulation RobotUnitSimulation
144  * @ingroup ArmarXSimulation-Components
145  * A description of the component RobotUnitSimulation.
146  *
147  * @class RobotUnitSimulation
148  * @ingroup Component-RobotUnitSimulation
149  * @brief Brief description of class RobotUnitSimulation.
150  *
151  * Detailed description of class RobotUnitSimulation.
152  */
154  virtual public RobotUnit,
155  virtual public RobotUnitSimulationSinterface
156  {
157  public:
159  torquesTB {&cvGotSensorData},
160  anglesTB {&cvGotSensorData},
161  velocitiesTB {&cvGotSensorData},
162  robPoseTB {&cvGotSensorData},
163  robVelTB {&cvGotSensorData},
164  forceTorqueTB {&cvGotSensorData}
165  {}
166  /**
167  * @see armarx::ManagedIceObject::getDefaultName()
168  */
169  std::string getDefaultName() const override
170  {
171  return "RobotUnitSimulation";
172  }
173 
174  void componentPropertiesUpdated(const std::set<std::string>& changedProperties) override;
175 
176  protected:
177  /**
178  * @see PropertyUser::createPropertyDefinitions()
179  */
181  {
183  }
184 
185  // RobotUnit interface
186  protected:
187  void onInitRobotUnit() override;
188  void onConnectRobotUnit() override;
189 
190  void joinControlThread() override;
191 
192  void rtTask();
193 
194  std::atomic_bool shutdownRtThread {false};
195  std::thread rtThread;
196  SimulatorInterfacePrx simulatorPrx;
198  std::string simulatorPrxName;
199  std::string robotName;
200 
203 
205 
206  public:
207  void reportState(SimulatedRobotState const& state, const Ice::Current& = Ice::emptyCurrent) override;
208 
209  private:
210  void updateForceTorque(ForceTorqueData const& ftData, IceUtil::Time timestamp);
211  void fillTB(TripleBufferWithGuardAndTime<std::vector<float>>& b, const NameValueMap& nv, const std::string name) const;
212  void rtUpdateSensors(bool wait);
213  void rtSendCommands();
214 
215  bool skipReport() const;
216 
217  const std::string& getMappedFTName(const std::string& name)const
218  {
219  return ftMappings.count(name) ? ftMappings.at(name).sensorName : name;
220  }
221  const std::string& getMappedFTReportingFrame(const std::string& name, const std::string& unmappedFrame)const
222  {
223  return ftMappings.count(name) ? ftMappings.at(name).reportFrame : unmappedFrame;
224  }
225  Eigen::Matrix3f getMappedFTReportingTransformation(const std::string& name)const
226  {
227  return ftMappings.count(name) ? ftMappings.at(name).reportTransformation : Eigen::Matrix3f::Identity();
228  }
229 
230  void rtPollRobotState();
231  std::atomic_bool isPolling {false};
232 
233  struct RobVel
234  {
235  Eigen::Vector3f lin {std::nanf(""), std::nanf(""), std::nanf("")};
236  Eigen::Vector3f ang {std::nanf(""), std::nanf(""), std::nanf("")};
237  };
238  struct FT
239  {
240  Eigen::Vector3f force {std::nanf(""), std::nanf(""), std::nanf("")};
241  Eigen::Vector3f torque {std::nanf(""), std::nanf(""), std::nanf("")};
242  };
243  // ////////////////////////////////////////////////////////////////////////////////////////////////// //
244  //devs
245  // ////////////////////////////////////////////////////////////////////////////////////////////////// //
246  std::condition_variable cvGotSensorData;
247  std::atomic<bool> gotSensorData{false};
248  IceUtil::Time sensorValuesTimestamp;
249  //joints
250  KeyValueVector<std::string, JointSimulationDevicePtr> jointDevs;
251  TripleBufferWithGuardAndTime<std::vector<float>> torquesTB;
252  TripleBufferWithGuardAndTime<std::vector<float>> anglesTB;
253  TripleBufferWithGuardAndTime<std::vector<float>> velocitiesTB;
254  NameValueMap velocitiesCtrl;
255  NameValueMap anglesCtrl;
256  NameValueMap torquesCtrl;
257  //platform
258  PlatformSimulationDevicePtr platformDev;
259  //pos/vel
260  TripleBufferWithGuardAndTime<Eigen::Matrix4f> robPoseTB;
261  TripleBufferWithGuardAndTime<RobVel> robVelTB;
262  //sensor
263  KeyValueVector<std::string, ForceTorqueSimulationSensorDevicePtr> forceTorqueDevs;
264  TripleBufferWithGuardAndTime<std::vector<FT>> forceTorqueTB;
265  std::vector<AtomicWrapper<std::uintmax_t>> forceTorqueTimes;
266  struct FTMappingData
267  {
268  std::string sensorName;
269  std::string originalReportFrame;
270  std::string reportFrame;
271  Eigen::Matrix3f reportTransformation;
272  };
273  std::map<std::string, FTMappingData> ftMappings;
274  //pose
275  // GlobalRobotPoseSimulationSensorDevicePtr globalPoseDevice;
276  ///TODO IMU
277  // ////////////////////////////////////////////////////////////////////////////////////////////////// //
278  //other
279  // ////////////////////////////////////////////////////////////////////////////////////////////////// //
280  //settings
281  std::atomic_bool synchronizedSimulation;
282  IceUtil::Time controlIterationMs;
283  std::string simulatorRobotListenerInterfaceTopic;
284  std::string simulatorForceTorqueListenerInterfaceTopic;
285  //metadata
286  std::atomic<std::uintmax_t> iterationCount {0};
287 
288  // RobotUnit interface
289  public:
291  {
292  return controlIterationMs;
293  }
294 
295  // RobotUnitManagementInterface interface
296  public:
297  bool isSimulation(const Ice::Current&) const override
298  {
299  return true;
300  }
301  };
302 }
armarx::TripleBufferWithGuardAndTime::getReadBuffer
const T & getReadBuffer() const
Definition: RobotUnitSimulation.h:83
armarx::RobotUnitSimulation::getDefaultName
std::string getDefaultName() const override
Definition: RobotUnitSimulation.h:169
armarx::RobotUnitSimulation::createPropertyDefinitions
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
Definition: RobotUnitSimulation.h:180
armarx::nowNS
std::uintmax_t nowNS()
Definition: RobotUnitSimulation.h:50
armarx::RobotUnitSimulation::rtThread
std::thread rtThread
Definition: RobotUnitSimulation.h:195
armarx::RobotUnitSimulation::RobotUnitSimulation
RobotUnitSimulation()
Definition: RobotUnitSimulation.h:158
RobotUnit.h
armarx::RobotUnitSimulation::simulatorPrxName
std::string simulatorPrxName
Definition: RobotUnitSimulation.h:198
armarx::TripleBufferWithGuardAndTime::write
void write()
Definition: RobotUnitSimulation.h:87
armarx::RobotUnitSimulation::reportState
void reportState(SimulatedRobotState const &state, const Ice::Current &=Ice::emptyCurrent) override
Definition: RobotUnitSimulation.cpp:350
Pose.h
armarx::TripleBufferWithGuardAndTime::guard
std::unique_lock< std::recursive_mutex > guard()
Definition: RobotUnitSimulation.h:60
armarx::PropertyDefinitionContainer::prefix
std::string prefix
Prefix of the properties such as namespace, domain, component name, etc.
Definition: PropertyDefinitionContainer.h:333
armarx::RobotUnitSimulation::maxAngularPlatformVelocity
float maxAngularPlatformVelocity
Definition: RobotUnitSimulation.h:202
armarx::TripleBufferWithGuardAndTime::TripleBufferWithGuardAndTime
TripleBufferWithGuardAndTime(std::condition_variable *cv)
Definition: RobotUnitSimulation.h:58
armarx::TripleBufferWithGuardAndTime::isLastWrite1SecondAgo
bool isLastWrite1SecondAgo() const
Definition: RobotUnitSimulation.h:69
GfxTL::Identity
void Identity(MatrixXX< N, N, T > *a)
Definition: MatrixXX.h:523
IMUSimulationSensorDevice.h
armarx::RobotUnitSimulation::robot
VirtualRobot::RobotPtr robot
Definition: RobotUnitSimulation.h:204
armarx::TripleBufferWithGuardAndTime::reinit
void reinit(const T &i)
Definition: RobotUnitSimulation.h:74
armarx::RobotUnitSimulationPropertyDefinitions
Definition: RobotUnitSimulation.h:112
armarx::RobotUnitSimulation::onConnectRobotUnit
void onConnectRobotUnit() override
called in onConnectComponent
Definition: RobotUnitSimulation.cpp:122
ForceTorqueSimulationSensorDevice.h
armarx::RobotUnitSimulation::robotName
std::string robotName
Definition: RobotUnitSimulation.h:199
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
Component.h
armarx::TripleBufferWithGuardAndTime
Definition: RobotUnitSimulation.h:56
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:297
armarx::TripleBufferWithGuardAndTime::getWriteBuffer
T & getWriteBuffer()
Definition: RobotUnitSimulation.h:79
armarx::control::njoint_controller::platform::platform_follower_controller::NameValueMap
std::map< std::string, float > NameValueMap
Definition: PlatformFollowerController.h:91
NJointController.h
armarx::Component::getConfigIdentifier
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition: Component.cpp:74
armarx::RobotUnitSimulationPropertyDefinitions::RobotUnitSimulationPropertyDefinitions
RobotUnitSimulationPropertyDefinitions(std::string prefix)
Definition: RobotUnitSimulation.h:116
GfxTL::Matrix3f
MatrixXX< 3, 3, float > Matrix3f
Definition: MatrixXX.h:600
armarx::RobotUnitSimulation::joinControlThread
void joinControlThread() override
Implementations have to join their ControlThread in this hook. (used by RobotUnit::finishRunning())
Definition: RobotUnitSimulation.cpp:131
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:137
armarx::WriteBufferedTripleBuffer
Same as the TripleBuffer, but partial writes of the data structure are ok. The write operation may be...
Definition: TripleBuffer.h:267
PlatformSimulationDevice.h
armarx::RobotUnitSimulation::simulatorPrx
SimulatorInterfacePrx simulatorPrx
Definition: RobotUnitSimulation.h:196
cv
Definition: helper.h:35
JointSimulationDevice.h
armarx::TripleBufferWithGuardAndTime::read
void read()
Definition: RobotUnitSimulation.h:94
T
float T
Definition: UnscentedKalmanFilterTest.cpp:35
armarx::RobotUnitSimulation
Brief description of class RobotUnitSimulation.
Definition: RobotUnitSimulation.h:153
armarx::RobotUnitPropertyDefinitions
Definition: RobotUnit.h:45
armarx::RobotUnitSimulation::simulationDataTimestampInMicroSeconds
std::atomic< long > simulationDataTimestampInMicroSeconds
Definition: RobotUnitSimulation.h:197
armarx::PropertyDefinitionsPtr
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
Definition: forward_declarations.h:34
armarx::RobotUnitSimulation::getControlThreadTargetPeriod
IceUtil::Time getControlThreadTargetPeriod() const override
The ControlThread's period.
Definition: RobotUnitSimulation.h:290
armarx::RobotUnitSimulation::maxLinearPlatformVelocity
float maxLinearPlatformVelocity
Definition: RobotUnitSimulation.h:201
armarx::PropertyDefinitionBase::eModifiable
@ eModifiable
Definition: PropertyDefinitionInterface.h:57
armarx::RobotUnitSimulation::onInitRobotUnit
void onInitRobotUnit() override
called in onInitComponent
Definition: RobotUnitSimulation.cpp:38
GlobalRobotPoseSimulationSensorDevice.h
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::RobotUnitSimulation::shutdownRtThread
std::atomic_bool shutdownRtThread
Definition: RobotUnitSimulation.h:194
VirtualRobot::RobotPtr
std::shared_ptr< class Robot > RobotPtr
Definition: Bus.h:18
armarx::TripleBufferWithGuardAndTime::getLastWriteT
std::size_t getLastWriteT() const
Definition: RobotUnitSimulation.h:65
armarx::RobotUnitSimulation::componentPropertiesUpdated
void componentPropertiesUpdated(const std::set< std::string > &changedProperties) override
Definition: RobotUnitSimulation.cpp:602