Cheetah Software  1.0
Simulation.cpp
Go to the documentation of this file.
1 #include "Simulation.h"
2 #include "Dynamics/Quadruped.h"
3 #include "ParamHandler.hpp"
4 
5 #include <Configuration.h>
7 #include <unistd.h>
8 #include <fstream>
9 
10 // if DISABLE_HIGH_LEVEL_CONTROL is defined, the simulator will run freely,
11 // without trying to connect to a robot
12 //#define DISABLE_HIGH_LEVEL_CONTROL
13 
19  SimulatorControlParameters& params, ControlParameters& userParams)
20  : _simParams(params), _userParams(userParams), _tau(12) {
21  // init parameters
22  printf("[Simulation] Load parameters...\n");
24  .lockMutex(); // we want exclusive access to the simparams at this point
26  printf(
27  "[ERROR] Simulator parameters are not fully initialized. You forgot: "
28  "\n%s\n",
30  throw std::runtime_error("simulator not initialized");
31  }
32 
33  // init LCM
34  if (_simParams.sim_state_lcm) {
35  printf("[Simulation] Setup LCM...\n");
36  _lcm = new lcm::LCM(getLcmUrl(_simParams.sim_lcm_ttl));
37  if (!_lcm->good()) {
38  printf("[ERROR] Failed to set up LCM\n");
39  throw std::runtime_error("lcm bad");
40  }
41  }
42 
43  // init quadruped info
44  printf("[Simulation] Build quadruped...\n");
45  _robot = robot;
46  _quadruped = _robot == RobotType::MINI_CHEETAH ? buildMiniCheetah<double>()
47  : buildCheetah3<double>();
48  printf("[Simulation] Build actuator model...\n");
50  _window = window;
51 
52  // init graphics
53  if (_window) {
54  printf("[Simulation] Setup Cheetah graphics...\n");
55  Vec4<float> truthColor, seColor;
56  truthColor << 0.2, 0.4, 0.2, 0.6;
57  seColor << 0.4, 0.2, 0.2, 0.6;
58  _simRobotID = _robot == RobotType::MINI_CHEETAH ? window->setupMiniCheetah(truthColor, true)
59  : window->setupCheetah3(truthColor, true);
61  ? window->setupMiniCheetah(seColor, false)
62  : window->setupCheetah3(seColor, false);
63  }
64 
65  // init rigid body dynamics
66  printf("[Simulation] Build rigid body model...\n");
69  _simulator =
70  new DynamicsSimulator<double>(_model, (bool)_simParams.use_spring_damper);
72 
73  DVec<double> zero12(12);
74  for (u32 i = 0; i < 12; i++) {
75  zero12[i] = 0.;
76  }
77 
78  // set some sane defaults:
79  _tau = zero12;
80  _robotControllerState.q = zero12;
81  _robotControllerState.qd = zero12;
84  ori::coordinateRotation(CoordinateAxis::Z, 0.));
85  // Mini Cheetah
86  x0.bodyPosition.setZero();
87  x0.bodyVelocity.setZero();
88  x0.q = zero12;
89  x0.qd = zero12;
90 
91  // Mini Cheetah Initial Posture
92  // x0.bodyPosition[2] = -0.49;
93  // Cheetah 3
94  // x0.bodyPosition[2] = -0.34;
95  // x0.q[0] = -0.807;
96  // x0.q[1] = -1.2;
97  // x0.q[2] = 2.4;
98 
99  // x0.q[3] = 0.807;
100  // x0.q[4] = -1.2;
101  // x0.q[5] = 2.4;
102 
103  // x0.q[6] = -0.807;
104  // x0.q[7] = -1.2;
105  // x0.q[8] = 2.4;
106 
107  // x0.q[9] = 0.807;
108  // x0.q[10] = -1.2;
109  // x0.q[11] = 2.4;
110 
111  // Initial (Mini Cheetah stand)
112  // x0.bodyPosition[2] = -0.185;
113  // Cheetah 3
114  // x0.bodyPosition[2] = -0.075;
115 
116  // x0.q[0] = -0.03;
117  // x0.q[1] = -0.79;
118  // x0.q[2] = 1.715;
119 
120  // x0.q[3] = 0.03;
121  // x0.q[4] = -0.79;
122  // x0.q[5] = 1.715;
123 
124  // x0.q[6] = -0.03;
125  // x0.q[7] = -0.72;
126  // x0.q[8] = 1.715;
127 
128  // x0.q[9] = 0.03;
129  // x0.q[10] = -0.72;
130  // x0.q[11] = 1.715;
131 
132  // Cheetah lies on the ground
133  //x0.bodyPosition[2] = -0.45;
134  x0.bodyPosition[2] = 0.05;
135  x0.q[0] = -0.7;
136  x0.q[1] = 1.;
137  x0.q[2] = 2.715;
138 
139  x0.q[3] = 0.7;
140  x0.q[4] = 1.;
141  x0.q[5] = 2.715;
142 
143  x0.q[6] = -0.7;
144  x0.q[7] = -1.0;
145  x0.q[8] = -2.715;
146 
147  x0.q[9] = 0.7;
148  x0.q[10] = -1.0;
149  x0.q[11] = -2.715;
150 
151 
152  setRobotState(x0);
154 
155  printf("[Simulation] Setup low-level control...\n");
156  // init spine:
158  for (int leg = 0; leg < 4; leg++) {
160  _spineBoards[leg].data = &_spiData;
161  _spineBoards[leg].cmd = &_spiCommand;
162  _spineBoards[leg].resetData();
163  _spineBoards[leg].resetCommand();
164  }
165  } else if (_robot == RobotType::CHEETAH_3) {
166  // init ti board
167  for (int leg = 0; leg < 4; leg++) {
175  }
176  } else {
177  assert(false);
178  }
179 
180  // init shared memory
181  printf("[Simulation] Setup shared memory...\n");
183  _sharedMemory().init();
184 
185  // shared memory fields:
186  _sharedMemory().simToRobot.robotType = _robot;
188  &_sharedMemory().robotToSim.visualizationData;
189 
190  // load robot control parameters
191  printf("[Simulation] Load control parameters...\n");
195  } else if (_robot == RobotType::CHEETAH_3) {
198  } else {
199  assert(false);
200  }
201 
203  printf("Not all robot control parameters were initialized. Missing:\n%s\n",
205  throw std::runtime_error("not all parameters initialized from ini file");
206  }
207 
208  // init IMU simulator
209  printf("[Simulation] Setup IMU simulator...\n");
211 
213  printf("[Simulation] Ready!\n");
214 }
215 
216 void Simulation::sendControlParameter(const std::string& name,
217  ControlParameterValue value,
218  ControlParameterValueKind kind, bool isUser) {
219  ControlParameterRequest& request =
220  _sharedMemory().simToRobot.controlParameterRequest;
221  ControlParameterResponse& response =
222  _sharedMemory().robotToSim.controlParameterResponse;
223 
224  // first check no pending message
225  assert(request.requestNumber == response.requestNumber);
226 
227  // new message
228  request.requestNumber++;
229 
230  // message data
232  strcpy(request.name, name.c_str());
233  request.value = value;
234  request.parameterKind = kind;
235  printf("%s\n", request.toString().c_str());
236 
237  // run robot:
238  _robotMutex.lock();
240  _sharedMemory().simulatorIsDone();
241 
242  // wait for robot code to finish
243  if (_sharedMemory().waitForRobotWithTimeout()) {
244  } else {
245  _wantStop = true;
246  _running = false;
247  _connected = false;
248  printf(
249  "[ERROR] Timed out waiting for message from robot! Did it crash?\n");
250  request.requestNumber = response.requestNumber;
251  _robotMutex.unlock();
252  return;
253  }
254 
255  //_sharedMemory().waitForRobot();
256  _robotMutex.unlock();
257 
258  // verify response is good
259  assert(response.requestNumber == request.requestNumber);
260  assert(response.parameterKind == request.parameterKind);
261  assert(std::string(response.name) == request.name);
262 }
263 
269  // connect to robot
270  _robotMutex.lock();
271  _sharedMemory().simToRobot.mode = SimulatorMode::DO_NOTHING;
272  _sharedMemory().simulatorIsDone();
273 
274  printf("[Simulation] Waiting for robot...\n");
275 
276  // this loop will check to see if the robot is connected at 10 Hz
277  // doing this in a loop allows us to click the "stop" button in the GUI
278  // and escape from here before the robot code connects, if needed
279  while (!_sharedMemory().tryWaitForRobot()) {
280  if (_wantStop) {
281  return;
282  }
283  usleep(100000);
284  }
285  printf("Success! the robot is alive\n");
286  _connected = true;
287  _robotMutex.unlock();
288 
289  // send all control parameters
290  printf("[Simulation] Send robot control parameters to robot...\n");
291  for (auto& kv : _robotParams.collection._map) {
292  sendControlParameter(kv.first, kv.second->get(kv.second->_kind),
293  kv.second->_kind, false);
294  }
295 
296  for (auto& kv : _userParams.collection._map) {
297  sendControlParameter(kv.first, kv.second->get(kv.second->_kind),
298  kv.second->_kind, true);
299  }
300 }
301 
305 void Simulation::step(double dt, double dtLowLevelControl,
306  double dtHighLevelControl) {
307  // Low level control (if needed)
309  lowLevelControl();
311  }
312 
313  // High level control
315 #ifndef DISABLE_HIGH_LEVEL_CONTROL
317 #endif
319  _timeOfNextHighLevelControl + dtHighLevelControl;
320  }
321 
322  // actuator model:
324  for (int leg = 0; leg < 4; leg++) {
325  for (int joint = 0; joint < 3; joint++) {
326  _tau[leg * 3 + joint] = _actuatorModels[joint].getTorque(
327  _spineBoards[leg].torque_out[joint],
328  _simulator->getState().qd[leg * 3 + joint]);
329  }
330  }
331  } else if (_robot == RobotType::CHEETAH_3) {
332  for (int leg = 0; leg < 4; leg++) {
333  for (int joint = 0; joint < 3; joint++) {
334  _tau[leg * 3 + joint] = _actuatorModels[joint].getTorque(
335  _tiBoards[leg].data->tau_des[joint],
336  _simulator->getState().qd[leg * 3 + joint]);
337  }
338  }
339  } else {
340  assert(false);
341  }
342 
343  // dynamics
344  _currentSimTime += dt;
345 
346  // Set Homing Information
348  homing.active_flag = _simParams.go_home;
349  homing.position = _simParams.home_pos;
350  homing.rpy = _simParams.home_rpy;
351  homing.kp_lin = _simParams.home_kp_lin;
352  homing.kd_lin = _simParams.home_kd_lin;
353  homing.kp_ang = _simParams.home_kp_ang;
354  homing.kd_ang = _simParams.home_kd_ang;
355  _simulator->setHoming(homing);
356 
357  _simulator->step(dt, _tau, _simParams.floor_kp, _simParams.floor_kd);
358 }
359 
362  // update spine board data:
363  for (int leg = 0; leg < 4; leg++) {
364  _spiData.q_abad[leg] = _simulator->getState().q[leg * 3 + 0];
365  _spiData.q_hip[leg] = _simulator->getState().q[leg * 3 + 1];
366  _spiData.q_knee[leg] = _simulator->getState().q[leg * 3 + 2];
367 
368  _spiData.qd_abad[leg] = _simulator->getState().qd[leg * 3 + 0];
369  _spiData.qd_hip[leg] = _simulator->getState().qd[leg * 3 + 1];
370  _spiData.qd_knee[leg] = _simulator->getState().qd[leg * 3 + 2];
371  }
372 
373  // run spine board control:
374  for (auto& spineBoard : _spineBoards) {
375  spineBoard.run();
376  }
377 
378  } else if (_robot == RobotType::CHEETAH_3) {
379  // update data
380  for (int leg = 0; leg < 4; leg++) {
381  for (int joint = 0; joint < 3; joint++) {
382  _tiBoards[leg].data->q[joint] =
383  _simulator->getState().q[leg * 3 + joint];
384  _tiBoards[leg].data->dq[joint] =
385  _simulator->getState().qd[leg * 3 + joint];
386  }
387  }
388 
389  // run control
390  for (auto& tiBoard : _tiBoards) {
391  tiBoard.run_ti_board_iteration();
392  }
393  } else {
394  assert(false);
395  }
396 }
397 
399  // send joystick data to robot:
400  _sharedMemory().simToRobot.gamepadCommand = _window->getDriverCommand();
401  _sharedMemory().simToRobot.gamepadCommand.applyDeadband(
402  _simParams.game_controller_deadband);
403 
404  // send IMU data to robot:
407  _sharedMemory().simToRobot.cheaterState);
408 
411  &_sharedMemory().simToRobot.vectorNav);
412 
413 
414  // send leg data to robot
416  _sharedMemory().simToRobot.spiData = _spiData;
417  } else if (_robot == RobotType::CHEETAH_3) {
418  for (int i = 0; i < 4; i++) {
419  _sharedMemory().simToRobot.tiBoardData[i] = *_tiBoards[i].data;
420  }
421  } else {
422  assert(false);
423  }
424 
425  // signal to the robot that it can start running
426  // the _robotMutex is used to prevent qt (which runs in its own thread) from
427  // sending a control parameter while the robot code is already running.
428  _robotMutex.lock();
429  _sharedMemory().simToRobot.mode = SimulatorMode::RUN_CONTROLLER;
430  _sharedMemory().simulatorIsDone();
431 
432  // wait for robot code to finish (and send LCM while waiting)
433  if (_lcm) {
434  buildLcmMessage();
435  _lcm->publish(SIM_LCM_NAME, &_simLCM);
436  }
437 
438  // first make sure we haven't killed the robot code
439  if (_wantStop) return;
440 
441  // next try waiting at most 1 second:
442  if (_sharedMemory().waitForRobotWithTimeout()) {
443  } else {
444  _wantStop = true;
445  _running = false;
446  _connected = false;
447  printf(
448  "[ERROR] Timed out waiting for message from robot! Did it crash?\n");
449  _robotMutex.unlock();
450  return;
451  }
452  _robotMutex.unlock();
453 
454  // update
456  _spiCommand = _sharedMemory().robotToSim.spiCommand;
457 
458  // pretty_print(_spiCommand.q_des_abad, "q des abad", 4);
459  // pretty_print(_spiCommand.q_des_hip, "q des hip", 4);
460  // pretty_print(_spiCommand.q_des_knee, "q des knee", 4);
461  } else if (_robot == RobotType::CHEETAH_3) {
462  for (int i = 0; i < 4; i++) {
463  _tiBoards[i].command = _sharedMemory().robotToSim.tiBoardCommand[i];
464  }
465  } else {
466  assert(false);
467  }
468 
470 }
471 
473  _simLCM.time = _currentSimTime;
474  _simLCM.timesteps = _highLevelIterations;
475  auto& state = _simulator->getState();
476  auto& dstate = _simulator->getDState();
477 
478  Vec3<double> rpy = ori::quatToRPY(state.bodyOrientation);
479  RotMat<double> Rbody = ori::quaternionToRotationMatrix(state.bodyOrientation);
480  Vec3<double> omega = Rbody.transpose() * state.bodyVelocity.head<3>();
481  Vec3<double> v = Rbody.transpose() * state.bodyVelocity.tail<3>();
482 
483  for (size_t i = 0; i < 4; i++) {
484  _simLCM.quat[i] = state.bodyOrientation[i];
485  }
486 
487  for (size_t i = 0; i < 3; i++) {
488  _simLCM.vb[i] = state.bodyVelocity[i + 3]; // linear velocity in body frame
489  _simLCM.rpy[i] = rpy[i];
490  for (size_t j = 0; j < 3; j++) {
491  _simLCM.R[i][j] = Rbody(i, j);
492  }
493  _simLCM.omegab[i] = state.bodyVelocity[i];
494  _simLCM.omega[i] = omega[i];
495  _simLCM.p[i] = state.bodyPosition[i];
496  _simLCM.v[i] = v[i];
497  _simLCM.vbd[i] = dstate.dBodyVelocity[i + 3];
498  }
499 
500  for (size_t leg = 0; leg < 4; leg++) {
501  for (size_t joint = 0; joint < 3; joint++) {
502  _simLCM.q[leg][joint] = state.q[leg * 3 + joint];
503  _simLCM.qd[leg][joint] = state.qd[leg * 3 + joint];
504  _simLCM.qdd[leg][joint] = dstate.qdd[leg * 3 + joint];
505  _simLCM.tau[leg][joint] = _tau[leg * 3 + joint];
506  size_t gcID = _simulator->getModel()._footIndicesGC.at(leg);
507  _simLCM.p_foot[leg][joint] = _simulator->getModel()._pGC.at(gcID)[joint];
508  _simLCM.f_foot[leg][joint] = _simulator->getContactForce(gcID)[joint];
509  }
510  }
511 }
512 
520 void Simulation::addCollisionPlane(double mu, double resti, double height,
521  double sizeX, double sizeY, double checkerX,
522  double checkerY, bool addToWindow) {
523  _simulator->addCollisionPlane(mu, resti, height);
524  if (addToWindow && _window) {
526  Checkerboard checker(sizeX, sizeY, checkerX, checkerY);
527 
528  size_t graphicsID = _window->_drawList.addCheckerboard(checker);
530  _window->_drawList.updateCheckerboard(height, graphicsID);
532  }
533 }
534 
546 void Simulation::addCollisionBox(double mu, double resti, double depth,
547  double width, double height,
548  const Vec3<double>& pos,
549  const Mat3<double>& ori, bool addToWindow,
550  bool transparent) {
551  _simulator->addCollisionBox(mu, resti, depth, width, height, pos, ori);
552  if (addToWindow && _window) {
554  _window->_drawList.addBox(depth, width, height, pos, ori, transparent);
556  }
557 }
558 
559 void Simulation::addCollisionMesh(double mu, double resti, double grid_size,
560  const Vec3<double>& left_corner_loc,
561  const DMat<double>& height_map,
562  bool addToWindow, bool transparent) {
563  _simulator->addCollisionMesh(mu, resti, grid_size, left_corner_loc,
564  height_map);
565  if (addToWindow && _window) {
567  _window->_drawList.addMesh(grid_size, left_corner_loc, height_map,
568  transparent);
570  }
571 }
572 
579 void Simulation::runAtSpeed(bool graphics) {
580  firstRun(); // load the control parameters
581 
582  // if we requested to stop, stop.
583  if (_wantStop) return;
584  assert(!_running);
585  _running = true;
586  Timer frameTimer;
587  Timer freeRunTimer;
588  u64 desiredSteps = 0;
589  u64 steps = 0;
590 
591  double frameTime = 1. / 60.;
592  double lastSimTime = 0;
593 
594  printf(
595  "[Simulator] Starting run loop (dt %f, dt-low-level %f, dt-high-level %f "
596  "speed %f graphics %d)...\n",
597  _simParams.dynamics_dt, _simParams.low_level_dt, _simParams.high_level_dt,
598  _simParams.simulation_speed, graphics);
599 
600  while (_running) {
601  double dt = _simParams.dynamics_dt;
602  double dtLowLevelControl = _simParams.low_level_dt;
603  double dtHighLevelControl = _simParams.high_level_dt;
604  _desiredSimSpeed = (_window && _window->wantTurbo()) ? 100.f : _simParams.simulation_speed;
605  u64 nStepsPerFrame = (u64)(((1. / 60.) / dt) * _desiredSimSpeed);
606  if (!_window->IsPaused() && steps < desiredSteps) {
608  step(dt, dtLowLevelControl, dtHighLevelControl);
610  steps++;
611  } else {
612  double timeRemaining = frameTime - frameTimer.getSeconds();
613  if (timeRemaining > 0) {
614  usleep((u32)(timeRemaining * 1e6));
615  }
616  }
617  if (frameTimer.getSeconds() > frameTime) {
618  double realElapsedTime = frameTimer.getSeconds();
619  frameTimer.start();
620  if (graphics && _window) {
621  double simRate = (_currentSimTime - lastSimTime) / realElapsedTime;
622  lastSimTime = _currentSimTime;
623  sprintf(_window->infoString,
624  "[Simulation Run %5.2fx]\n"
625  "real-time: %8.3f\n"
626  "sim-time: %8.3f\n"
627  "rate: %8.3f\n",
628  _desiredSimSpeed, freeRunTimer.getSeconds(), _currentSimTime,
629  simRate);
630  updateGraphics();
631  }
632  if (!_window->IsPaused() && (desiredSteps - steps) < nStepsPerFrame)
633  desiredSteps += nStepsPerFrame;
634  }
635  }
636 }
637 
638 void Simulation::loadTerrainFile(const std::string& terrainFileName,
639  bool addGraphics) {
640  printf("load terrain %s\n", terrainFileName.c_str());
641  ParamHandler paramHandler(terrainFileName);
642 
643  if (!paramHandler.fileOpenedSuccessfully()) {
644  printf("[ERROR] could not open yaml file for terrain\n");
645  throw std::runtime_error("yaml bad");
646  }
647 
648  std::vector<std::string> keys = paramHandler.getKeys();
649 
650  for (auto& key : keys) {
651  auto load = [&](double& val, const std::string& name) {
652  if (!paramHandler.getValue<double>(key, name, val))
653  throw std::runtime_error("terrain read bad: " + key + " " + name);
654  };
655 
656  auto loadVec = [&](double& val, const std::string& name, size_t idx) {
657  std::vector<double> v;
658  if (!paramHandler.getVector<double>(key, name, v))
659  throw std::runtime_error("terrain read bad: " + key + " " + name);
660  val = v.at(idx);
661  };
662 
663  auto loadArray = [&](double* val, const std::string& name, size_t idx) {
664  std::vector<double> v;
665  if (!paramHandler.getVector<double>(key, name, v))
666  throw std::runtime_error("terrain read bad: " + key + " " + name);
667  assert(v.size() == idx);
668  for (size_t i = 0; i < idx; i++) val[i] = v[i];
669  };
670 
671  printf("terrain element %s\n", key.c_str());
672  std::string typeName;
673  paramHandler.getString(key, "type", typeName);
674  if (typeName == "infinite-plane") {
675  double mu, resti, height, gfxX, gfxY, checkerX, checkerY;
676  load(mu, "mu");
677  load(resti, "restitution");
678  load(height, "height");
679  loadVec(gfxX, "graphicsSize", 0);
680  loadVec(gfxY, "graphicsSize", 1);
681  loadVec(checkerX, "checkers", 0);
682  loadVec(checkerY, "checkers", 1);
683  addCollisionPlane(mu, resti, height, gfxX, gfxY, checkerX, checkerY,
684  addGraphics);
685  } else if (typeName == "box") {
686  double mu, resti, depth, width, height, transparent;
687  double pos[3];
688  double ori[3];
689  load(mu, "mu");
690  load(resti, "restitution");
691  load(depth, "depth");
692  load(width, "width");
693  load(height, "height");
694  loadArray(pos, "position", 3);
695  loadArray(ori, "orientation", 3);
696  load(transparent, "transparent");
697 
699  R_box.transposeInPlace(); // collisionBox uses "rotation" matrix instead
700  // of "transformation"
701  addCollisionBox(mu, resti, depth, width, height, Vec3<double>(pos), R_box,
702  addGraphics, transparent != 0.);
703  } else if (typeName == "stairs") {
704  double mu, resti, rise, run, stepsDouble, width, transparent;
705  double pos[3];
706  double ori[3];
707  load(mu, "mu");
708  load(resti, "restitution");
709  load(rise, "rise");
710  load(width, "width");
711  load(run, "run");
712  load(stepsDouble, "steps");
713  loadArray(pos, "position", 3);
714  loadArray(ori, "orientation", 3);
715  load(transparent, "transparent");
716 
718  Vec3<double> pOff(pos);
719  R.transposeInPlace(); // "graphics" rotation matrix
720 
721  size_t steps = (size_t)stepsDouble;
722 
723  double heightOffset = rise / 2;
724  double runOffset = run / 2;
725  for (size_t step = 0; step < steps; step++) {
726  Vec3<double> p(runOffset, 0, heightOffset);
727  p = R * p + pOff;
728 
729  addCollisionBox(mu, resti, run, width, heightOffset * 2, p, R,
730  addGraphics, transparent != 0.);
731 
732  heightOffset += rise / 2;
733  runOffset += run;
734  }
735  } else if (typeName == "mesh") {
736  double mu, resti, transparent, grid;
737  Vec3<double> left_corner;
738  std::vector<std::vector<double> > height_map_2d;
739  load(mu, "mu");
740  load(resti, "restitution");
741  load(transparent, "transparent");
742  load(grid, "grid");
743  loadVec(left_corner[0], "left_corner_loc", 0);
744  loadVec(left_corner[1], "left_corner_loc", 1);
745  loadVec(left_corner[2], "left_corner_loc", 2);
746 
747  int x_len(0);
748  int y_len(0);
749  bool file_input(false);
750  paramHandler.getBoolean(key, "heightmap_file", file_input);
751  if (file_input) {
752  // Read from text file
753  std::string file_name;
754  paramHandler.getString(key, "heightmap_file_name", file_name);
755  std::ifstream f_height;
756  f_height.open(THIS_COM "/config/" + file_name);
757  if (!f_height.good()) {
758  std::cout << "file reading error: "
759  << THIS_COM "../config/" + file_name << std::endl;
760  }
761  int i(0);
762  int j(0);
763  double tmp;
764 
765  std::string line;
766  std::vector<double> height_map_vec;
767  while (getline(f_height, line)) {
768  std::istringstream iss(line);
769  j = 0;
770  while (iss >> tmp) {
771  height_map_vec.push_back(tmp);
772  ++j;
773  }
774  y_len = j;
775  height_map_2d.push_back(height_map_vec);
776  height_map_vec.clear();
777  // printf("y len: %d\n", y_len);
778  ++i;
779  }
780  x_len = i;
781 
782  } else {
783  paramHandler.get2DArray(key, "height_map", height_map_2d);
784  x_len = height_map_2d.size();
785  y_len = height_map_2d[0].size();
786  // printf("x, y len: %d, %d\n", x_len, y_len);
787  }
788 
789  DMat<double> height_map(x_len, y_len);
790  for (int i(0); i < x_len; ++i) {
791  for (int j(0); j < y_len; ++j) {
792  height_map(i, j) = height_map_2d[i][j];
793  // printf("height (%d, %d) : %f\n", i, j, height_map(i,j) );
794  }
795  }
796  addCollisionMesh(mu, resti, grid, left_corner, height_map, addGraphics,
797  transparent != 0.);
798 
799  } else {
800  throw std::runtime_error("unknown terrain " + typeName);
801  }
802  }
803 }
804 
807  _sharedMemory().robotToSim.mainCheetahVisualization.quat.cast<double>();
809  _sharedMemory().robotToSim.mainCheetahVisualization.p.cast<double>();
810  for (int i = 0; i < 12; i++)
812  _sharedMemory().robotToSim.mainCheetahVisualization.q[i];
814  _robotDataSimulator->forwardKinematics(); // calc all body positions
817  _controllerRobotID, false);
819  _window->update();
820 }
void resetData()
Definition: SpineBoard.cpp:17
Vec3< T > bodyPosition
float q_knee[4]
Definition: SpineBoard.h:37
void addCollisionBox(double mu, double resti, double depth, double width, double height, const Vec3< double > &pos, const Mat3< double > &ori, bool addToWindow=true, bool transparent=true)
Definition: Simulation.cpp:546
void addMesh(double grid_size, const Vec3< double > &left_corner, const DMat< double > &height_map, bool transparent)
Definition: DrawList.cpp:338
VisualizationData * _visualizationData
Definition: DrawList.h:51
void runAtSpeed(bool graphics=true)
Definition: Simulation.cpp:579
void step(double dt, double dtLowLevelControl, double dtHighLevelControl)
Definition: Simulation.cpp:305
void forwardKinematics()
Do forward kinematics for feet.
ControlParameterCollection collection
SVec< T > bodyVelocity
Definition: Timer.h:12
Mat3< T > coordinateRotation(CoordinateAxis axis, T theta)
ControlParameterValueKind parameterKind
EIGEN_MAKE_ALIGNED_OPERATOR_NEW Vec3< T > position
SpiCommand * cmd
Definition: SpineBoard.h:52
ControlParameterValueKind
void updateCheaterState(const FBModelState< T > &robotState, const FBModelStateDerivative< T > &robotStateD, CheaterState< T > &state)
Mat3< typename T::Scalar > rpyToRotMat(const Eigen::MatrixBase< T > &v)
T _hipLinkLength
Definition: Quadruped.h:62
Main simulation class.
std::map< std::string, ControlParameter * > _map
void addCollisionMesh(double mu, double resti, double grid_size, const Vec3< double > &left_corner_loc, const DMat< double > &height_map, bool addToWindow=true, bool transparent=true)
Definition: Simulation.cpp:559
std::vector< ActuatorModel< double > > _actuatorModels
Definition: Simulation.h:135
typename Eigen::Matrix< T, 3, 3 > Mat3
Definition: cppTypes.h:54
void highLevelControl()
Definition: Simulation.cpp:398
Data structure containing parameters for quadruped robot.
bool _connected
Definition: Simulation.h:143
#define MINI_CHEETAH_DEFAULT_PARAMETERS
typename Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > DMat
Definition: cppTypes.h:106
void updateGraphics()
Definition: Simulation.cpp:805
size_t setupMiniCheetah(Vec4< float > color, bool useOld)
Definition: Graphics3D.cpp:122
std::mutex _robotMutex
Definition: Simulation.h:119
void lowLevelControl()
Definition: Simulation.cpp:360
typename Eigen::Matrix< T, 3, 1 > Vec3
Definition: cppTypes.h:26
void start()
Definition: Timer.h:16
TI_BoardControl _tiBoards[4]
Definition: Simulation.h:139
Graphics3D * _window
Definition: Simulation.h:127
ControlParameterRequestKind requestKind
const Vec3< T > & getContactForce(size_t idx)
SharedMemoryObject< SimulatorSyncronizedMessage > _sharedMemory
Definition: Simulation.h:120
DynamicsSimulator< double > * _robotDataSimulator
Definition: Simulation.h:134
T _kneeLinkLength
Definition: Quadruped.h:62
#define SIM_LCM_NAME
Definition: Simulation.h:31
float q_hip[4]
Definition: SpineBoard.h:36
void firstRun()
Definition: Simulation.cpp:268
void updateRobotFromModel(DynamicsSimulator< T > &model, size_t id, bool updateOrigin=false)
Definition: DrawList.h:170
void init(float side_sign, s32 board)
Definition: SpineBoard.cpp:8
void loadTerrainFile(const std::string &terrainFileName, bool addGraphics=true)
Definition: Simulation.cpp:638
bool IsPaused()
Definition: Graphics3D.h:56
DVec< double > _tau
Definition: Simulation.h:132
void setState(const FBModelState< T > &state)
RobotControlParameters _robotParams
Definition: Simulation.h:124
char name[CONTROL_PARAMETER_MAXIMUM_NAME_LENGTH]
void set_link_lengths(float l1, float l2, float l3)
std::string getLcmUrl(s64 ttl)
Definition: utilities.cpp:32
size_t _simRobotID
Definition: Simulation.h:126
void reset_ti_board_command()
size_t setupCheetah3(Vec4< float > color, bool useOld)
Definition: Graphics3D.cpp:117
bool _running
Definition: Simulation.h:142
void addBox(double depth, double width, double height, const Vec3< double > &pos, const Mat3< double > &ori, bool transparent)
Definition: DrawList.cpp:288
std::string getConfigDirectoryPath()
Definition: utilities.cpp:30
void addCollisionPlane(double mu, double resti, double height, double sizeX=20, double sizeY=20, double checkerX=40, double checkerY=40, bool addToWindow=true)
Definition: Simulation.cpp:520
ControlParameterValueKind parameterKind
SpiData _spiData
Definition: Simulation.h:137
void addCollisionMesh(T mu, T rest, T grid_size, const Vec3< T > &left_corner_loc, const DMat< T > &height_map)
Quadruped< double > _quadruped
Definition: Simulation.h:128
#define DEVELOPMENT_SIMULATOR_SHARED_MEMORY_NAME
Definition: SharedMemory.h:21
void buildLcmMessage()
Definition: Simulation.cpp:472
uint32_t u32
Definition: cTypes.h:18
void setRobotState(FBModelState< double > &state)
Definition: Simulation.h:48
double getSeconds()
Definition: Timer.h:27
double _timeOfNextLowLevelControl
Definition: Simulation.h:147
bool createNew(const std::string &name, bool allowOverwrite=false)
Definition: SharedMemory.h:125
s64 _highLevelIterations
Definition: Simulation.h:149
void updateVectornav(const FBModelState< T > &robotState, const FBModelStateDerivative< T > &robotStateD, VectorNavData *data)
Vec3< typename T::Scalar > quatToRPY(const Eigen::MatrixBase< T > &q)
SpiCommand _spiCommand
Definition: Simulation.h:136
SpineBoard _spineBoards[4]
Definition: Simulation.h:138
void setHoming(const RobotHomingInfo< T > &homing)
RobotType _robot
Definition: Simulation.h:140
void init(float side_sign)
TiBoardData * data
SpiData * data
Definition: SpineBoard.h:53
ControlParameters & _userParams
Definition: Simulation.h:123
simulator_lcmt _simLCM
Definition: Simulation.h:150
SimulatorControlParameters & _simParams
Definition: Simulation.h:122
Code to read the Logitech F310 Game Controller Creates a DriverCommand object to be sent to the robot...
#define CHEETAH_3_DEFAULT_PARAMETERS
float q_abad[4]
Definition: SpineBoard.h:35
EIGEN_MAKE_ALIGNED_OPERATOR_NEW Simulation(RobotType robot, Graphics3D *window, SimulatorControlParameters &params, ControlParameters &userParams)
Definition: Simulation.cpp:18
FloatingBaseModel< double > _model
Definition: Simulation.h:130
Quat< typename T::Scalar > rotationMatrixToQuaternion(const Eigen::MatrixBase< T > &r1)
typename Eigen::Matrix< T, 4, 1 > Vec4
Definition: cppTypes.h:30
float qd_abad[4]
Definition: SpineBoard.h:38
char name[CONTROL_PARAMETER_MAXIMUM_NAME_LENGTH]
void step(T dt, const DVec< T > &tau, T kp, T kd)
Initialize simulator with given model.
void buildDrawList()
Definition: DrawList.cpp:266
GamepadCommand & getDriverCommand()
Definition: Graphics3D.h:52
const FBModelState< T > & getState() const
void updateCheckerboard(T height, size_t id)
Definition: DrawList.h:229
size_t _controllerRobotID
Definition: Simulation.h:126
void addCollisionPlane(T mu, T rest, T height)
T _abadLinkLength
Definition: Quadruped.h:62
vector< Vec3< T > > _pGC
double _desiredSimSpeed
Definition: Simulation.h:145
vector< uint64_t > _footIndicesGC
const FBModelStateDerivative< T > & getDState() const
TiBoardCommand command
uint64_t u64
Definition: cTypes.h:17
DynamicsSimulator< double > * _simulator
Definition: Simulation.h:133
typename Eigen::Matrix< T, Eigen::Dynamic, 1 > DVec
Definition: cppTypes.h:102
bool _wantStop
Definition: Simulation.h:144
RobotType
Definition: cppTypes.h:120
void lockGfxMutex()
Definition: Graphics3D.h:43
double _currentSimTime
Definition: Simulation.h:146
ImuSimulator< double > * _imuSimulator
Definition: Simulation.h:121
void updateAdditionalInfo(DynamicsSimulator< T > &model)
Definition: DrawList.h:191
Mat3< typename T::Scalar > quaternionToRotationMatrix(const Eigen::MatrixBase< T > &q)
void run_ti_board_iteration()
std::vector< ActuatorModel< T > > buildActuatorModels()
Definition: Quadruped.cpp:225
FBModelState< double > _robotControllerState
Definition: Simulation.h:129
void unlockGfxMutex()
Definition: Graphics3D.h:45
void initializeFromYamlFile(const std::string &path)
const FloatingBaseModel< T > & getModel()
double _timeOfNextHighLevelControl
Definition: Simulation.h:148
void resetCommand()
Definition: SpineBoard.cpp:35
typename Eigen::Matrix< T, 3, 3 > RotMat
Definition: cppTypes.h:18
void sendControlParameter(const std::string &name, ControlParameterValue value, ControlParameterValueKind kind, bool isUser)
Definition: Simulation.cpp:216
float qd_hip[4]
Definition: SpineBoard.h:39
EIGEN_MAKE_ALIGNED_OPERATOR_NEW Quat< T > bodyOrientation
std::string generateUnitializedList()
size_t addCheckerboard(Checkerboard &checkerBoard)
Definition: DrawList.cpp:215
FloatingBaseModel< T > buildModel()
Definition: Quadruped.cpp:113
DrawList _drawList
Definition: Graphics3D.h:49
void addCollisionBox(T mu, T rest, T depth, T width, T height, const Vec3< T > &pos, const Mat3< T > &ori)
FloatingBaseModel< double > _robotDataModel
Definition: Simulation.h:131
MX f(const MX &x, const MX &u)
char infoString[200]
Definition: Graphics3D.h:50
bool wantTurbo()
Definition: Graphics3D.h:57
lcm::LCM * _lcm
Definition: Simulation.h:141
float qd_knee[4]
Definition: SpineBoard.h:40