WholeBodyTrajectoryController.cpp
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 * @author Fabian Reister (fabian dot reister at kit dot edu)
17 * @date 2024
18 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
19 * GNU General Public License
20 */
21
23
24#include <cstdint>
25#include <optional>
26#include <set>
27
28#include <SimoxUtility/algorithm/string/string_conversion_eigen.h>
29#include <SimoxUtility/json/eigen_conversion.h>
30#include <SimoxUtility/json/json.h>
31#include <SimoxUtility/math/convert/mat4f_to_rpy.h>
32
40
52
54#include <armarx/control/interface/ConfigurableNJointControllerInterface.h>
55#include <armarx/control/njoint_controller/joint_space/aron/WholeBodyTrajectoryControllerConfig.aron.generated.h>
56
57#include <range/v3/view/zip.hpp>
58
60{
61
64
66 const NJointControllerConfigPtr& config,
67 const VirtualRobot::RobotPtr& robot) :
69 pidPlatform_(initialConfigData().pidPlatform.Kp,
70 initialConfigData().pidPlatform.Ki,
71 initialConfigData().pidPlatform.Kd,
72 initialConfigData().pidPlatform.maxControlValue,
73 initialConfigData().pidPlatform.maxDerivation),
74 opidPlatform_(initialConfigData().opidPlatform.Kp,
75 initialConfigData().opidPlatform.Ki,
76 initialConfigData().opidPlatform.Kd,
77 initialConfigData().opidPlatform.maxControlValue,
78 initialConfigData().opidPlatform.maxDerivation,
79 true)
80 {
81 ARMARX_IMPORTANT << "Creating "
84
85 ARMARX_CHECK_EXPRESSION(robotUnit);
86
87 ARMARX_INFO << "Using RT robot";
88 robot_ = useSynchronizedRtRobot();
90
91 ARMARX_INFO << "Created RT robot";
92
93
94 // initialize control targets
95 {
96 ARMARX_INFO << "Initializing control targets";
97 controlTargets_.platformTarget =
98 useControlTarget(robotUnit->getRobotPlatformName(),
99 ControlModes::HolonomicPlatformVelocity)
101 ARMARX_CHECK_EXPRESSION(controlTargets_.platformTarget)
102 << "The actuator " << robotUnit->getRobotPlatformName() << " has no control mode "
103 << ControlModes::HolonomicPlatformVelocity;
104
105 for (const auto& jointName : initialConfigData().jointNames)
106 {
107 auto* const controlTarget = useControlTarget<ControlTarget1DoFActuatorVelocity>(
108 jointName, ControlModes::Velocity1DoF);
109 ARMARX_CHECK_NOT_NULL(controlTarget) << jointName;
110
111 controlTargets_.jointTargets.push_back(controlTarget);
112 }
113 ARMARX_INFO << VAROUT(initialConfigData().jointNames);
114
115 for (const auto& jointName : initialConfigData().handJointNames)
116 {
117 auto* const controlTarget = useControlTarget<ControlTarget1DoFActuatorPosition>(
118 jointName, ControlModes::Position1DoF);
119 ARMARX_CHECK_NOT_NULL(controlTarget) << jointName;
120
121 controlTargets_.handTargets.push_back(controlTarget);
122 }
123 ARMARX_INFO << VAROUT(initialConfigData().handJointNames);
124 }
125
126 // initialize sensor values
127 {
128 ARMARX_INFO << "Initializing sensor values";
129
130 // initialize joint sensor values
131 {
132 for (const auto& jointName : initialConfigData().jointNames)
133 {
134 const SensorValueBase* sv = useSensorValue(jointName);
135 jointSensorValues_.push_back(sv->asA<SensorValue1DoFActuator>());
136 }
137 }
138
139 // initialize global pose sensor value
140 {
141 const SensorValueBase* sv =
143 svGlobalRobotLocalization_ =
145 }
146 }
147
148 // initialize arm PID controller
149 {
150 ARMARX_INFO << "Initializing PID controller";
151
152 std::vector<bool> isJointLimitless;
153 for (const auto& jointName : initialConfigData().jointNames)
154 {
155 const auto node = robot_->getRobotNode(jointName);
156 isJointLimitless.push_back(node->isLimitless());
157 }
158
159 pidArm_.emplace(initialConfigData().pidArm.Kp,
160 initialConfigData().pidArm.Ki,
161 initialConfigData().pidArm.Kd,
162 initialConfigData().pidArm.maxControlValue,
163 initialConfigData().pidArm.maxDerivation,
164 false,
165 isJointLimitless);
166
167 const std::size_t nDofArm = initialConfigData().jointNames.size();
168 pidArm_->preallocate(nDofArm);
169 }
170
171 // preallocate other PID controllers
172 {
174 pidPlatform_.preallocate(2);
175 }
176
177 // initialize jointNames
178 {
180 jointNames_ = initialConfigData().jointNames;
181 }
182
183 // initialize helper nodes etc
184 {
185 ARMARX_INFO << "Initializing helper nodes";
186 // FIXME remove hard coded string
187 const std::string tcpNodeName = "Hand R TCP";
188
189 // maybe this is causing issues (cloning rt robot in non rt part)
190 ARMARX_INFO << "Debug robot";
191 debugRobot_ = robot->clone();
192 ARMARX_INFO << "cloned.";
193
194 ARMARX_CHECK_NOT_NULL(debugRobot_);
195 publishTcpNode_ = debugRobot_->getRobotNode(tcpNodeName);
196 ARMARX_CHECK_NOT_NULL(publishTcpNode_);
197
198 rtTcpNode_ = robot_->getRobotNode(tcpNodeName);
199 ARMARX_CHECK_NOT_NULL(rtTcpNode_);
200 }
201
202 // initialize trajectory
203 ARMARX_INFO << "Initializing trajectory";
205 trajectory_.emplace(initialConfigData().trajectory);
206
208
209 // init debug data (for onPublish), preallocate memory (very important here!)
210 {
211 ARMARX_INFO << "Initializing debug data";
212 const DebugData initDebugData{
213 .localTimestamp = 0,
214 .platformPosDiff = 0,
215 .platformOriDiff = 0,
216 .jointPosDiff = std::vector<float>(initialConfigData().jointNames.size(), 0),
217 .targetState = trajectory_->initialPoint(),
218 .currentTcpPose = Eigen::Isometry3f{rtTcpNode_->getGlobalPose()},
219 .currentPlatformPose = Eigen::Isometry3f{robot_->getGlobalPose()},
220 .isControllerActive = false};
221
222 bufferRtToOnPublish_.reinitAllBuffers(initDebugData);
223 }
224
225 ARMARX_INFO << "Init done.";
226 }
227
228 std::string
229 Controller::getClassName(const Ice::Current& iceCurrent) const
230 {
231 return common::ControllerTypeNames.to_name(
233 }
234
235 void
236 Controller::rtRun(const IceUtil::Time& sensorValuesTimestamp,
237 const IceUtil::Time& timeSinceLastIteration)
238 {
240
241 auto& debugData = bufferRtToOnPublish_.getWriteBuffer();
242
243 // const armarx::DateTime timestamp(sensorValuesTimestamp);
244 const std::int64_t timestamp = armarx::rtNow().toMicroSeconds();
245
246 ARMARX_CHECK_NOT_NULL(trajectory_);
247
248 // trajectory replay finished?
249 // if (not trajectory_->isValid(timestamp))
250 // {
251 // std::cerr << "Timestamp is not valid!" << std::endl;
252 // std::cerr << timestamp << std::endl;
253 // std::cerr << armarx::rtNow() << std::endl;
254
255 // std::cerr << armarx::rtNow() << std::endl;
256
257
258 // // platform: set to velocity zero
259 // controlTargets_.platformTarget->velocityX = 0;
260 // controlTargets_.platformTarget->velocityY = 0;
261 // controlTargets_.platformTarget->velocityRotation = 0;
262
263 // // joints: we are in position control mode so we just keep the last target
264
265 // return;
266 // }
267
268 const auto trajPointOpt = trajectory_->at(timestamp);
269
271
272 if (not trajPointOpt.has_value()) // or not trajectory_->timeBounds().isWithin(timestamp))
273 {
274 // ARMARX_WARNING << "Timestamp is not within bounds!";
275
276 // platform: set to velocity zero
277 controlTargets_.platformTarget->velocityX = 0;
278 controlTargets_.platformTarget->velocityY = 0;
279 controlTargets_.platformTarget->velocityRotation = 0;
280
281 // joints: we are in velocity control mode so we set the target to zero
282 for (auto* const jointControlTarget : controlTargets_.jointTargets)
283 {
284 jointControlTarget->velocity = 0;
285 }
286
287 return;
288 }
289
291 const Trajectory::TrajectoryPoint& trajPoint = trajPointOpt.value();
292
293 debugData.localTimestamp = trajPoint.timestampMicroSeconds;
294 debugData.targetState = trajPoint;
295 debugData.currentTcpPose = Eigen::Isometry3f{rtTcpNode_->getGlobalPose()};
296 debugData.currentPlatformPose = Eigen::Isometry3f{robot_->getGlobalPose()};
297 debugData.isControllerActive = isControllerActive();
298
299 // update control devices: platform; See: NJointHolonomicPlatformGlobalPositionController
300 {
301 ARMARX_CHECK_EQUAL(trajPoint.jointValuesPlatform.size(), 3);
302 ARMARX_CHECK_EQUAL(trajPoint.jointVelocitiesPlatform.size(), 3);
303
304 const Eigen::Vector2f global_P_robot_target{trajPoint.jointValuesPlatform.at(0),
305 trajPoint.jointValuesPlatform.at(1)};
306 const double targetOrientationGlobal = trajPoint.jointValuesPlatform.at(2);
307
308 ARMARX_CHECK_NOT_NULL(svGlobalRobotLocalization_);
309 const auto global_T_robot = svGlobalRobotLocalization_->global_T_root;
310 const Eigen::Vector3f rpy = simox::math::mat4f_to_rpy(global_T_robot);
311 const float globalOrientation = rpy.z();
312 const Eigen::Vector2f global_P_robot = global_T_robot.block<2, 1>(0, 3);
313
314 const float measuredOrientation = globalOrientation;
315
316 pidPlatform_.update(
317 timeSinceLastIteration.toSecondsDouble(), global_P_robot, global_P_robot_target);
318 opidPlatform_.update(timeSinceLastIteration.toSecondsDouble(),
319 static_cast<double>(measuredOrientation),
320 targetOrientationGlobal);
321
322 {
323 debugData.platformPosDiff = (global_P_robot_target - global_P_robot).norm();
324 debugData.platformOriDiff =
325 static_cast<float>(targetOrientationGlobal) - measuredOrientation;
326 }
327
328
330 {
331 // The given velocity describes the velocity in the local frame of the robot relative to robot's global pose.
332 // The velocity targets that we must generate however are relative to the robot's platform frame.
333 // This means that we must rotate the given velocity targets to the robot's platform frame.
334
335 const Eigen::Rotation2Df local_R_global(-measuredOrientation);
336 const Eigen::Vector2f& vPosError = local_R_global * pidPlatform_.getControlValue();
337 const Eigen::Vector2f vVelFFRobotFrame =
338 local_R_global * Eigen::Vector2f(trajPoint.jointVelocitiesPlatform.at(0),
339 trajPoint.jointVelocitiesPlatform.at(1));
340
341 const auto& vFF = trajPoint.jointVelocitiesPlatform;
342
343 // The feed forward values are in the local frame of the robot. This means that if the robot is rotated compared to desired orientation,
344 // then the robot will move in the wrong direction.
345
346 // To fix this, we rotate the feed forward values to the global frame of the robot.
347 // const Eigen::Rotation2Df global_R_local_target(-targetOrientationGlobal);
348 // const Eigen::Rotation2Df local_R_local_target =
349 // global_R_local.inverse() * global_R_local_target;
350 // const Eigen::Vector2f vFF_local_target =
351 // local_R_local_target * Eigen::Vector2f(vFF.at(0), vFF.at(1));
352
353 constexpr float ffFactorPlatform = 1.0; // FIXME check without as well
354
355
356 // controlTargets_.platformTarget->velocityX = vFF.at(0) + vPosError.x();
357 // controlTargets_.platformTarget->velocityY = vFF.at(1) + vPosError.y();
358 controlTargets_.platformTarget->velocityX =
359 ffFactorPlatform * vVelFFRobotFrame.x() + vPosError.x();
360 controlTargets_.platformTarget->velocityY =
361 ffFactorPlatform * vVelFFRobotFrame.y() + vPosError.y();
362 // controlTargets_.platformTarget->velocityRotation =
363 // vFF.at(2) + static_cast<float>(opidPlatform_.getControlValue());
364
365 // FIXME remove 0
366
367 controlTargets_.platformTarget->velocityRotation =
368 ffFactorPlatform * vFF.at(2) +
369 static_cast<float>(opidPlatform_.getControlValue());
370 }
371 }
372
373 // update control devices: joints
375 {
376 ARMARX_CHECK_EQUAL(controlTargets_.jointTargets.size(), trajPoint.jointValues.size());
377 ARMARX_CHECK_EQUAL(controlTargets_.jointTargets.size(),
378 trajPoint.jointVelocities.size());
379
380 ARMARX_CHECK_NOT_NULL(pidArm_);
381
382
383 const auto toEigen = [](const std::vector<double>& vec) -> Eigen::VectorXf
384 {
385 Eigen::VectorXf eigenVec(vec.size());
386 for (std::size_t i = 0; i < vec.size(); i++)
387 {
388 eigenVec(i) = static_cast<float>(vec.at(i));
389 }
390 return eigenVec;
391 };
392
393 // update PID controller (internal update)
394 {
395
396 const Eigen::VectorXf jointPositionTargets = toEigen(trajPoint.jointValues);
397
398 // set joint position measured based on sensor values
399 Eigen::VectorXf jointPositionMeasured(jointSensorValues_.size());
400 for (std::size_t i = 0; i < jointSensorValues_.size(); i++)
401 {
402 jointPositionMeasured(i) = jointSensorValues_.at(i)->position;
403 }
404
405 // update debug data structure
406 ARMARX_CHECK_EQUAL(debugData.jointPosDiff.size(), jointSensorValues_.size());
407 for (std::size_t i = 0; i < jointSensorValues_.size(); i++)
408 {
409 debugData.jointPosDiff.at(i) =
410 std::abs(jointPositionTargets(i) - jointPositionMeasured(i));
411 }
412
413 // PID control for position error
414 pidArm_->update(timeSinceLastIteration.toSecondsDouble(),
415 jointPositionMeasured,
416 jointPositionTargets);
417 }
418
419 const Eigen::VectorXf& jointVelocityForPosError = pidArm_->getControlValue();
420
421 for (std::size_t i = 0; i < controlTargets_.jointTargets.size(); i++)
422 {
423 auto* const jointControlTarget = controlTargets_.jointTargets.at(i);
424
425 // FIXME check if within bounds etc
426 // const double jointPosTarget = trajPoint.jointValues.at(i);
427 const double jointVelTarget = trajPoint.jointVelocities.at(i);
428
429
430 // update control target
431 jointControlTarget->velocity =
432 static_cast<float>(jointVelTarget) + jointVelocityForPosError(i);
433
434 if (not jointControlTarget->isValid())
435 {
436 ARMARX_WARNING << "Invalid control target for " << VAROUT(i)
437 << ". Value: " << jointControlTarget->velocity;
438 }
439 }
440 }
441
443 // update control devices: hand
444 {
445 ARMARX_CHECK_EQUAL(controlTargets_.handTargets.size(),
446 trajPoint.handJointValues.size());
447 for (std::size_t i = 0; i < controlTargets_.handTargets.size(); i++)
448 {
449 auto* const handControlTarget = controlTargets_.handTargets.at(i);
450 const double jointPosTarget = trajPoint.handJointValues.at(i);
451 handControlTarget->position = static_cast<float>(jointPosTarget);
452 }
453 }
454
455 bufferRtToOnPublish_.commitWrite();
456
457 // advance
458 // trajIdx_++;
459 }
460
461 void
463 {
464 ARMARX_CHECK_NOT_NULL(trajectory_);
465 // FIXME is this the correct clock?
466 const std::int64_t timestampMicroSeconds = armarx::rtNow().toMicroSeconds();
467
468 trajectory_->setStartTime(timestampMicroSeconds);
469
471 whatever_.empty()); // controller is single-shot. Should be recreated for each run.
472 }
473
474 void
476 const DebugDrawerInterfacePrx& debugDrawer,
477 const DebugObserverInterfacePrx& debugObservers)
478 {
479 StringVariantBaseMap datafields;
480
481 const auto& debugData = bufferRtToOnPublish_.getUpToDateReadBuffer();
482
483 datafields["localTimestamp"] = new Variant(debugData.localTimestamp);
484
485 datafields["platform/dpos"] = new Variant(debugData.platformPosDiff);
486 datafields["platform/dori"] = new Variant(debugData.platformOriDiff);
487
488 ARMARX_CHECK_EQUAL(jointNames_.size(), debugData.jointPosDiff.size());
489 for (const auto& [jointName, diff] :
490 ranges::views::zip(jointNames_, debugData.jointPosDiff))
491 {
492 datafields[jointName + "/dpos"] = new Variant(diff);
493 }
494
495 const float tcpDiff = [&]() -> float
496 {
497 namespace rv = ranges::views;
498
499 // set target joint values
500 std::map<std::string, float> targetJointValues;
501 for (const auto& [jointName, jointValue] :
502 rv::zip(jointNames_, debugData.targetState.jointValues))
503 {
504 targetJointValues.emplace(jointName, jointValue);
505 }
506
507 const Eigen::Isometry3f targetGlobalPose =
508 Eigen::Translation3f{
509 static_cast<float>(debugData.targetState.jointValuesPlatform.at(0)),
510 static_cast<float>(debugData.targetState.jointValuesPlatform.at(1)),
511 0} *
512 Eigen::AngleAxisf{
513 static_cast<float>(debugData.targetState.jointValuesPlatform.at(2)),
514 Eigen::Vector3f::UnitZ()};
515
516 debugRobot_->setJointValues(targetJointValues);
517 debugRobot_->setGlobalPose(targetGlobalPose.matrix());
518
519 const Eigen::Isometry3f targetTcpPose(publishTcpNode_->getGlobalPose());
520
521 const Eigen::Isometry3f tcpDiffTf = debugData.currentTcpPose.inverse() * targetTcpPose;
522
523 auto batchPrx = debugDrawer->ice_batchOneway();
524
525 // visu tcp poses
526 {
527
528 batchPrx->setSphereDebugLayerVisu(
529 "tcp_target",
530 new armarx::Vector3(Eigen::Vector3f{targetTcpPose.translation()}),
531 ::armarx::DrawColor{1, 0, 0, 0},
532 10);
533
534 batchPrx->setSphereDebugLayerVisu(
535 "tcp_current",
536 new armarx::Vector3(Eigen::Vector3f{debugData.currentTcpPose.translation()}),
537 ::armarx::DrawColor{0, 1, 0, 0},
538 10);
539
540 batchPrx->setPoseDebugLayerVisu("tcp_target_pose", toIce(targetTcpPose.matrix()));
541 batchPrx->setPoseDebugLayerVisu("tcp_current_pose",
542 toIce(debugData.currentTcpPose.matrix()));
543 }
544
545 // visu platform poses
546 {
547 batchPrx->setSphereDebugLayerVisu(
548 "platform_target",
549 new armarx::Vector3(Eigen::Vector3f{targetGlobalPose.translation()}),
550 ::armarx::DrawColor{1, 0, 0, 0},
551 10);
552
553 batchPrx->setSphereDebugLayerVisu("platform_current",
554 new armarx::Vector3(Eigen::Vector3f{
555 debugData.currentPlatformPose.translation()}),
556 ::armarx::DrawColor{0, 1, 0, 0},
557 10);
558
559 batchPrx->setPoseDebugLayerVisu("platform_target_pose",
560 toIce(targetGlobalPose.matrix()));
561
562 batchPrx->setPoseDebugLayerVisu("platform_current_pose",
563 toIce(debugData.currentPlatformPose.matrix()));
564 }
565
566 batchPrx->ice_flushBatchRequests();
567
568 // TODO if we are interested in the orientation diff, implement it here
569
570 return tcpDiffTf.translation().norm();
571 }();
572
573 datafields["tcpDiff"] = new Variant(tcpDiff);
574
575 debugObservers->setDebugChannel(common::ControllerTypeNames.to_name(
577 datafields);
578
579 // log data
580 if (whateverFlag_.load())
581 {
582 whatever_.push_back(debugData);
583 }
584 }
585
586 namespace arondto
587 {
588 void
589 to_json(nlohmann::json& j, const TrajectoryPoint& trajectoryPoint)
590 {
591 j["timestampMicroSeconds"] = trajectoryPoint.timestampMicroSeconds;
592 j["jointValues"] = trajectoryPoint.jointValues;
593 j["jointValuesPlatform"] = trajectoryPoint.jointValuesPlatform;
594 j["handJointValues"] = trajectoryPoint.handJointValues;
595 j["jointVelocities"] = trajectoryPoint.jointVelocities;
596 j["jointVelocitiesPlatform"] = trajectoryPoint.jointVelocitiesPlatform;
597 }
598 } // namespace arondto
599
600 void
601 to_json(nlohmann::json& j, const DebugData& debugData)
602 {
603 j["localTimestamp"] = debugData.localTimestamp;
604 j["platformPosDiff"] = debugData.platformPosDiff;
605 j["platformOriDiff"] = debugData.platformOriDiff;
606 j["jointPosDiff"] = debugData.jointPosDiff;
607 j["targetState"] = debugData.targetState;
608 j["currentTcpPose"] = Eigen::Matrix4f{debugData.currentTcpPose.matrix()};
609 j["currentPlatformPose"] = Eigen::Matrix4f{debugData.currentPlatformPose.matrix()};
610 j["isControllerActive"] = debugData.isControllerActive;
611 }
612
613 void
615 {
616 ARMARX_IMPORTANT << "Disconnecting controller " << getClassName() << "...";
617 whateverFlag_.store(false);
618
619 nlohmann::json j;
620 j["data"] = whatever_;
621
622 const std::string filename = armarx::Clock::Now().toDateTimeString() + ".json";
623
624 const armarx::PackagePath packagePath{"grasping_on_the_move",
625 "controller_execution/" + filename};
626
627 ARMARX_INFO << "Writing debug data to " << packagePath.toSystemPath();
628
629 std::ofstream ofs(packagePath.toSystemPath());
630 ofs << std::setw(4) << j << std::endl;
631 ofs.close();
632 }
633} // namespace armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller
std::string timestamp()
#define ARMARX_CHECK_NOT_EMPTY(c)
#define VAROUT(x)
static DateTime Now()
Current time on the virtual clock.
Definition Clock.cpp:93
Brief description of class ControlTargetHolonomicPlatformVelocity.
bool isControllerActive(const Ice::Current &=Ice::emptyCurrent) const final override
const SensorValueBase * useSensorValue(const std::string &sensorDeviceName) const
Get a const ptr to the given SensorDevice's SensorValue.
const VirtualRobot::RobotPtr & useSynchronizedRtRobot(bool updateCollisionModel=false)
Requests a VirtualRobot for use in rtRun *.
ControlTargetBase * useControlTarget(const std::string &deviceName, const std::string &controlMode)
Declares to calculate the ControlTarget for the given ControlDevice in the given ControlMode when rtR...
The SensorValueBase class.
const T * asA() const
The Variant class is described here: Variants.
Definition Variant.h:224
The Vector3 class.
Definition Pose.h:113
void onPublish(const SensorAndControl &, const DebugDrawerInterfacePrx &, const DebugObserverInterfacePrx &) override
Controller(const RobotUnitPtr &robotUnit, const NJointControllerConfigPtr &config, const VirtualRobot::RobotPtr &robot)
void rtRun(const IceUtil::Time &sensorValuesTimestamp, const IceUtil::Time &timeSinceLastIteration) override
TODO make protected and use attorneys.
std::string getClassName(const Ice::Current &iceCurrent=Ice::emptyCurrent) const override
void rtPreActivateController() override
This function is called before the controller is activated.
armarx::control::njoint_controller::joint_space:: whole_body_trajectory_controller::arondto::TrajectoryPoint TrajectoryPoint
std::string toDateTimeString() const
Definition DateTime.cpp:75
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:190
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
std::shared_ptr< class Robot > RobotPtr
Definition Bus.h:19
const simox::meta::EnumNames< ControllerType > ControllerTypeNames
Definition type.h:170
const NJointControllerRegistration< Controller > Registration(common::ControllerTypeNames.to_name(common::ControllerType::WholeBodyTrajectoryController))
::IceInternal::ProxyHandle<::IceProxy::armarx::DebugObserverInterface > DebugObserverInterfacePrx
std::map< std::string, VariantBasePtr > StringVariantBaseMap
IceUtil::Time rtNow()
Definition RtTiming.h:40
IceUtil::Handle< class RobotUnit > RobotUnitPtr
Definition FTSensor.h:34
::IceInternal::ProxyHandle<::IceProxy::armarx::DebugDrawerInterface > DebugDrawerInterfacePrx
void toIce(std::map< IceKeyT, IceValueT > &iceMap, const boost::container::flat_map< CppKeyT, CppValueT > &cppMap)
detail::ControlThreadOutputBufferEntry SensorAndControl
Eigen::Vector3f toEigen(const pcl::PointXYZ &pt)
double norm(const Point &a)
Definition point.hpp:102
#define ARMARX_TRACE
Definition trace.h:77