32#include <SimoxUtility/json/json.hpp>
51 algorithms::Toppra::DriveParams
52 buildDriveParams(
const Config& config)
54 algorithms::Toppra::DriveParams params =
60 params.torqueFraction *= config.parametrizationTorqueFraction;
62 params.numSamples = config.parametrizationSamples;
69 toReference(
const algorithms::Toppra& toppra)
73 const Eigen::MatrixXd& samples = toppra.lastSamples();
75 nlohmann::json waypoints = nlohmann::json::array();
77 for (Eigen::Index i = 0; i < samples.rows(); i++)
79 waypoints.push_back(nlohmann::json{
80 {
"t", samples(i, Column::T)},
81 {
"x", samples(i, Column::X)},
82 {
"y", samples(i, Column::Y)},
83 {
"yaw", samples(i, Column::YAW)},
84 {
"velocity", samples(i, Column::VELOCITY)},
85 {
"angular_velocity", samples(i, Column::ANGULAR_VELOCITY)},
86 {
"tangential_acceleration", samples(i, Column::TANGENTIAL_ACCELERATION)},
87 {
"angular_acceleration", samples(i, Column::ANGULAR_ACCELERATION)}});
90 nlohmann::json reference;
91 reference[
"success"] =
true;
92 reference[
"duration"] = toppra.lastDuration();
93 reference[
"waypoints"] = waypoints;
104 const float boundaryVelocity)
108 const std::vector<core::GlobalTrajectoryPoint>& points =
trajectory.points();
110 float arcLength = 0.F;
112 float spanStart = 0.F;
114 for (std::size_t i = 0; i + 1 < points.size(); i++)
116 const float segment = (points[i + 1].waypoint.pose.translation() -
117 points[i].waypoint.pose.translation())
119 arcLength += segment;
126 const float from = points[i].velocity;
127 const float to = points[i + 1].velocity;
130 const float demand = std::abs(to * to - from * from) / (2.F * segment);
148 spanStart = arcLength - segment;
154 check.
spans.emplace_back(spanStart, arcLength);
160 check.
spans.emplace_back(spanStart, arcLength);
164 const float terminalVelocity = points.back().velocity;
166 terminalVelocity * terminalVelocity / (2.F * rateLimit.
maxDeceleration);
172 ARMARX_WARNING <<
"The velocity profile ends at " << terminalVelocity
175 <<
" mm of path that does not exist -- the base will overshoot the "
176 "goal by roughly that much.";
182 <<
"The velocity profile demands more than the device command ramp can "
184 << check.
violations <<
" of " << (points.size() - 1)
185 <<
" segments. Worst: " << check.
worstDemand <<
" mm/s^2 against a limit of "
187 <<
" mm. The base will not track the profile there -- expect it to lag on the "
188 "way up and to overshoot on the way down.";
201 if (name ==
"ramping")
205 if (name ==
"toppra")
210 throw std::invalid_argument(
"Unknown parametrization mode `" + name +
211 "`. Expected `none`, `ramping` or `toppra`.");
230 ReparametrizationResult
241 const auto constructionStarted = std::chrono::steady_clock::now();
244 fac::TrajectoryParametrizationFactory::create(general, buildDriveParams(config));
246 const double constructionSeconds =
247 std::chrono::duration<double>(std::chrono::steady_clock::now() -
252 .trajectory =
trajectory, .reference =
nullptr, .seconds = 0.0};
254 const auto started = std::chrono::steady_clock::now();
260 result.seconds = std::chrono::duration<double>(
261 std::chrono::steady_clock::now() - started)
265 if (
const auto* toppra =
269 result.reference = toReference(*toppra);
272 std::cout <<
" [reparametrization] " << std::left << std::setw(32)
273 <<
"one-time setup (startup)" << std::right << std::setw(8) << std::fixed
274 << std::setprecision(1) << constructionSeconds * 1e3 <<
" ms" << std::endl;
277 <<
"`: " << constructionSeconds <<
" s setup + " << result.seconds
278 <<
" s per request, " << result.trajectory.points().size()
Time-optimal reparametrization under per-motor torque and command-ramp limits.
SampleColumn
Column layout of lastSamples().
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Toppra::DriveParams LoadDriveParams(const std::filesystem::path &configFile)
Read Toppra::DriveParams from a PlatformDynamics<Robot>.json.
std::shared_ptr< TrajectoryParametrization > TrajectoryParametrizationPtr
std::filesystem::path DriveParamsPath(const std::string &robot)
Resolve config/platform/PlatformDynamics<robot>.json inside the armarx_navigation package.
This file is part of ArmarX.
CommandRampCheck checkAgainstCommandRamp(const core::GlobalTrajectory &trajectory, const simulation::CommandRateLimit &rateLimit, const float boundaryVelocity)
Compare the profile's v * dv/ds against rateLimit.
core::TrajectoryParametrization parametrizationModeFromString(const std::string &name)
Parse the --parametrization choice. Throws on an unknown name.
ReparametrizationResult reparametrize(const core::GlobalTrajectory &trajectory, const Config &config)
Re-assign the velocities along trajectory according to config.parametrization.
std::string toString(const core::TrajectoryParametrization mode)
TrajectoryParametrization
How the velocities along a planned path are assigned.
@ Ramping
Ramp down at the start, the goal and every corner. The stack's historical behaviour.
@ None
Leave the planner's velocities alone.
@ Toppra
Time-optimal under per-motor torque and command-ramp limits.
How far a velocity profile asks for more than the device command ramp can deliver.
bool terminalVelocityExceedsBoundary
Whether the profile ends above boundaryVelocity, i.e. faster than by design.
float worstDemand
Largest demanded tangential acceleration [mm/s^2], and where along the path it is.
float worstLimit
The bound that was exceeded there [mm/s^2].
std::vector< std::pair< float, float > > spans
Arc-length spans in which the demand exceeds the ramp, for the plot.
std::size_t violations
Waypoints demanding more than the ramp can deliver.
float terminalStoppingDistance
Distance the ramp needs to stop from the profile's final velocity [mm].
Everything the application needs, as read from the scene description file.
core::GeneralConfig generalConfig
core::TrajectoryParametrization parametrization
How the velocities along the planned path are (re-)assigned before simulating.
TrajectoryParametrization parametrization
How the planned velocity profile is (re-)assigned before execution.
The per-axis command ramp the platform device applies below the navigation stack.