NJointTrajectoryController.cpp
Go to the documentation of this file.
2 
3 #include <VirtualRobot/TimeOptimalTrajectory/TimeOptimalTrajectory.h>
4 
6 #include <ArmarXCore/interface/observers/ObserverInterface.h>
7 
11 
12 namespace armarx
13 {
14  NJointControllerRegistration<NJointTrajectoryController>
15  registrationControllerNJointTrajectoryController("NJointTrajectoryController");
16 
18  const NJointControllerConfigPtr& config,
19  const VirtualRobot::RobotPtr& robot)
20  {
21  cfg = NJointTrajectoryControllerConfigPtr::dynamicCast(config);
22  ARMARX_CHECK_EXPRESSION(cfg) << "Needed type: NJointTrajectoryControllerConfigPtr";
23 
24  for (std::string jointName : cfg->jointNames)
25  {
26  ControlTargetBase* ct = useControlTarget(jointName, ControlModes::Velocity1DoF);
27  const SensorValueBase* sv = useSensorValue(jointName);
28  targets.push_back(ct->asA<ControlTarget1DoFActuatorVelocity>());
29  sensors.push_back(sv->asA<SensorValue1DoFActuatorPosition>());
30  }
31  if (cfg->jointNames.size() == 0)
32  {
33  ARMARX_ERROR << "cfg->jointNames.size() == 0";
34  }
35  for (auto& jointName : cfg->jointNames)
36  {
37  LimitlessState ls;
38  ls.enabled = false;
39  VirtualRobot::RobotNodePtr rn = robot->getRobotNode(jointName);
40  if (rn)
41  {
42  ls.enabled = rn->isLimitless();
43  ls.limitLo = rn->getJointLimitLo();
44  ls.limitHi = rn->getJointLimitHi();
45  }
46  ARMARX_DEBUG << "limitless status - " << jointName << ": " << rn->isLimitless();
47  limitlessStates.push_back(ls);
48  }
49  }
50 
52  {
53  }
54 
55  std::string
56  NJointTrajectoryController::getClassName(const Ice::Current&) const
57  {
58  return "NJointTrajectoryController";
59  }
60 
61  void
63  {
64  offeringTopic("StaticPlotter");
65  }
66 
67  void
69  {
70  plotter = getTopic<StaticPlotterInterfacePrx>("StaticPlotter");
71  dbgObs = getTopic<DebugObserverInterfacePrx>("DebugObserver");
72  }
73 
74  void
75  NJointTrajectoryController::rtRun(const IceUtil::Time& sensorValuesTimestamp,
76  const IceUtil::Time& timeSinceLastIteration)
77  {
78  if (rtGetControlStruct().trajectoryCtrl)
79  {
81  ARMARX_CHECK_EQUAL(sensors.size(), targets.size());
82  const auto& dimNames = contr.getTraj()->getDimensionNames();
83  for (size_t i = 0; i < sensors.size(); i++)
84  // for(auto& s : sensors)
85  {
86  ARMARX_CHECK_EQUAL(dimNames.at(i), cfg->jointNames.at(i));
87  currentPos(i) = sensors.at(i)->position;
88  }
89 
90  auto& newVelocities =
91  contr.update(timeSinceLastIteration.toSecondsDouble() * direction, currentPos);
92  // StringVariantBaseMap positions;
93  // ARMARX_RT_LOGF_INFO("Current error %.3f", contr.getCurrentError()(1)).deactivateSpam(0.1);
94 
95  // for (int i = 0; i < contr.getCurrentError().rows(); ++i)
96  // {
97  // positions[dimNames.at(i) + "-targetPosition"] = new Variant(contr.getPositions()(i));
98  // positions[dimNames.at(i) + "-currentPosition"] = new Variant(currentPos(i));
99  // }
100  // dbgObs->setDebugChannel("positions", positions);
101  currentTimestamp = contr.getCurrentTimestamp();
102  finished =
103  (currentTimestamp >= contr.getTraj()->rbegin()->getTimestamp() &&
104  direction == 1.0) ||
105  (currentTimestamp <= contr.getTraj()->begin()->getTimestamp() && direction == -1.0);
106 
107  for (size_t i = 0; i < targets.size(); ++i)
108  {
109  {
110  targets.at(i)->velocity =
111  (cfg->isPreview || finished) ? 0.0f : newVelocities(i);
112  }
113  }
114 
115  if (finished && looping)
116  {
117  direction *= -1.0;
118  }
119  }
120  }
121 
122  void
123  NJointTrajectoryController::setTrajectory(const TrajectoryBasePtr& t, const Ice::Current&)
124  {
125  TIMING_START(TrajectoryOptimization);
127  TrajectoryPtr trajectory = TrajectoryPtr::dynamicCast(t);
128  ARMARX_CHECK_EXPRESSION(trajectory);
129  size_t trajectoryDimensions = trajectory->dim();
130  ARMARX_CHECK_EQUAL(trajectoryDimensions, targets.size());
131  trajectory->setLimitless(limitlessStates);
132  // trajectory->gaussianFilter(0.3);
133  if (cfg->considerConstraints)
134  {
135  std::list<Eigen::VectorXd> pathPoints;
136  double timeStep = cfg->preSamplingStepMs / 1000.0;
137  Eigen::VectorXd maxVelocities =
138  Eigen::VectorXd::Constant(trajectoryDimensions, cfg->maxVelocity);
139  Eigen::VectorXd maxAccelerations =
140  Eigen::VectorXd::Constant(trajectoryDimensions, cfg->maxAcceleration);
142  for (const Trajectory::TrajData& element : *trajectory)
143  {
144  Eigen::VectorXd waypoint(trajectoryDimensions);
145  for (size_t i = 0; i < trajectoryDimensions; ++i)
146  {
147  waypoint(i) = element.getPosition(i);
148  }
149  pathPoints.emplace_back(waypoint);
150  }
151 
152  VirtualRobot::Path p(pathPoints, cfg->maxDeviation);
153  VirtualRobot::TimeOptimalTrajectory timeOptimalTraj(
154  p, maxVelocities, maxAccelerations, timeStep);
155 
156  TrajectoryPtr newTraj = new Trajectory();
157 
158  Ice::DoubleSeq newTimestamps;
159  double duration = timeOptimalTraj.getDuration();
160  for (double t = 0.0; t < duration; t += timeStep)
161  {
162  newTimestamps.push_back(t);
163  }
164  newTimestamps.push_back(duration);
165 
166  for (size_t d = 0; d < trajectoryDimensions; d++)
167  {
168  // Ice::DoubleSeq position;
169  // for (double t = 0.0; t < duration; t += timeStep)
170  // {
171  // position.push_back(timeOptimalTraj.getPosition(t)[d]);
172  // }
173  // position.push_back(timeOptimalTraj.getPosition(duration)[d]);
174  // newTraj->addDimension(position, newTimestamps, trajectory->getDimensionName(d));
175 
176  Ice::DoubleSeq derivs;
177  for (double t = 0.0; t < duration; t += timeStep)
178  {
179  derivs.clear();
180  derivs.push_back(timeOptimalTraj.getPosition(t)[d]);
181  derivs.push_back(timeOptimalTraj.getVelocity(t)[d]);
182  newTraj->addDerivationsToDimension(d, t, derivs);
183  }
184  derivs.clear();
185  derivs.push_back(timeOptimalTraj.getPosition(duration)[d]);
186  derivs.push_back(timeOptimalTraj.getVelocity(duration)[d]);
187  newTraj->addDerivationsToDimension(d, duration, derivs);
188  }
189  newTraj->setDimensionNames(trajectory->getDimensionNames());
190  newTraj->setLimitless(limitlessStates);
192  TIMING_END(TrajectoryOptimization);
193  ARMARX_INFO << "Trajectory duration: " << newTraj->getTimeLength();
194  ARMARX_INFO << VAROUT(newTraj->output());
195  trajectory = newTraj;
196  }
197 
198  trajEndTime = *trajectory->getTimestamps().rbegin() - *trajectory->getTimestamps().begin();
199  currentPos.resize(trajectory->getDimensionNames().size());
200 
201  startTimestamp = *trajectory->getTimestamps().begin();
202  endTimestamp = *trajectory->getTimestamps().rbegin();
203  if (plotter)
204  {
205  StringFloatSeqDict posData;
206  StringFloatSeqDict velData;
207  for (size_t d = 0; d < trajectory->dim(); ++d)
208  {
209  auto positions = trajectory->getDimensionData(d, 0);
210  posData[trajectory->getDimensionName(d)] =
211  Ice::FloatSeq(positions.begin(), positions.end());
212  auto velocities = trajectory->getDimensionData(d, 1);
213  velData[trajectory->getDimensionName(d)] =
214  Ice::FloatSeq(velocities.begin(), velocities.end());
215  }
216  auto timestampsDouble = trajectory->getTimestamps();
217  Ice::FloatSeq timestamps(timestampsDouble.begin(), timestampsDouble.end());
218  plotter->addPlotWithTimestampVector("Positions", timestamps, posData);
219  plotter->addPlotWithTimestampVector("Velocities", timestamps, velData);
220  }
221  else
222  {
223  ARMARX_WARNING << "Plotter proxy is NULL";
224  }
225 
226 
228  ARMARX_INFO << VAROUT(cfg->PID_p) << VAROUT(cfg->PID_i) << VAROUT(cfg->PID_d);
229 
230  trajectoryCtrl.reset(
231  new TrajectoryController(trajectory, cfg->PID_p, cfg->PID_i, cfg->PID_d, false));
232  getWriterControlStruct().trajectoryCtrl = trajectoryCtrl;
234  }
235 
236  bool
238  {
239  return finished;
240  }
241 
242  double
244  {
245  return currentTimestamp;
246  }
247 
248  float
250  {
251  return math::MathUtils::ILerp(startTimestamp, endTimestamp, currentTimestamp);
252  }
253 
254  double
256  {
258  if (trajectoryCtrl)
259  {
260  return trajectoryCtrl->getCurrentTimestamp();
261  }
262  else
263  {
264  return 0.0;
265  }
266  }
267 
268  void
270  {
271  this->looping = looping;
272  }
273 
274  double
276  {
277  return trajEndTime;
278  }
279 
282  {
284  if (trajectoryCtrl)
285  {
286  return TrajectoryPtr::dynamicCast(trajectoryCtrl->getTraj()->clone());
287  }
288  else
289  {
290  return new Trajectory();
291  }
292  }
293 
294  void
296  {
297  startTime = IceUtil::Time();
298  }
299 
300  void
302  {
303  for (auto& target : targets)
304  {
305  target->velocity = 0.0f;
306  }
307  }
308 
309 } // namespace armarx
armarx::NJointTrajectoryController::onConnectNJointController
void onConnectNJointController() override
Definition: NJointTrajectoryController.cpp:68
armarx::math::MathUtils::ILerp
static float ILerp(float a, float b, float f)
Definition: MathUtils.h:160
armarx::ControlTargetBase::asA
const T * asA() const
Definition: ControlTargetBase.h:76
RtLogging.h
TIMING_START
#define TIMING_START(name)
Definition: TimeUtil.h:280
armarx::NJointTrajectoryController::getCurrentTimestamp
double getCurrentTimestamp(const Ice::Current &) override
Definition: NJointTrajectoryController.cpp:243
armarx::TrajectoryController
Subcontroller which handles all program interaction with the modle, communicates with other controlle...
Definition: TrajectoryController.h:32
MathUtils.h
armarx::NJointControllerWithTripleBuffer< NJointTrajectoryControllerControlData >::rtGetControlStruct
const NJointTrajectoryControllerControlData & rtGetControlStruct() const
Definition: NJointControllerWithTripleBuffer.h:32
TIMING_END
#define TIMING_END(name)
Definition: TimeUtil.h:296
armarx::SensorValueBase::asA
const T * asA() const
Definition: SensorValueBase.h:82
armarx::SensorValueBase
The SensorValueBase class.
Definition: SensorValueBase.h:40
armarx::ControlTargetBase
Brief description of class JointControlTargetBase.
Definition: ControlTargetBase.h:47
armarx::NJointTrajectoryController::setTrajectory
void setTrajectory(const TrajectoryBasePtr &t, const Ice::Current &) override
Definition: NJointTrajectoryController.cpp:123
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::TrajectoryController::FoldLimitlessJointPositions
static void FoldLimitlessJointPositions(TrajectoryPtr traj)
Definition: TrajectoryController.cpp:161
boost::target
Vertex target(const detail::edge_base< Directed, Vertex > &e, const PCG &)
Definition: point_cloud_graph.h:688
armarx::Trajectory::TrajData
Definition: Trajectory.h:85
armarx::NJointTrajectoryController::onInitNJointController
void onInitNJointController() override
Definition: NJointTrajectoryController.cpp:62
armarx::NJointControllerWithTripleBuffer< NJointTrajectoryControllerControlData >::getWriterControlStruct
NJointTrajectoryControllerControlData & getWriterControlStruct()
Definition: NJointControllerWithTripleBuffer.h:54
armarx::NJointControllerWithTripleBuffer< NJointTrajectoryControllerControlData >::LockGuardType
std::lock_guard< std::recursive_mutex > LockGuardType
Definition: NJointControllerWithTripleBuffer.h:14
armarx::NJointTrajectoryController::isFinished
bool isFinished(const Ice::Current &) override
Definition: NJointTrajectoryController.cpp:237
armarx::TrajectoryController::getCurrentTimestamp
double getCurrentTimestamp() const
Definition: TrajectoryController.cpp:115
IceInternal::Handle< Trajectory >
armarx::NJointTrajectoryController::getTrajectoryCopy
TrajectoryPtr getTrajectoryCopy() const
Definition: NJointTrajectoryController.cpp:281
armarx::NJointTrajectoryController::getCurrentTrajTime
double getCurrentTrajTime() const
Definition: NJointTrajectoryController.cpp:255
armarx::NJointTrajectoryController::getClassName
std::string getClassName(const Ice::Current &) const override
Definition: NJointTrajectoryController.cpp:56
armarx::TrajectoryController::UnfoldLimitlessJointPositions
static void UnfoldLimitlessJointPositions(TrajectoryPtr traj)
Definition: TrajectoryController.cpp:125
armarx::registrationControllerNJointTrajectoryController
NJointControllerRegistration< NJointTrajectoryController > registrationControllerNJointTrajectoryController("NJointTrajectoryController")
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:177
armarx::NJointTrajectoryController::rtPostDeactivateController
void rtPostDeactivateController() override
This function is called after the controller is deactivated.
Definition: NJointTrajectoryController.cpp:301
armarx::NJointTrajectoryController::NJointTrajectoryController
NJointTrajectoryController(RobotUnit *prov, const NJointControllerConfigPtr &config, const VirtualRobot::RobotPtr &)
Definition: NJointTrajectoryController.cpp:17
armarx::NJointControllerWithTripleBuffer< NJointTrajectoryControllerControlData >::writeControlStruct
void writeControlStruct()
Definition: NJointControllerWithTripleBuffer.h:44
armarx::NJointControllerWithTripleBuffer< NJointTrajectoryControllerControlData >::controlDataMutex
MutexType controlDataMutex
Definition: NJointControllerWithTripleBuffer.h:73
armarx::TrajectoryController::update
const Eigen::VectorXf & update(double deltaT, const Eigen::VectorXf &currentPosition)
Definition: TrajectoryController.cpp:54
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:189
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
armarx::NJointTrajectoryController::rtRun
void rtRun(const IceUtil::Time &sensorValuesTimestamp, const IceUtil::Time &timeSinceLastIteration) override
TODO make protected and use attorneys.
Definition: NJointTrajectoryController.cpp:75
armarx::VariantType::Trajectory
const VariantTypeId Trajectory
Definition: Trajectory.h:44
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
TimeUtil.h
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:182
armarx::ManagedIceObject::offeringTopic
void offeringTopic(const std::string &name)
Registers a topic for retrival after initialization.
Definition: ManagedIceObject.cpp:290
NJointTrajectoryController.h
armarx::RobotUnit
The RobotUnit class manages a robot and its controllers.
Definition: RobotUnit.h:180
armarx::armem::server::ltm::detail::mixin::Path
std::filesystem::path Path
Definition: DiskStorageMixin.h:17
armarx::TrajectoryController::getTraj
const TrajectoryPtr & getTraj() const
Definition: TrajectoryController.cpp:120
armarx::NJointTrajectoryController::setLooping
void setLooping(bool looping)
Definition: NJointTrajectoryController.cpp:269
ARMARX_CHECK_EQUAL
#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...
Definition: ExpressionException.h:130
armarx::NJointTrajectoryControllerControlData::trajectoryCtrl
TrajectoryControllerPtr trajectoryCtrl
Definition: NJointTrajectoryController.h:21
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
armarx::NJointTrajectoryController::rtPreActivateController
void rtPreActivateController() override
This function is called before the controller is activated.
Definition: NJointTrajectoryController.cpp:295
armarx::NJointTrajectoryController::getCurrentProgressFraction
float getCurrentProgressFraction(const Ice::Current &) override
Definition: NJointTrajectoryController.cpp:249
armarx::NJointTrajectoryController::~NJointTrajectoryController
~NJointTrajectoryController()
Definition: NJointTrajectoryController.cpp:51
NJointControllerRegistry.h
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::NJointTrajectoryController::getTrajEndTime
double getTrajEndTime() const
Definition: NJointTrajectoryController.cpp:275
armarx::NJointControllerBase::useSensorValue
const SensorValueBase * useSensorValue(const std::string &sensorDeviceName) const
Get a const ptr to the given SensorDevice's SensorValue.
Definition: NJointController.cpp:383
VirtualRobot::RobotPtr
std::shared_ptr< class Robot > RobotPtr
Definition: Bus.h:18