31#include <SimoxUtility/json/json.hpp>
47 return std::atan2(pose.linear()(1, 0), pose.linear()(0, 0));
54 nlohmann::json points = nlohmann::json::array();
58 const core::Position& position = point.waypoint.pose.translation();
60 points.push_back(nlohmann::json{{
"x", position.x()},
62 {
"yaw", yawOf(point.waypoint.pose)},
63 {
"velocity", point.velocity}});
68 return nlohmann::json{{
"points", points}, {
"length", 0.F}, {
"duration", 0.F}};
71 return nlohmann::json{
83 return nlohmann::json{
90 {
"alpha", params.
alpha},
103 template <
class Sample>
105 span(
const std::vector<Sample>& samples)
107 if (samples.size() < 2)
112 return static_cast<double>(samples.back().timestampUs - samples.front().timestampUs) *
117 writeRtCsv(
const std::filesystem::path& file,
const std::vector<RtSample>& samples)
119 std::ofstream stream{file};
120 if (not stream.good())
126 stream <<
"t_us,episode,seq,x,y,yaw,v_meas_x,v_meas_y,w_meas,v_tgt_x,v_tgt_y,w_tgt,"
127 "v_cmd_x,v_cmd_y,w_cmd,dt,stale,slew_limited\n";
129 stream << std::setprecision(9);
133 stream << s.timestampUs <<
',' << s.episode <<
',' << s.sequence <<
',' << s.x
134 <<
',' << s.y <<
',' << s.yaw <<
',' << s.vMeasX <<
',' << s.vMeasY <<
','
135 << s.wMeas <<
',' << s.vTgtX <<
',' << s.vTgtY <<
',' << s.wTgt <<
','
136 << s.vCmdX <<
',' << s.vCmdY <<
',' << s.wCmd <<
',' << s.dt <<
','
137 << (s.stale ? 1 : 0) <<
',' << (s.slewLimited ? 1 : 0) <<
'\n';
142 writeControlCsv(
const std::filesystem::path& file,
143 const std::vector<ControlSample>& samples)
145 std::ofstream stream{file};
146 if (not stream.good())
152 stream <<
"t_us,episode,seq,traj_rev,x,y,yaw,ref_x,ref_y,ref_yaw,ref_v,proj_idx,"
153 "final_seg,pos_err,ori_err,cur_ori,des_ori,ff_ang,capped_ff_v,ff_sat,guard,"
154 "v_raw_x,v_raw_y,w_raw,v_filt_x,v_filt_y,w_filt,"
155 "limit_linear,limit_angular,velocity_factor\n";
157 stream << std::setprecision(9);
161 stream << s.timestampUs <<
',' << s.episode <<
',' << s.sequence <<
','
162 << s.trajectoryRevision <<
',' << s.x <<
',' << s.y <<
',' << s.yaw <<
','
163 << s.refX <<
',' << s.refY <<
',' << s.refYaw <<
',' << s.refVelocity <<
','
164 << s.projectionIndex <<
',' << (s.finalSegment ? 1 : 0) <<
','
165 << s.positionError <<
',' << s.orientationError <<
','
166 << s.currentOrientation <<
',' << s.desiredOrientation <<
',' << s.ffAngular
167 <<
',' << s.cappedFfVelocity <<
',' << (s.ffSaturated ? 1 : 0) <<
','
168 << s.guard <<
',' << s.vRawX <<
',' << s.vRawY <<
',' << s.wRaw <<
','
169 << s.vFiltX <<
',' << s.vFiltY <<
',' << s.wFilt <<
',' << s.limitLinear
170 <<
',' << s.limitAngular <<
',' << s.velocityFactor <<
'\n';
180 std::ostringstream name;
182 << std::setfill(
'0') << episode.
episode;
184 const std::filesystem::path directory =
187 std::filesystem::create_directories(directory);
196 meta[
"rt"] = nlohmann::json{{
"recorded", episode.
rtSamples.size()},
211 std::ofstream stream{directory /
"meta.json"};
212 if (not stream.good())
217 stream <<
meta.dump(2) << std::endl;
221 nlohmann::json revisions = nlohmann::json::array();
225 nlohmann::json entry = toJson(revision.
trajectory);
226 entry[
"revision"] = revision.
revision;
227 revisions.push_back(entry);
230 const nlohmann::json trajectories{
231 {
"revisions", revisions},
234 std::ofstream stream{directory /
"trajectory.json"};
235 if (not stream.good())
237 ARMARX_WARNING <<
"Cannot write " << (directory /
"trajectory.json");
240 stream << trajectories.dump(2) << std::endl;
243 writeRtCsv(directory /
"rt.csv", episode.
rtSamples);
244 writeControlCsv(directory /
"control.csv", episode.
controlSamples);
246 ARMARX_INFO <<
"Wrote the execution diagnostics of episode " << episode.
episode <<
" to "
247 << directory <<
" (" << episode.
rtSamples.size() <<
" rt samples, "
249 << episode.
trajectories.size() <<
" trajectory revisions).";
251 return directory.string();
253 catch (
const std::exception& e)
256 ARMARX_WARNING <<
"Could not write the execution diagnostics: " << e.what();
std::string toDateTimeString() const
#define ARMARX_INFO
The normal logging level.
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
float maxLinearAcceleration
Rate at which the RT thread walks the commanded twist towards this controller's output.
float minFeedforwardVelocityFraction
Floor on the capped linear feed-forward, as a fraction of the requested velocity.
bool enableAngularFeedforward
bool coupleLinearAndAngularLimits
float maxAngularAcceleration
float angularFeedforwardFraction
Fraction of limits.angular the angular feed-forward may use. 1 lets it saturate.
float lookaheadDistance
Lookahead as a distance [mm]. 0 keeps the pure maxSegmentsAhead behaviour.