3 #include <VirtualRobot/Nodes/RobotNode.h>
4 #include <VirtualRobot/Robot.h>
5 #include <VirtualRobot/TimeOptimalTrajectory/TimeOptimalTrajectory.h>
8 #include <ArmarXCore/interface/observers/ObserverInterface.h>
16 NJointControllerRegistration<NJointTrajectoryController>
20 const NJointControllerConfigPtr& config,
23 cfg = NJointTrajectoryControllerConfigPtr::dynamicCast(config);
26 for (std::string jointName : cfg->jointNames)
30 targets.push_back(ct->
asA<ControlTarget1DoFActuatorVelocity>());
31 sensors.push_back(sv->
asA<SensorValue1DoFActuatorPosition>());
33 if (cfg->jointNames.size() == 0)
37 for (
auto& jointName : cfg->jointNames)
41 VirtualRobot::RobotNodePtr rn = robot->getRobotNode(jointName);
44 ls.enabled = rn->isLimitless();
45 ls.limitLo = rn->getJointLimitLo();
46 ls.limitHi = rn->getJointLimitHi();
48 ARMARX_DEBUG <<
"limitless status - " << jointName <<
": " << rn->isLimitless();
49 limitlessStates.push_back(ls);
60 return "NJointTrajectoryController";
72 plotter = getTopic<StaticPlotterInterfacePrx>(
"StaticPlotter");
73 dbgObs = getTopic<DebugObserverInterfacePrx>(
"DebugObserver");
84 const auto& dimNames = contr.
getTraj()->getDimensionNames();
85 for (
size_t i = 0; i < sensors.size(); i++)
89 currentPos(i) = sensors.at(i)->position;
93 contr.
update(timeSinceLastIteration.toSecondsDouble() * direction, currentPos);
105 (currentTimestamp >= contr.
getTraj()->rbegin()->getTimestamp() &&
107 (currentTimestamp <= contr.
getTraj()->begin()->getTimestamp() && direction == -1.0);
109 for (
size_t i = 0; i < targets.size(); ++i)
112 targets.at(i)->velocity =
113 (cfg->isPreview || finished) ? 0.0f : newVelocities(i);
117 if (finished && looping)
131 size_t trajectoryDimensions = trajectory->dim();
133 trajectory->setLimitless(limitlessStates);
135 if (cfg->considerConstraints)
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);
146 Eigen::VectorXd waypoint(trajectoryDimensions);
147 for (
size_t i = 0; i < trajectoryDimensions; ++i)
149 waypoint(i) = element.getPosition(i);
151 pathPoints.emplace_back(waypoint);
155 VirtualRobot::TimeOptimalTrajectory timeOptimalTraj(
156 p, maxVelocities, maxAccelerations, timeStep);
160 Ice::DoubleSeq newTimestamps;
161 double duration = timeOptimalTraj.getDuration();
162 for (
double t = 0.0; t < duration; t += timeStep)
164 newTimestamps.push_back(t);
166 newTimestamps.push_back(duration);
168 for (
size_t d = 0; d < trajectoryDimensions; d++)
178 Ice::DoubleSeq derivs;
179 for (
double t = 0.0; t < duration; t += timeStep)
182 derivs.push_back(timeOptimalTraj.getPosition(t)[d]);
183 derivs.push_back(timeOptimalTraj.getVelocity(t)[d]);
184 newTraj->addDerivationsToDimension(d, t, derivs);
187 derivs.push_back(timeOptimalTraj.getPosition(duration)[d]);
188 derivs.push_back(timeOptimalTraj.getVelocity(duration)[d]);
189 newTraj->addDerivationsToDimension(d, duration, derivs);
191 newTraj->setDimensionNames(trajectory->getDimensionNames());
192 newTraj->setLimitless(limitlessStates);
195 ARMARX_INFO <<
"Trajectory duration: " << newTraj->getTimeLength();
197 trajectory = newTraj;
200 trajEndTime = *trajectory->getTimestamps().rbegin() - *trajectory->getTimestamps().begin();
201 currentPos.resize(trajectory->getDimensionNames().size());
203 startTimestamp = *trajectory->getTimestamps().begin();
204 endTimestamp = *trajectory->getTimestamps().rbegin();
207 StringFloatSeqDict posData;
208 StringFloatSeqDict velData;
209 for (
size_t d = 0; d < trajectory->dim(); ++d)
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());
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);
232 trajectoryCtrl.reset(
247 return currentTimestamp;
262 return trajectoryCtrl->getCurrentTimestamp();
273 this->looping = looping;
288 return TrajectoryPtr::dynamicCast(trajectoryCtrl->getTraj()->clone());
305 for (
auto&
target : targets)