PlatformGlobalTrajectoryController.cpp
Go to the documentation of this file.
2 
3 #include <string>
4 
5 #include <Ice/Current.h>
6 #include <IceUtil/Time.h>
7 
8 #include <VirtualRobot/VirtualRobot.h>
9 
14 #include <ArmarXCore/interface/core/ManagedIceObjectDefinitions.h>
15 #include <ArmarXCore/interface/observers/ObserverInterface.h>
16 #include <ArmarXCore/interface/observers/VariantBase.h>
19 
25 #include <RobotAPI/interface/units/RobotUnit/NJointController.h>
26 #include <RobotAPI/interface/visualization/DebugDrawerInterface.h>
27 
28 #include <armarx/control/interface/ConfigurableNJointControllerInterface.h> // IWYU pragma: keep
30 #include <armarx/navigation/platform_controller/aron/PlatformGlobalTrajectoryControllerConfig.aron.generated.h>
33 
35 {
36  const NJointControllerRegistration<Controller> Registration(
38 
40  const NJointControllerConfigPtr& config,
42  {
43  ARMARX_IMPORTANT << "Creating "
44  << common::ControllerTypeNames.to_name(
46  // config
47  ConfigPtrT cfg = ConfigPtrT::dynamicCast(config);
49  // ARMARX_CHECK_EXPRESSION(!cfg->nodeSetName.empty());
50 
51  ARMARX_CHECK_EXPRESSION(robotUnit);
52 
53  const auto robot = useSynchronizedRtRobot();
54 
55  // Control target
56  {
57  const std::string controlTargetName = robotUnit->getRobotPlatformName();
58 
59  ARMARX_INFO << "Using control target " << controlTargetName;
60  auto* ct = useControlTarget(controlTargetName, ControlModes::HolonomicPlatformVelocity);
61  ARMARX_CHECK_NOT_NULL(ct) << "Cannot use control target `" << controlTargetName << "`";
62 
63  platformTarget = ct->asA<ControlTargetHolonomicPlatformVelocity>();
64 
65  ARMARX_CHECK_EXPRESSION(platformTarget)
66  << "The actuator " << controlTargetName << " has no control mode "
67  << ControlModes::HolonomicPlatformVelocity;
68  }
69 
70 
71  const auto configData = ::armarx::fromAron<arondto::Config, Config>(cfg->config);
72  const auto trajectoryFollowingControllerParams = configData.params;
73 
75  configBuffer_updateConfigToAdditionalTask.reinitAllBuffers(configData);
76  configBuffer_updateConfigToOnPublish.reinitAllBuffers(configData);
77 
78  trajectoryFollowingController.emplace(trajectoryFollowingControllerParams);
79 
80  ARMARX_INFO << "Init done.";
81  }
82 
83  std::string
84  Controller::getClassName(const Ice::Current& iceCurrent) const
85  {
88  }
89 
90  void
91  Controller::rtRun(const IceUtil::Time& sensorValuesTimestamp,
92  const IceUtil::Time& timeSinceLastIteration)
93  {
95 
96  // update control devices
97  platformTarget->velocityX = rtGetControlStruct().linear.x();
98  platformTarget->velocityY = rtGetControlStruct().linear.y();
99  platformTarget->velocityRotation = rtGetControlStruct().angular;
100 
101  // read data (for non-rt)
102  robotStateBuffer_rtToAdditionalTask.getWriteBuffer().global_T_robot.matrix() =
103  rtGetRobot()->getGlobalPose();
104  robotStateBuffer_rtToAdditionalTask.commitWrite();
105  }
106 
107  void
109  const Ice::Current& iceCurrent)
110  {
111  // TODO maybe update pid controller
112 
113  const auto updateConfig = ::armarx::fromAron<arondto::Config, Config>(dto);
114 
115  configBuffer_updateConfigToAdditionalTask.getWriteBuffer() = updateConfig;
116  configBuffer_updateConfigToAdditionalTask.commitWrite();
117 
118  configBuffer_updateConfigToOnPublish.getWriteBuffer() = updateConfig;
119  configBuffer_updateConfigToOnPublish.commitWrite();
120 
121  ARMARX_VERBOSE << "Trajectory with " << updateConfig.targets.trajectory.points().size();
122  }
123 
124  void
126  {
127  ARMARX_TRACE;
128  ARMARX_CHECK(trajectoryFollowingController.has_value());
129 
130  const auto& configBuffer =
131  configBuffer_updateConfigToAdditionalTask.getUpToDateReadBuffer();
132 
133 
134  // if trajectory is empty, set velocity to 0
135  if (configBuffer.targets.trajectory.points().empty())
136  {
137  ARMARX_INFO << deactivateSpam(1) << "Trajectory is empty!";
138 
139  filteredTwist.reset();
140 
141  getWriterControlStruct().reset();
143  return;
144  }
145 
146  // update controller
147  ARMARX_TRACE;
148 
149  // make sure twist limits are up to date (they are changed on the fly by e.g. the safety guard)
150  trajectoryFollowingController->updateTwistLimits(configBuffer.params.limits);
151 
152  // make sure the velocity factor (scaling the twist) is up to date
153  // (it can be changed on the fly by, e.g., a skill using the navigator)
154  trajectoryFollowingController->updateVelocityFactor(configBuffer.params.velocityFactor);
155 
156  // run the controller, resulting in the required twist and other values
158  trajectoryFollowingController->control(
159  configBuffer.targets.trajectory,
160  robotStateBuffer_rtToAdditionalTask.getUpToDateReadBuffer().global_T_robot);
161 
162  // low-pass filter the twist
163  {
164  const float alpha = configBuffer.params.alpha;
165  filteredTwist.linear =
166  alpha * filteredTwist.linear + (1. - alpha) * result.twist.linear.head<2>();
167  filteredTwist.angular =
168  alpha * filteredTwist.angular + (1. - alpha) * result.twist.angular.z();
169  }
170 
171  // store result
172  getWriterControlStruct() = filteredTwist;
173  ARMARX_TRACE;
175 
176  // store results (onPublish)
177  targetBuffer_additionalTaskToOnPublish.getWriteBuffer().target = filteredTwist;
178  targetBuffer_additionalTaskToOnPublish.getWriteBuffer().dropPointVelocity =
179  result.dropPoint.velocity;
180  targetBuffer_additionalTaskToOnPublish.getWriteBuffer().currentOrientation =
181  result.currentOrientation;
182  targetBuffer_additionalTaskToOnPublish.getWriteBuffer().desiredOrientation =
183  result.desiredOrientation;
184  targetBuffer_additionalTaskToOnPublish.getWriteBuffer().orientationError =
185  result.orientationError;
186  targetBuffer_additionalTaskToOnPublish.getWriteBuffer().positionError =
187  result.positionError;
188  targetBuffer_additionalTaskToOnPublish.getWriteBuffer().isFinalSegment =
189  result.isFinalSegment;
190  targetBuffer_additionalTaskToOnPublish.commitWrite();
191  }
192 
193  void
195  const DebugDrawerInterfacePrx& /*debugDrawer*/,
196  const DebugObserverInterfacePrx& debugObservers)
197  {
198  StringVariantBaseMap datafields;
199 
200  const auto& debugStuff = targetBuffer_additionalTaskToOnPublish.getUpToDateReadBuffer();
201  const auto& config = configBuffer_updateConfigToOnPublish.getUpToDateReadBuffer();
202 
203 
204  datafields["vx"] = new Variant(debugStuff.target.linear.x());
205  datafields["vy"] = new Variant(debugStuff.target.linear.y());
206  datafields["v_linear"] = new Variant(debugStuff.target.linear.norm());
207  datafields["vyaw"] = new Variant(debugStuff.target.angular);
208  datafields["trajectory_points"] = new Variant(config.targets.trajectory.points().size());
209 
210  datafields["drop_point_velocity"] = new Variant(debugStuff.dropPointVelocity);
211 
212  datafields["orientationError"] = new Variant(debugStuff.orientationError);
213  datafields["desiredOrientation"] = new Variant(debugStuff.desiredOrientation);
214  datafields["currentOrientation"] = new Variant(debugStuff.currentOrientation);
215  datafields["isFinalSegment"] = new Variant(debugStuff.isFinalSegment);
216 
217  datafields["positionError"] = new Variant(debugStuff.positionError);
218 
219  datafields["limitLinear"] = new Variant(config.params.limits.linear);
220  datafields["limitAngular"] = new Variant(config.params.limits.angular);
221 
222  debugObservers->setDebugChannel(
224  datafields);
225  }
226 
227  void
229  {
230  ARMARX_TRACE;
231  ARMARX_INFO << "PlatformGlobalTrajectoryController::onInitNJointController";
232 
233  runTask(
234  "PlatformGlobalTrajectoryControllerAdditionalTask",
235  [&]
236  {
237  CycleUtil c(10);
238  getObjectScheduler()->waitForObjectStateMinimum(eManagedIceObjectStarted);
240  << "Create a new thread alone PlatformGlobalTrajectoryController controller";
241  while (getState() == eManagedIceObjectStarted)
242  {
243  if (isControllerActive() and rtReady.load())
244  {
245  ARMARX_VERBOSE << "additional task";
246  additionalTask();
247  }
248  c.waitForCycleDuration();
249  }
250  });
251 
252  ARMARX_INFO << "PlatformGlobalTrajectoryController::onInitNJointController done.";
253  }
254 
255  void
257  {
258  // additionalTask() is not executed. Thus, we can access lastTwist without mutex.
259  filteredTwist.reset();
260 
261  robotStateBuffer_rtToAdditionalTask.getWriteBuffer().global_T_robot.matrix() =
262  rtGetRobot()->getGlobalPose();
263  robotStateBuffer_rtToAdditionalTask.commitWrite();
264 
265  rtReady.store(true);
266  }
267 
268  void
270  {
271  rtReady.store(false);
272  }
273 
274  Controller::~Controller() = default;
275 
277  Controller::getConfig(const ::Ice::Current&)
278  {
279  ARMARX_ERROR << "NYI";
280  return nullptr;
281  }
282 } // namespace armarx::navigation::platform_controller::platform_global_trajectory
armarx::NJointControllerWithTripleBuffer< Target >::reinitTripleBuffer
void reinitTripleBuffer(const Target &initial)
Definition: NJointControllerWithTripleBuffer.h:68
armarx::ControlTargetHolonomicPlatformVelocity
Brief description of class ControlTargetHolonomicPlatformVelocity.
Definition: ControlTargetHolonomicPlatformVelocity.h:38
armarx::ControlTargetBase::asA
const T * asA() const
Definition: ControlTargetBase.h:76
armarx::Variant
The Variant class is described here: Variants.
Definition: Variant.h:223
armarx::navigation::traj_ctrl::global::TrajectoryControllerResult::currentOrientation
float currentOrientation
Definition: TrajectoryController.h:45
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:187
armarx::navigation::traj_ctrl::global::TrajectoryControllerResult
Definition: TrajectoryController.h:40
armarx::navigation::platform_controller::platform_global_trajectory::Twist2D::reset
void reset()
Definition: PlatformGlobalTrajectoryController.h:75
armarx::TripleBuffer::getWriteBuffer
T & getWriteBuffer()
Definition: TripleBuffer.h:92
armarx::NJointControllerBase::useSynchronizedRtRobot
const VirtualRobot::RobotPtr & useSynchronizedRtRobot(bool updateCollisionModel=false)
Requests a VirtualRobot for use in rtRun *.
Definition: NJointController.cpp:293
armarx::NJointControllerWithTripleBuffer< Target >::rtGetControlStruct
const Target & rtGetControlStruct() const
Definition: NJointControllerWithTripleBuffer.h:32
armarx::StringVariantBaseMap
std::map< std::string, VariantBasePtr > StringVariantBaseMap
Definition: ManagedIceObject.h:110
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:190
NJointControllerBase.h
controller_types.h
armarx::navigation::traj_ctrl::global::TrajectoryControllerResult::desiredOrientation
float desiredOrientation
Definition: TrajectoryController.h:46
RobotUnit.h
armarx::TripleBuffer::commitWrite
void commitWrite()
Definition: TripleBuffer.h:163
armarx::NJointControllerBase::useControlTarget
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...
Definition: NJointController.cpp:410
armarx::navigation::core::GlobalTrajectoryPoint::velocity
float velocity
Definition: Trajectory.h:40
ARMARX_CHECK_NOT_NULL
#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...
Definition: ExpressionException.h:206
trace.h
armarx::CycleUtil
This util class helps with keeping a cycle time during a control cycle.
Definition: CycleUtil.h:40
armarx::ManagedIceObject::getState
int getState() const
Retrieve current state of the ManagedIceObject.
Definition: ManagedIceObject.cpp:769
armarx::navigation::common::ControllerType::PlatformGlobalTrajectory
@ PlatformGlobalTrajectory
armarx::navigation::platform_controller::platform_global_trajectory::Controller::updateConfig
void updateConfig(const ::armarx::aron::data::dto::DictPtr &dto, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
Definition: PlatformGlobalTrajectoryController.cpp:108
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:46
armarx::NJointControllerBase::ConfigPtrT
NJointControllerConfigPtr ConfigPtrT
Definition: NJointControllerBase.h:587
armarx::navigation::platform_controller::platform_global_trajectory::Controller::onInitNJointController
void onInitNJointController() override
Definition: PlatformGlobalTrajectoryController.cpp:228
armarx::navigation::traj_ctrl::global::TrajectoryControllerResult::dropPoint
core::GlobalTrajectoryPoint dropPoint
Definition: TrajectoryController.h:43
armarx::NJointControllerWithTripleBuffer< Target >::getWriterControlStruct
Target & getWriterControlStruct()
Definition: NJointControllerWithTripleBuffer.h:54
armarx::ControlTargetHolonomicPlatformVelocity::velocityRotation
float velocityRotation
Definition: ControlTargetHolonomicPlatformVelocity.h:43
ARMARX_CHECK
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
Definition: ExpressionException.h:82
armarx::navigation::platform_controller::platform_global_trajectory::Controller::additionalTask
void additionalTask()
Definition: PlatformGlobalTrajectoryController.cpp:125
IceInternal::Handle
Definition: forward_declarations.h:8
TrajectoryController.h
armarx::NJointControllerBase::rtGetRobot
const VirtualRobot::RobotPtr & rtGetRobot()
TODO make protected and use attorneys.
Definition: NJointControllerBase.h:846
armarx::navigation::traj_ctrl::global::TrajectoryControllerResult::isFinalSegment
bool isFinalSegment
Definition: TrajectoryController.h:44
armarx::detail::ControlThreadOutputBufferEntry
Definition: ControlThreadOutputBuffer.h:182
ARMARX_TRACE
#define ARMARX_TRACE
Definition: trace.h:77
armarx::navigation::platform_controller::platform_global_trajectory::Controller::Controller
Controller(const RobotUnitPtr &robotUnit, const NJointControllerConfigPtr &config, const VirtualRobot::RobotPtr &)
Definition: PlatformGlobalTrajectoryController.cpp:39
armarx::navigation::traj_ctrl::global::TrajectoryControllerResult::orientationError
float orientationError
Definition: TrajectoryController.h:47
armarx::navigation::platform_controller::platform_global_trajectory::Controller::getConfig
::armarx::aron::data::dto::DictPtr getConfig(const ::Ice::Current &=::Ice::emptyCurrent) override
Definition: PlatformGlobalTrajectoryController.cpp:277
armarx::navigation::platform_controller::platform_global_trajectory::Controller::getClassName
std::string getClassName(const Ice::Current &iceCurrent=Ice::emptyCurrent) const override
Definition: PlatformGlobalTrajectoryController.cpp:84
armarx::NJointControllerBase::isControllerActive
bool isControllerActive(const Ice::Current &=Ice::emptyCurrent) const final override
Definition: NJointControllerBase.h:778
armarx::navigation::platform_controller::platform_global_trajectory::Controller::rtPostDeactivateController
void rtPostDeactivateController() override
This function is called after the controller is deactivated.
Definition: PlatformGlobalTrajectoryController.cpp:269
armarx::NJointControllerBase::runTask
void runTask(const std::string &taskName, Task &&task)
Executes a given task in a separate thread from the Application ThreadPool.
Definition: NJointControllerBase.h:754
armarx::navigation::platform_controller::platform_global_trajectory::Twist2D::angular
float angular
Definition: PlatformGlobalTrajectoryController.h:72
ControlModes.h
armarx::NJointControllerWithTripleBuffer< Target >::rtUpdateControlStruct
bool rtUpdateControlStruct()
Definition: NJointControllerWithTripleBuffer.h:38
armarx::navigation::platform_controller::platform_global_trajectory::Registration
const NJointControllerRegistration< Controller > Registration(common::ControllerTypeNames.to_name(common::ControllerType::PlatformGlobalTrajectory))
aron_conversions.h
armarx::NJointControllerWithTripleBuffer< Target >::writeControlStruct
void writeControlStruct()
Definition: NJointControllerWithTripleBuffer.h:44
ArmarXObjectScheduler.h
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:196
armarx::ControlTargetHolonomicPlatformVelocity::velocityX
float velocityX
Definition: ControlTargetHolonomicPlatformVelocity.h:41
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
armarx::ControlTargetHolonomicPlatformVelocity::velocityY
float velocityY
Definition: ControlTargetHolonomicPlatformVelocity.h:42
CycleUtil.h
ExpressionException.h
armarx::navigation::core::Twist::linear
LinearVelocity linear
Definition: basic_types.h:55
armarx::aron::data::DictPtr
std::shared_ptr< Dict > DictPtr
Definition: Dict.h:41
ControlTargetHolonomicPlatformVelocity.h
ARMARX_CHECK_EXPRESSION
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
Definition: ExpressionException.h:73
PlatformGlobalTrajectoryController.h
armarx::navigation::common::ControllerTypeNames
const simox::meta::EnumNames< ControllerType > ControllerTypeNames
Definition: controller_types.h:17
armarx::navigation::platform_controller::platform_global_trajectory::Controller::rtRun
void rtRun(const IceUtil::Time &sensorValuesTimestamp, const IceUtil::Time &timeSinceLastIteration) override
TODO make protected and use attorneys.
Definition: PlatformGlobalTrajectoryController.cpp:91
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
armarx::navigation::platform_controller::platform_global_trajectory::Controller::rtPreActivateController
void rtPreActivateController() override
This function is called before the controller is activated.
Definition: PlatformGlobalTrajectoryController.cpp:256
IceUtil::Handle< class RobotUnit >
IceInternal::ProxyHandle<::IceProxy::armarx::DebugDrawerInterface >
armarx::navigation::core::Twist::angular
AngularVelocity angular
Definition: basic_types.h:56
armarx::navigation::traj_ctrl::global::TrajectoryControllerResult::twist
core::Twist twist
Definition: TrajectoryController.h:42
armarx::navigation::platform_controller::platform_global_trajectory::Twist2D::linear
Eigen::Vector2f linear
Definition: PlatformGlobalTrajectoryController.h:71
armarx::Logging::deactivateSpam
SpamFilterDataPtr deactivateSpam(float deactivationDurationSec=10.0f, const std::string &identifier="", bool deactivate=true) const
disables the logging for the current line for the given amount of seconds.
Definition: Logging.cpp:99
armarx::navigation::traj_ctrl::global::TrajectoryControllerResult::positionError
float positionError
Definition: TrajectoryController.h:48
Logging.h
armarx::navigation::platform_controller::platform_global_trajectory::Controller::~Controller
~Controller() override
armarx::TripleBuffer::getUpToDateReadBuffer
const T & getUpToDateReadBuffer() const
Definition: TripleBuffer.h:116
armarx::navigation::platform_controller::platform_global_trajectory
Definition: aron_conversions.cpp:35
Variant.h
armarx::TripleBuffer::reinitAllBuffers
std::enable_if< std::is_copy_constructible< U >::value >::type reinitAllBuffers(const T &init)
Definition: TripleBuffer.h:171
NJointControllerRegistry.h
armarx::ManagedIceObject::getObjectScheduler
ArmarXObjectSchedulerPtr getObjectScheduler() const
Definition: ManagedIceObject.cpp:776
armarx::navigation::platform_controller::platform_global_trajectory::Controller::onPublish
void onPublish(const SensorAndControl &sac, const DebugDrawerInterfacePrx &debugDrawer, const DebugObserverInterfacePrx &debugObservers) override
Definition: PlatformGlobalTrajectoryController.cpp:194
VirtualRobot::RobotPtr
std::shared_ptr< class Robot > RobotPtr
Definition: Bus.h:19