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