SharedMemoryController.cpp
Go to the documentation of this file.
2
3#include <boost/date_time/posix_time/posix_time.hpp>
4
5#include <Eigen/Dense>
6
8
12
17
19{
20 namespace base = armarx::control::njoint_controller::task_space;
21
22 armarx::NJointControllerRegistration<
27
33
39
45
47 base::NJointTSMixImpVelController>>
51
53 base::NJointTSImpColController>>
57
59 base::NJointTSMixImpVelColController>>
63
64 // Implement getClassName() method for templated NJointSharedMemoryTaskspaceController
65 template <>
66 std::string
68 class base::NJointTSVelController>::getClassName(const Ice::Current&) const
69 {
72 }
73
74 template <>
75 std::string
77 class base::NJointTSVelColController>::getClassName(const Ice::Current&) const
78 {
81 }
82
83 template <>
84 std::string
86 class base::NJointTSVeloColController>::getClassName(const Ice::Current&) const
87 {
90 }
91
92 template <>
93 std::string
95 class base::NJointTSImpController>::getClassName(const Ice::Current&) const
96 {
99 }
100
101 template <>
102 std::string
104 class base::NJointTSMixImpVelController>::
105 getClassName(const Ice::Current&) const
106 {
109 }
110
111 template <>
112 std::string
114 class base::NJointTSImpColController>::
115 getClassName(const Ice::Current&) const
116 {
119 }
120
121 template <>
122 std::string
124 class base::NJointTSMixImpVelColController>::
125 getClassName(const Ice::Current&) const
126 {
129 }
130
131 template <typename NJointTaskspaceController>
134 const armarx::NJointControllerConfigPtr& config,
135 const VirtualRobot::RobotPtr& robot) :
137 {
138 init();
139 }
140
141 // Method(s) of NJointSharedMemoryTaskspaceController in general
142 template <typename NJointTaskspaceController>
143 void
145 {
146 writer = std::make_unique<SharedMemoryWriter<ToSharedMemory>>(
147 "NJointSharedMemoryTaskspaceController_rt2shared_memory",
148 "NJointSharedMemoryTaskspaceController_rt2shared_memory_mutex");
149
150 reader = std::make_unique<SharedMemoryReader<FromSharedMemory>>(
151 "NJointSharedMemoryTaskspaceController_shared_memory2rt",
152 "NJointSharedMemoryTaskspaceController_shared_memory2rt_mutex");
153
154 ARMARX_CHECK(this->limb.size() <= MAX_N)
155 << "NJointSharedMemoryTaskspaceController currently supports maximum " << MAX_N
156 << " limbs!";
157
158 if (this->hands)
159 {
160 ARMARX_CHECK(this->hands->hands.size() == 0 or
161 this->hands->hands.size() == this->limb.size())
162 << "NJointSharedMemoryTaskspaceController currently supports either zero hands or "
163 "n_hands = n_limbs!";
164 }
165
166 writeConfig();
167
168 ARMARX_INFO << "-- NJointSharedMemoryTaskspaceController initialized --";
169 }
170
171 template <typename NJointTaskspaceController>
172 void
174 {
175 const auto [rtTargetSafe, ftSafe] = this->additionalTaskUpdateStatus();
176
177 if (not writer->sem.timed_wait(boost::posix_time::microsec_clock::universal_time() +
178 boost::posix_time::milliseconds(5)))
179 {
180 return;
181 }
182
183 // Compute time
184 for (auto& pair : this->limb)
185 {
186 pair.second->nonRTDeltaT =
187 pair.second->rtStatusInNonRT.accumulateTime - pair.second->nonRTAccumulateTime;
188 pair.second->nonRTAccumulateTime = pair.second->rtStatusInNonRT.accumulateTime;
189 }
190 if (this->hands)
191 {
192 for (auto& pair : this->hands->hands)
193 {
194 pair.second->nonRTDeltaT =
195 pair.second->rtsInNonRT.accumulateTime - pair.second->nonRTAccumulateTime;
196 pair.second->nonRTAccumulateTime = pair.second->rtsInNonRT.accumulateTime;
197 }
198 }
199
200
201 ToSharedMemory writeData;
202 {
203 unsigned int index = 0;
204 unsigned int indexJSC = 0;
205 for (auto& pair : this->limb)
206 {
207 auto& arm = pair.second;
208
209 // Taskspace (Current actual pose and twist)
210 Eigen::Matrix<float, 7, 1> currentPose;
211 currentPose.head(3) = simox::math::mat4f_to_pos(arm->rtStatusInNonRT.currentPose);
212 currentPose.tail(4) = simox::math::mat4f_to_quat(arm->rtStatusInNonRT.currentPose)
213 .coeffs(); // x,y,z,w
214 std::memcpy(
215 writeData.currentPose + (index * 7), currentPose.data(), sizeof(float) * 7);
216 std::memcpy(writeData.currentTwist + (index * 6),
217 arm->rtStatusInNonRT.currentTwist.data(),
218 sizeof(float) * 6);
219
220 // Taskspace (Current desired pose)
221 Eigen::Matrix<float, 7, 1> currentDesiredPose;
222 currentDesiredPose.head(3) =
223 simox::math::mat4f_to_pos(arm->rtStatusInNonRT.desiredPose);
224 currentDesiredPose.tail(4) =
225 simox::math::mat4f_to_quat(arm->rtStatusInNonRT.desiredPose)
226 .coeffs(); // x,y,z,w
227 std::memcpy(writeData.currentDesiredPose + index * 7,
228 currentDesiredPose.data(),
229 sizeof(float) * 7);
230
231 // Forces
232 std::memcpy(writeData.currentForceTorque + (index * 6),
233 arm->rtStatusInNonRT.currentForceTorque.data(),
234 sizeof(float) * 6);
235
236 {
237 // Joint Space
238 const unsigned int n = arm->rtStatusInNonRT.jointPosition.size();
240 std::memcpy(writeData.currentJointAngles + indexJSC,
241 arm->rtStatusInNonRT.jointPosition.data(),
242 sizeof(float) * n);
243 std::memcpy(writeData.currentJointVelocities + indexJSC,
244 arm->rtStatusInNonRT.qvelFiltered.data(),
245 sizeof(float) * n);
246 indexJSC += n;
247 }
248
249 //writeData.deltaTinSeconds = arm->rtStatusInNonRT.deltaT;
250 writeData.deltaTinSeconds = arm->nonRTDeltaT;
251
252 writeAdditonalDataToSM(writeData, arm->nonRtConfig, index);
253
254 index++;
255 }
256 }
257
258 if (this->hands)
259 {
260 unsigned int index = 0;
261 for (auto& [_, hand] : this->hands->hands)
262 {
263 const unsigned int n = hand->targetNonRT.jointPosition.value().size();
265 std::memcpy(writeData.currentHandConfig + index,
266 hand->targetNonRT.jointPosition->data(),
267 sizeof(float) * n);
268 index += n;
269 }
270 }
271
272 writeCoordinatorDataToSM(writeData);
273
274 writeData.rtSafe = rtTargetSafe;
275 writeData.n_limbs = this->limb.size();
276
277 writer->updateNonLocking(writeData);
278
279 reader->sem.post(); // notify shared_memory that writing is done
280
281 if (not rtTargetSafe)
282 {
284 }
285
286 // wait for shared_memory to have read and written but maximum 5ms
287 // (e.g., when shared_memory code was quit)
288 if (not writer->sem.timed_wait(boost::posix_time::microsec_clock::universal_time() +
289 boost::posix_time::milliseconds(5)))
290 {
291 ARMARX_RT_LOGF_WARN("Waiting for semaphore timed out");
292 return;
293 }
294
295 FromSharedMemory readData;
296 reader->updateNonLocking(readData);
297
298 if (readData.initialized)
299 {
300 unsigned int index = 0;
301 unsigned int indexJSC = 0;
302 for (auto& pair : this->limb)
303 {
304 auto& arm = pair.second;
305
306 // Task space
307 Eigen::Matrix<float, 7, 1> desiredPose;
308 std::memcpy(
309 desiredPose.data(), readData.desiredPose + (index * 7), sizeof(float) * 7);
310 const Eigen::Vector3f& pos = desiredPose.head(3);
311 const Eigen::Vector4f& orientation = desiredPose.tail(4);
312 const Eigen::Matrix4f pose =
313 simox::math::pos_quat_to_mat4f(pos, Eigen::Quaternionf(orientation));
314 arm->nonRtConfig.desiredPose = pose;
315 std::memcpy(arm->nonRtConfig.desiredTwist.data(),
316 readData.desiredTwist + (index * 6),
317 sizeof(float) * 6);
318
319 if (readData.useJointAngles)
320 {
321 // Joint space
322 const unsigned int n = arm->nonRtConfig.desiredNullspaceJointAngles->size();
324 std::memcpy(arm->nonRtConfig.desiredNullspaceJointAngles->data(),
325 readData.desiredJointAngles + indexJSC,
326 sizeof(float) * n);
327 indexJSC += n;
328 }
329
330 readAdditonalDataFromSM(readData, arm->nonRtConfig, index);
331
332 // ARMARX_RT_LOGF_INFO(
333 // "new target \n\n [%.2f]\n\n", pos(2)).deactivateSpam(1);
334
335 index++;
336 }
337 }
338 if (readData.initialized and this->hands)
339 {
340 unsigned int index = 0;
341 for (auto& [_, hand] : this->hands->hands)
342 {
343 const unsigned int n = hand->targetNonRT.jointPosition.value().size();
345 std::memcpy(hand->targetNonRT.jointPosition->data(),
346 readData.desiredHandConfig + index,
347 sizeof(float) * n);
348 index += n;
349 }
350 }
351
352 if (readData.initialized)
353 {
355 }
356
358 }
359
360 template <typename NJointTaskspaceController>
361 void
363 {
364 // TODO optional write config (joint names, etc.) to shared memory
365 }
366
367} // namespace armarx::control::njoint_controller::task_space
#define ARMARX_RT_LOGF_WARN(...)
uint8_t index
#define MAX_JS_DIM_N
#define MAX_N
#define MAX_HC_DIM_N
void writeAdditonalDataToSM(ToSharedMemory &writeData, const typename NJointTaskspaceController::Config &config, unsigned int index) const
NJointSharedMemoryTaskspaceController(const armarx::RobotUnitPtr &robotUnit, const armarx::NJointControllerConfigPtr &config, const VirtualRobot::RobotPtr &robot)
void readAdditonalDataFromSM(const FromSharedMemory &readData, typename NJointTaskspaceController::Config &config, unsigned int index) const
NJointTaskspaceController(const RobotUnitPtr &robotUnit, const NJointControllerConfigPtr &config, const VirtualRobot::RobotPtr &)
Definition Base.cpp:138
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_CHECK_LESS_EQUAL(lhs, rhs)
This macro evaluates whether lhs is less or equal (<=) rhs and if it turns out to be false it will th...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
Quaternion< float, 0 > Quaternionf
std::shared_ptr< class Robot > RobotPtr
Definition Bus.h:19
const simox::meta::EnumNames< ControllerType > ControllerTypeNames
Definition type.h:170
armarx::NJointControllerRegistration< NJointSharedMemoryTaskspaceController< base::NJointTSMixImpVelColController > > registrationControllerNJointCollisionAvoidanceTSMixedImpedanceVelocityController(armarx::control::common::ControllerTypeNames.to_name(armarx::control::common::ControllerType::SharedMemoryTSMixImpVelCol))
armarx::NJointControllerRegistration< NJointSharedMemoryTaskspaceController< base::NJointTSMixImpVelController > > registrationControllerNJointTSMixedImpedanceVelocityController(armarx::control::common::ControllerTypeNames.to_name(armarx::control::common::ControllerType::SharedMemoryTSMixImpVel))
armarx::NJointControllerRegistration< NJointSharedMemoryTaskspaceController< base::NJointTSVeloColController > > registrationControllerNJointSharedMemoryTSVeloColController(armarx::control::common::ControllerTypeNames.to_name(armarx::control::common::ControllerType::SharedMemoryTSVeloCol))
armarx::NJointControllerRegistration< NJointSharedMemoryTaskspaceController< base::NJointTSVelColController > > registrationControllerNJointSharedMemoryTSVelColController(armarx::control::common::ControllerTypeNames.to_name(armarx::control::common::ControllerType::SharedMemoryTSVelCol))
armarx::NJointControllerRegistration< NJointSharedMemoryTaskspaceController< base::NJointTSImpController > > registrationControllerNJointTSImpedanceController(armarx::control::common::ControllerTypeNames.to_name(armarx::control::common::ControllerType::SharedMemoryTSImp))
armarx::NJointControllerRegistration< NJointSharedMemoryTaskspaceController< base::NJointTSVelController > > registrationControllerNJointTSVelocityController(armarx::control::common::ControllerTypeNames.to_name(armarx::control::common::ControllerType::SharedMemoryTSVel))
armarx::NJointControllerRegistration< NJointSharedMemoryTaskspaceController< base::NJointTSImpColController > > registrationControllerNJointCollisionAvoidanceTSImpedanceController(armarx::control::common::ControllerTypeNames.to_name(armarx::control::common::ControllerType::SharedMemoryTSImpCol))
IceUtil::Handle< class RobotUnit > RobotUnitPtr
Definition FTSensor.h:34