RcsPySim
A robot control and simulation library
ECBoxLifting.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  Copyright (c) 2020, Fabio Muratore, Honda Research Institute Europe GmbH, and
3  Technical University of Darmstadt.
4  All rights reserved.
5 
6  Redistribution and use in source and binary forms, with or without
7  modification, are permitted provided that the following conditions are met:
8  1. Redistributions of source code must retain the above copyright
9  notice, this list of conditions and the following disclaimer.
10  2. Redistributions in binary form must reproduce the above copyright
11  notice, this list of conditions and the following disclaimer in the
12  documentation and/or other materials provided with the distribution.
13  3. Neither the name of Fabio Muratore, Honda Research Institute Europe GmbH,
14  or Technical University of Darmstadt, nor the names of its contributors may
15  be used to endorse or promote products derived from this software without
16  specific prior written permission.
17 
18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  DISCLAIMED. IN NO EVENT SHALL FABIO MURATORE, HONDA RESEARCH INSTITUTE EUROPE GMBH,
22  OR TECHNICAL UNIVERSITY OF DARMSTADT BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
26  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  POSSIBILITY OF SUCH DAMAGE.
29 *******************************************************************************/
30 
31 #include "ExperimentConfig.h"
32 #include "action/ActionModelIK.h"
36 #include "observation/OMCombined.h"
41 #include "observation/OMPartial.h"
48 #include "physics/PPDBoxExtents.h"
51 #include "physics/ForceDisturber.h"
52 #include "util/string_format.h"
53 
54 #include <Rcs_macros.h>
55 #include <Rcs_typedef.h>
56 #include <Rcs_Vec3d.h>
57 #include <TaskPosition3D.h>
58 #include <TaskVelocity1D.h>
59 #include <TaskDistance.h>
60 #include <TaskOmega1D.h>
61 #include <TaskEuler3D.h>
62 #include <TaskFactory.h>
63 
64 #ifdef GRAPHICS_AVAILABLE
65 
66 #include <RcsViewer.h>
67 
68 #endif
69 
70 #include <memory>
71 #include <iomanip>
72 
73 namespace Rcs
74 {
76 {
78  {
79  // Get the relevant bodies
80  RcsBody* rightGrasp = RcsGraph_getBodyByName(graph, "PowerGrasp_R");
81  RCHECK(rightGrasp);
82  RcsBody* box = RcsGraph_getBodyByName(graph, "Box");
83  RCHECK(box);
84  RcsBody* basket = RcsGraph_getBodyByName(graph, "Basket");
85  RCHECK(basket);
86 
87  // Get reference frames for the position and orientation tasks
88  std::string refFrameType = "world";
89  properties->getProperty(refFrameType, "refFrame");
90  RcsBody* refBody = nullptr;
91  RcsBody* refFrame = nullptr;
92  if (refFrameType == "world") {
93  // Keep nullptr
94  }
95  else if (refFrameType == "box") {
96  refBody = box;
97  refFrame = box;
98  }
99  else if (refFrameType == "basket") {
100  refBody = basket;
101  refFrame = basket;
102  }
103  else {
104  std::ostringstream os;
105  os << "Unsupported reference frame type: " << refFrame;
106  throw std::invalid_argument(os.str());
107  }
108 
109  // Get the type of action model
110  std::string actionModelType = "unspecified";
111  properties->getProperty(actionModelType, "actionModelType");
112 
113  // Get the method how to combine the movement primitives / tasks given their activation (common for both)
114  std::string taskCombinationMethod = "unspecified";
115  properties->getProperty(taskCombinationMethod, "taskCombinationMethod");
117 
118  if (actionModelType == "ik_activation") {
119  // Create the action model
120  auto amIK = new AMIKControllerActivation(graph, tcm);
121  std::vector<Task*> tasks;
122 
123  // Check if the tasks are defined on position or velocity level. Adapt their parameters if desired.
124  if (properties->getPropertyBool("positionTasks", true)) {
125  RcsBody* tip1R = RcsGraph_getBodyByName(graph, "tip1_R");
126  RCHECK(tip1R);
127  // Right
128  tasks.emplace_back(new TaskPosition1D("Y", graph, rightGrasp, refBody, refFrame));
129  tasks.emplace_back(new TaskPosition1D("Z", graph, rightGrasp, refBody, refFrame));
130 // tasks.emplace_back(new TaskPosition1D("Y", graph, rightGrasp, refBody, refFrame));
131  tasks.emplace_back(new TaskDistance(graph, tip1R, box, 0.05));
132  }
133 
134  else {
135  // Right
136  tasks.emplace_back(new TaskVelocity1D("Yd", graph, rightGrasp, refBody, refFrame));
137  tasks.emplace_back(new TaskVelocity1D("Zd", graph, rightGrasp, refBody, refFrame));
138  }
139 
140  // Add the tasks
141  for (auto t : tasks) { amIK->addTask(t); }
142 
143  // Add the always active tasks
144  amIK->addAlwaysActiveTask(new TaskPosition1D("X", graph, rightGrasp, basket, basket));
145 // amIK->addAlwaysActiveTask(new TaskOmega1D("Cd", graph, rightGrasp, nullptr, nullptr));
146 
147  // Set the tasks' desired states
148  std::vector<PropertySource*> taskSpec = properties->getChildList("taskSpecIK");
149  amIK->setXdesFromTaskSpec(taskSpec);
150 
151  // Incorporate collision costs into IK
152  if (properties->getPropertyBool("collisionAvoidanceIK", true)) {
153  REXEC(4) {
154  std::cout << "IK considers the provided collision model" << std::endl;
155  }
156  amIK->setupCollisionModel(collisionMdl);
157  }
158 
159  return amIK;
160  }
161 
162  else if (actionModelType == "ds_activation") {
163  // Initialize action model and tasks
164  std::unique_ptr<AMIKGeneric> innerAM(new AMIKGeneric(graph));
165  std::vector<std::unique_ptr<DynamicalSystem>> tasks;
166 
167  // Control effector positions and orientation
168  if (properties->getPropertyBool("positionTasks", false)) {
169  // Right
170  innerAM->addTask(new TaskPosition3D(graph, rightGrasp, basket, basket));
171  innerAM->addTask(new TaskEuler3D(graph, rightGrasp, basket, basket));
172  innerAM->addTask(TaskFactory::createTask(
173  R"(<Task name="Hand R Joints" controlVariable="Joints" jnts="fing1-knuck1_R tip1-fing1_R fing2-knuck2_R tip2-fing2_R fing3-knuck3_R tip3-fing3_R knuck1-base_R" tmc="0.1" vmax="1000" active="untrue"/>)",
174  graph)
175  );
176 // innerAM->addTask(TaskFactory::createTask(
177 // R"(<Task name="Distance R" controlVariable="Distance" effector="tip2_R" refBdy="Box" gainDX="1." active="true"/>)",
178 // graph)
179 // );
180 
181  // Obtain task data (depends on the order of the MPs coming from Pyrado)
182  // Right
183  unsigned int i = 0;
184  std::vector<unsigned int> taskDimsRight{
185  3, 3, 3, 3, 7
186  };
187  std::vector<unsigned int> offsetsRight{
188  0, 0, 3, 3, 6
189  };
190  auto& tsRight = properties->getChildList("tasksRight");
191  for (auto tsk : tsRight) {
192  DynamicalSystem* ds = DynamicalSystem::create(tsk, taskDimsRight[i]);
193  tasks.emplace_back(new DSSlice(ds, offsetsRight[i], taskDimsRight[i]));
194  i++;
195  }
196  }
197 
198  // Control effector velocity and orientation
199  else {
200  // Right
201  innerAM->addTask(new TaskVelocity1D("Xd", graph, rightGrasp, refBody, refFrame));
202  innerAM->addTask(new TaskVelocity1D("Yd", graph, rightGrasp, refBody, refFrame));
203  innerAM->addTask(new TaskVelocity1D("Zd", graph, rightGrasp, refBody, refFrame));
204  innerAM->addTask(new TaskOmega1D("Ad", graph, rightGrasp, refBody, refFrame));
205  innerAM->addTask(new TaskOmega1D("Bd", graph, rightGrasp, refBody, refFrame));
206  innerAM->addTask(new TaskOmega1D("Cd", graph, rightGrasp, refBody, refFrame));
207  // innerAM->addTask(new TaskJoint(graph, RcsGraph_getJointByName(graph, "fing1-knuck1_R")));
208  innerAM->addTask(TaskFactory::createTask(
209  R"(<Task name="Hand R Joints" controlVariable="Joints" jnts="fing1-knuck1_R tip1-fing1_R fing2-knuck2_R tip2-fing2_R fing3-knuck3_R tip3-fing3_R knuck1-base_R" tmc="0.1" vmax="1000" active="untrue"/>)",
210  graph)
211  );
212 
213  // Obtain task data (depends on the order of the MPs coming from Pyrado)
214  // Right
215  unsigned int i = 0;
216  std::vector<unsigned int> taskDimsRight{
217  1, 1, 1, 1, 1, 1, 7
218  };
219  std::vector<unsigned int> offsetsRight{
220  0, 1, 2, 3, 4, 5, 6
221  };
222  auto& tsRight = properties->getChildList("tasksRight");
223  for (auto tsk : tsRight) {
224  DynamicalSystem* ds = DynamicalSystem::create(tsk, taskDimsRight[i]);
225  tasks.emplace_back(new DSSlice(ds, offsetsRight[i], taskDimsRight[i]));
226  i++;
227  }
228  }
229 
230  if (tasks.empty()) {
231  throw std::invalid_argument("No tasks specified!");
232  }
233 
234  // Incorporate collision costs into IK
235  if (properties->getPropertyBool("collisionAvoidanceIK", true)) {
236  REXEC(4) {
237  std::cout << "IK considers the provided collision model" << std::endl;
238  }
239  innerAM->setupCollisionModel(collisionMdl);
240  }
241 
242  // Setup task-based action model
243  std::vector<DynamicalSystem*> taskRel;
244  for (auto& task : tasks) {
245  taskRel.push_back(task.release());
246  }
247 
248  return new AMDynamicalSystemActivation(innerAM.release(), taskRel, tcm);
249  }
250 
251  else {
252  std::ostringstream os;
253  os << "Unsupported action model type: " << actionModelType;
254  throw std::invalid_argument(os.str());
255  }
256  }
257 
259  {
260  std::unique_ptr<OMCombined> fullState(new OMCombined());
261 
262  // Observe effector positions (and velocities)
263  if (properties->getPropertyBool("observeVelocities", false)) {
264  auto omRightLin = new OMBodyStateLinear(graph, "PowerGrasp_R"); // in world coordinates
265  omRightLin->setMinState({0.4, -0.8, 0.6}); // [m]
266  omRightLin->setMaxState({1.6, 0.8, 1.4}); // [m]
267  omRightLin->setMaxVelocity(3.); // [m/s]
268  fullState->addPart(OMPartial::fromMask(omRightLin, {false, true, true}));
269  }
270  else {
271  auto omRightLin = new OMBodyStateLinearPositions(graph, "PowerGrasp_R"); // in world coordinates
272  omRightLin->setMinState({0.4, -0.8, 0.6}); // [m]
273  omRightLin->setMaxState({1.6, 0.8, 1.4}); // [m]
274  fullState->addPart(OMPartial::fromMask(omRightLin, {false, true, true}));
275  }
276 
277  // Observe box positions (and velocities)
278  if (properties->getPropertyBool("observeVelocities", false)) {
279 // auto omBoxLin = new OMBodyStateLinear(graph, "Box", "Table", "Table"); // in relative coordinates
280  auto omBoxLin = new OMBodyStateLinear(graph, "Box"); // in world coordinates
281  omBoxLin->setMinState({0.4, -0.8, 0.6}); // [m]
282  omBoxLin->setMaxState({1.6, 0.8, 1.4}); // [m]
283  omBoxLin->setMaxVelocity(3.); // [m/s]
284  fullState->addPart(OMPartial::fromMask(omBoxLin, {false, true, true}));
285  }
286  else {
287  auto omBoxLin = new OMBodyStateLinearPositions(graph, "Box"); // in world coordinates
288  omBoxLin->setMinState({0.4, -0.8, 0.6}); // [m]
289  omBoxLin->setMaxState({1.6, 0.8, 1.4}); // [m]
290  fullState->addPart(OMPartial::fromMask(omBoxLin, {false, true, true}));
291  }
292 
293  // Observe box orientation (and velocities)
294  if (properties->getPropertyBool("observeVelocities", false)) {
295  auto omBoxAng = new OMBodyStateAngular(graph, "Box"); // in world coordinates
296  omBoxAng->setMaxVelocity(RCS_DEG2RAD(720)); // [rad/s]
297  fullState->addPart(OMPartial::fromMask(omBoxAng, {true, false, false}));
298  }
299  else {
300  auto omBoxAng = new OMBodyStateAngularPositions(graph, "Box"); // in world coordinates
301  fullState->addPart(OMPartial::fromMask(omBoxAng, {true, false, false}));
302  }
303 
304  // Add goal distances
305  if (properties->getPropertyBool("observeDynamicalSystemGoalDistance", false)) {
307  RCHECK(amAct);
308  fullState->addPart(new OMDynamicalSystemGoalDistance(amAct));
309  }
310 
311  // Add force/torque measurements
312  if (properties->getPropertyBool("observeForceTorque", true)) {
313  RcsSensor* ftsL = RcsGraph_getSensorByName(graph, "WristLoadCellLBR_L");
314  if (ftsL) {
315  auto omForceTorque = new OMForceTorque(graph, ftsL->name, 1200, true);
316  fullState->addPart(OMPartial::fromMask(omForceTorque, {false, true, true, false, false, false}));
317  }
318  RcsSensor* ftsR = RcsGraph_getSensorByName(graph, "WristLoadCellLBR_R");
319  if (ftsR) {
320  auto omForceTorque = new OMForceTorque(graph, ftsR->name, 1200, true);
321  fullState->addPart(OMPartial::fromMask(omForceTorque, {false, true, true, false, false, false}));
322  }
323  }
324 
325  // Add current collision cost
326  if (properties->getPropertyBool("observeCollisionCost", true) & (collisionMdl != nullptr)) {
327  // Add the collision cost observation model
328  auto omColl = new OMCollisionCost(collisionMdl);
329  fullState->addPart(omColl);
330  }
331 
332  // Add predicted collision cost
333  if (properties->getPropertyBool("observePredictedCollisionCost", false) & (collisionMdl != nullptr)) {
334  // Get the horizon from config
335  int horizon = 20;
336  properties->getChild("collisionConfig")->getProperty(horizon, "predCollHorizon");
337  // Add the collision cost observation model
338  auto omCollPred = new OMCollisionCostPrediction(graph, collisionMdl, actionModel, horizon);
339  fullState->addPart(omCollPred);
340  }
341 
342  // Add manipulability index
343  auto ikModel = actionModel->unwrap<ActionModelIK>();
344  if (properties->getPropertyBool("observeManipulabilityIndex", false) && ikModel) {
345  bool ocm = properties->getPropertyBool("observeCurrentManipulability", true);
346  fullState->addPart(new OMManipulabilityIndex(ikModel, ocm));
347  }
348 
349  // Add the dynamical system discrepancy observation model
350  if (properties->getPropertyBool("observeDynamicalSystemDiscrepancy", false) & (collisionMdl != nullptr)) {
351  auto castedAM = dynamic_cast<AMDynamicalSystemActivation*>(actionModel);
352  if (castedAM) {
353  auto omDSDescr = new OMDynamicalSystemDiscrepancy(castedAM);
354  fullState->addPart(omDSDescr);
355  }
356  else {
357  throw std::invalid_argument("The action model needs to be of type AMDynamicalSystemActivation!");
358  }
359  }
360 
361  // Add the task space discrepancy observation model
362  if (properties->getPropertyBool("observeTaskSpaceDiscrepancy", true)) {
363  auto wamIK = actionModel->unwrap<ActionModelIK>();
364  if (wamIK) {
365  auto omTSDescrR = new OMTaskSpaceDiscrepancy("PowerGrasp_R", graph, wamIK->getController()->getGraph());
366  fullState->addPart(OMPartial::fromMask(omTSDescrR, {false, true, true}));
367  }
368  else {
369  throw std::invalid_argument("The action model needs to be of type ActionModelIK!");
370  }
371  }
372 
373  return fullState.release();
374  }
375 
377  {
378  manager->addParam("Box", new PPDBoxExtents(0, true, true, false)); // the Box body has only 1 shape
379  manager->addParam("Box", new PPDMassProperties());
380  manager->addParam("Box", new PPDMaterialProperties());
381  manager->addParam("Basket", new PPDMassProperties());
382  manager->addParam("Basket", new PPDMaterialProperties());
383  }
384 
386  {
387  return new ISSBoxLifting(graph, properties->getPropertyBool("fixedInitState", false));
388  }
389 
391  {
392  RcsBody* box = RcsGraph_getBodyByName(graph, "Box");
393  RCHECK(box);
394  return new ForceDisturber(box, box);
395  }
396 
397  virtual void initViewer(Rcs::Viewer* viewer)
398  {
399 #ifdef GRAPHICS_AVAILABLE
400  // Set camera above plate
401  RcsBody* table = RcsGraph_getBodyByName(graph, "Table");
402  RCHECK(table);
403  std::string cameraView = "egoView";
404  properties->getProperty(cameraView, "egoView");
405 
406  // The camera center is 10cm above the the plate's center
407  double cameraCenter[3];
408  Vec3d_copy(cameraCenter, table->A_BI->org);
409  cameraCenter[0] -= 0.2;
410 
411  // The camera location - not specified yet
412  double cameraLocation[3];
413  Vec3d_setZero(cameraLocation);
414 
415  // Camera up vector defaults to z
416  double cameraUp[3];
417  Vec3d_setUnitVector(cameraUp, 2);
418 
419  if (cameraView == "egoView") {
420  RcsBody* railBot = RcsGraph_getBodyByName(graph, "RailBot");
421  RCHECK(railBot);
422 
423  // Rotate to world frame
424  Vec3d_transformSelf(cameraLocation, table->A_BI);
425 
426  // Move the camera approx where the Kinect would be
427  cameraLocation[0] = railBot->A_BI->org[0] + 2.3;
428  cameraLocation[1] = 0;
429  cameraLocation[2] = railBot->A_BI->org[2] + 1.5;
430  }
431  else {
432  RMSG("Unsupported camera view: %s", cameraView.c_str());
433  return;
434  }
435 
436  // Apply the camera position
437  viewer->setCameraHomePosition(osg::Vec3d(cameraLocation[0], cameraLocation[1], cameraLocation[2]),
438  osg::Vec3d(cameraCenter[0], cameraCenter[1], cameraCenter[2]),
439  osg::Vec3d(cameraUp[0], cameraUp[1], cameraUp[2]));
440 #endif
441  }
442 
443  void
445  std::vector<std::string>& linesOut,
446  double currentTime, const MatNd* obs,
447  const MatNd* currentAction,
448  PhysicsBase* simulator,
449  PhysicsParameterManager* physicsManager,
450  ForceDisturber* forceDisturber) override
451  {
452  // Obtain simulator name
453  const char* simName = "None";
454  if (simulator != nullptr) {
455  simName = simulator->getClassName();
456  }
457  linesOut.emplace_back(
458  string_format("physics engine: %s sim time: %2.3f s", simName, currentTime));
459 
460  unsigned int numPosCtrlJoints = 0;
461  unsigned int numTrqCtrlJoints = 0;
462  // Iterate over unconstrained joints
463  RCSGRAPH_TRAVERSE_JOINTS(graph) {
464  if (JNT->jacobiIndex != -1) {
465  if (JNT->ctrlType == RCSJOINT_CTRL_TYPE::RCSJOINT_CTRL_POSITION) {
466  numPosCtrlJoints++;
467  }
468  else if (JNT->ctrlType == RCSJOINT_CTRL_TYPE::RCSJOINT_CTRL_TORQUE) {
469  numTrqCtrlJoints++;
470  }
471  }
472  }
473  linesOut.emplace_back(
474  string_format("num joints: %d total, %d pos ctrl, %d trq ctrl", graph->nJ, numPosCtrlJoints,
475  numTrqCtrlJoints));
476 
477  unsigned int sd = observationModel->getStateDim();
478 
479  auto omRightLin = observationModel->findOffsets<OMBodyStateLinear>(); // there are two, we find the first
480  if (omRightLin) {
481  linesOut.emplace_back(
482  string_format("right hand pg: [% 1.3f,% 1.3f,% 1.3f] m [% 1.3f,% 1.3f,% 1.3f] m/s",
483  obs->ele[omRightLin.pos], obs->ele[omRightLin.pos + 1], obs->ele[omRightLin.pos + 2],
484  obs->ele[sd + omRightLin.vel], obs->ele[sd + omRightLin.vel + 1],
485  obs->ele[sd + omRightLin.vel + 2]));
486  }
487 
488  auto omBoxAng = observationModel->findOffsets<OMBodyStateAngular>(); // assuming there is only the box one
489  if (omBoxAng && omRightLin) {
490  linesOut.emplace_back(
491  string_format("box absolute: [% 1.3f,% 1.3f,% 1.3f] m [% 3.0f,% 3.0f,% 3.0f] deg",
492  obs->ele[omRightLin.pos + 3], obs->ele[omRightLin.pos + 4], obs->ele[omRightLin.pos + 5],
493  RCS_RAD2DEG(obs->ele[omBoxAng.pos]), RCS_RAD2DEG(obs->ele[omBoxAng.pos + 1]),
494  RCS_RAD2DEG(obs->ele[omBoxAng.pos + 2])));
495  }
496  else if (omRightLin) {
497  linesOut.emplace_back(
498  string_format("box absolute: [% 1.3f,% 1.3f,% 1.3f] m",
499  obs->ele[omRightLin.pos + 3], obs->ele[omRightLin.pos + 4],
500  obs->ele[omRightLin.pos + 5]));
501  }
502 
503  auto omFTS = observationModel->findOffsets<OMForceTorque>();
504  if (omFTS) {
505  linesOut.emplace_back(
506  string_format("forces right: [% 3.1f, % 3.1f, % 3.1f] N",
507  obs->ele[omFTS.pos], obs->ele[omFTS.pos + 1], obs->ele[omFTS.pos + 2]));
508  }
509 
510  auto omColl = observationModel->findOffsets<OMCollisionCost>();
512  if (omColl && omCollPred) {
513  linesOut.emplace_back(
514  string_format("coll cost: %3.2f pred coll cost: %3.2f",
515  obs->ele[omColl.pos], obs->ele[omCollPred.pos]));
516 
517  }
518  else if (omColl) {
519  linesOut.emplace_back(string_format("coll cost: %3.2f", obs->ele[omColl.pos]));
520  }
521  else if (omCollPred) {
522  linesOut.emplace_back(string_format("pred coll cost: %3.2f", obs->ele[omCollPred.pos]));
523  }
524 
526  if (omMI) {
527  linesOut.emplace_back(string_format("manip idx: %1.3f", obs->ele[omMI.pos]));
528  }
529 
531  if (omGD) {
532  if (properties->getPropertyBool("positionTasks", false)) {
533  linesOut.emplace_back(
534  string_format("goal distance: [% 1.2f,% 1.2f,% 1.2f,% 1.2f,% 1.2f,\n"
535  " % 1.2f,% 1.2f,% 1.2f,% 1.2f,% 1.2f,% 1.2f]",
536  obs->ele[omGD.pos], obs->ele[omGD.pos + 1], obs->ele[omGD.pos + 2],
537  obs->ele[omGD.pos + 3], obs->ele[omGD.pos + 4],
538  obs->ele[omGD.pos + 5], obs->ele[omGD.pos + 6], obs->ele[omGD.pos + 7],
539  obs->ele[omGD.pos + 8], obs->ele[omGD.pos + 9], obs->ele[omGD.pos + 10]));
540  }
541  }
542 
544  if (omTSD) {
545  linesOut.emplace_back(
546  string_format("ts delta: [% 1.3f,% 1.3f,% 1.3f] m",
547  obs->ele[omTSD.pos], obs->ele[omTSD.pos + 1], obs->ele[omTSD.pos + 2]));
548  }
549 
550  std::stringstream ss;
551  ss << "actions: [";
552  for (unsigned int i = 0; i < currentAction->m - 1; i++) {
553  ss << std::fixed << std::setprecision(2) << MatNd_get(currentAction, i, 0) << ", ";
554  if (i == 6) {
555  ss << "\n ";
556  }
557  }
558  ss << std::fixed << std::setprecision(2) << MatNd_get(currentAction, currentAction->m - 1, 0) << "]";
559  linesOut.emplace_back(string_format(ss.str()));
560 
561  auto castedAM = dynamic_cast<AMDynamicalSystemActivation*>(actionModel);
562  if (castedAM) {
563  std::stringstream ss;
564  ss << "activations: [";
565  for (unsigned int i = 0; i < castedAM->getDim() - 1; i++) {
566  ss << std::fixed << std::setprecision(2) << MatNd_get(castedAM->getActivation(), i, 0) << ", ";
567  if (i == 6) {
568  ss << "\n ";
569  }
570  }
571  ss << std::fixed << std::setprecision(2) <<
572  MatNd_get(castedAM->getActivation(), castedAM->getDim() - 1, 0) << "]";
573  linesOut.emplace_back(string_format(ss.str()));
574 
575  linesOut.emplace_back(string_format("tcm: %s", castedAM->getTaskCombinationMethodName()));
576  }
577 
578  if (physicsManager != nullptr) {
579  // Get the parameters that are not stored in the Rcs graph
580  BodyParamInfo* box_bpi = physicsManager->getBodyInfo("Box");
581  BodyParamInfo* basket_bpi = physicsManager->getBodyInfo("Basket");
582 
583  linesOut.emplace_back(
584  string_format("box width: %1.3f m box length: %1.3f m",
585  box_bpi->body->shape[0]->extents[0], box_bpi->body->shape[0]->extents[1]));
586  linesOut.emplace_back(
587  string_format("box mass: %1.2f kg box frict coeff: %1.3f ",
588  box_bpi->body->m, box_bpi->material.getFrictionCoefficient()));
589  linesOut.emplace_back(
590  string_format("basket mass: %1.2f kg basket frict coeff: %1.3f ",
591  basket_bpi->body->m, basket_bpi->material.getFrictionCoefficient()));
592  }
593  }
594 
595 };
596 
597 // Register
599 
600 }
virtual bool getProperty(std::string &out, const char *property)=0
virtual bool getPropertyBool(const char *property, bool def=false)=0
virtual void populatePhysicsParameters(PhysicsParameterManager *manager)
virtual void initViewer(Rcs::Viewer *viewer)
RcsBody * body
The body.
Definition: BodyParamInfo.h:64
virtual ActionModel * createActionModel()
virtual ForceDisturber * createForceDisturber()
virtual PropertySource * getChild(const char *prefix)=0
void addParam(const char *bodyName, PhysicsParameterDescriptor *desc)
static TaskCombinationMethod checkTaskCombinationMethod(std::string tcmName)
virtual ObservationModel * createObservationModel()
virtual InitStateSetter * createInitStateSetter()
TaskCombinationMethod
Definition: ActionModel.h:46
virtual const std::vector< PropertySource * > & getChildList(const char *prefix)=0
virtual unsigned int getStateDim() const =0
void getHUDText(std::vector< std::string > &linesOut, double currentTime, const MatNd *obs, const MatNd *currentAction, PhysicsBase *simulator, PhysicsParameterManager *physicsManager, ForceDisturber *forceDisturber) override
BodyParamInfo * getBodyInfo(const char *bodyName)
static DynamicalSystem * create(PropertySource *properties, unsigned int innerTaskDim)
static OMPartial * fromMask(ObservationModel *wrapped, const std::vector< bool > &mask, bool exclude=false)
Definition: OMPartial.cpp:116
std::string string_format(const std::string &format, Args ... args)
Definition: string_format.h:45
ObservationModel * observationModel
Observation model (pluggable) used to create the observation which will be returned from step() ...
PropertySource * properties
Property source (owned)
const AM * unwrap() const
Definition: ActionModel.h:142
ActionModel * actionModel
Action model (pluggable)
RcsCollisionMdl * collisionMdl
Collision model to use. Is based on the graph, so take care when using with IK etc.
static ExperimentConfigRegistration< ECBoxLifting > RegBoxLifting("BoxLifting")
PhysicsMaterial material
Material of the body&#39;s first shape.
Definition: BodyParamInfo.h:70
RcsGraph * graph
Graph description.