Skip to content
Snippets Groups Projects
sot_loader.cpp 5.96 KiB
Newer Older
/*
 * Copyright 2011,
 * Olivier Stasse,
 *
 * CNRS
 *
 */
/* -------------------------------------------------------------------------- */
/* --- INCLUDES ------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

#include <ros/rate.h>
#include <dynamic_graph_bridge/sot_loader.hh>
#include "dynamic_graph_bridge/ros_init.hh"

// POSIX.1-2001
#include <dlfcn.h>

#include <boost/thread/condition.hpp>

boost::condition_variable cond;

Olivier Stasse's avatar
Olivier Stasse committed
using namespace dynamicgraph::sot;
namespace po = boost::program_options;

Olivier Stasse's avatar
Olivier Stasse committed
struct DataToLog {
  const std::size_t N;
  std::size_t idx, iter;
  std::vector<std::size_t> iters;
  std::vector<double> times;
  std::vector<double> ittimes;

  DataToLog(std::size_t N_)
    : N(N_)
    , idx(0)
    , iter(0)
    , iters(N, 0)
    , times(N, 0)
    , ittimes(N, 0)
  {}

  void record(const double t, const double itt) {
    iters  [idx] = iter;
    times  [idx] = t;
    ittimes[idx] = itt;
    ++idx;
    ++iter;
    if (idx == N) idx = 0;
  }

Olivier Stasse's avatar
Olivier Stasse committed
  void save(const char *prefix) {
    std::ostringstream oss;
    oss << prefix << "-times.log";

    std::ofstream aof(oss.str().c_str());
    if (aof.is_open()) {
      for (std::size_t k = 0; k < N; ++k) {
        aof
          << iters  [(idx + k) % N] << ' '
          << times  [(idx + k) % N] << ' '
          << ittimes[(idx + k) % N] << '\n';
      }
    }
    aof.close();
  }
};
Olivier Stasse's avatar
Olivier Stasse committed
void workThreadLoader(SotLoader *aSotLoader) {
  ros::Rate rate(1000); // 1 kHz
  if (ros::param::has("/sot_controller/dt")) {
    double periodd;
    ros::param::get("/sot_controller/dt", periodd);
    rate = ros::Rate(1/periodd);
Olivier Stasse's avatar
Olivier Stasse committed
  DataToLog dataToLog(5000);
  rate.reset();
  while (ros::ok() && aSotLoader->isDynamicGraphStopped()) {
    rate.sleep();
Olivier Stasse's avatar
Olivier Stasse committed
  }
Olivier Stasse's avatar
Olivier Stasse committed
  ros::NodeHandle nh("/geometric_simu");
  ros::Time timeOrigin = ros::Time::now();
  ros::Time time;
  while (ros::ok() && !aSotLoader->isDynamicGraphStopped()) {
Olivier Stasse's avatar
Olivier Stasse committed
    nh.param<bool>("paused", paused, false);

    if (!paused) {
      time = ros::Time::now();
Olivier Stasse's avatar
Olivier Stasse committed
      aSotLoader->oneIteration();

      ros::Duration d = ros::Time::now() - time;
      dataToLog.record((time - timeOrigin).toSec(), d.toSec());
    rate.sleep();
Olivier Stasse's avatar
Olivier Stasse committed
  }
  dataToLog.save("/tmp/geometric_simu");
  cond.notify_all();
  ros::waitForShutdown();
}

Olivier Stasse's avatar
Olivier Stasse committed
SotLoader::SotLoader()
    : sensorsIn_(),
      controlValues_(),
      angleEncoder_(),
      angleControl_(),
      forces_(),
      torques_(),
      baseAtt_(),
      accelerometer_(3),
      gyrometer_(3),
      thread_() {
  readSotVectorStateParam();
  initPublication();
Joseph Mirabel's avatar
Joseph Mirabel committed

  freeFlyerPose_.header.frame_id = "odom";
  freeFlyerPose_.child_frame_id = "base_link";
Olivier Stasse's avatar
Olivier Stasse committed
SotLoader::~SotLoader() {
  dynamic_graph_stopped_ = true;
  thread_.join();
}

Guilhem Saurel's avatar
Guilhem Saurel committed
void SotLoader::startControlLoop() { thread_ = boost::thread(workThreadLoader, this); }
Olivier Stasse's avatar
Olivier Stasse committed
void SotLoader::initializeRosNode(int argc, char *argv[]) {
  SotLoaderBasic::initializeRosNode(argc, argv);
Olivier Stasse's avatar
Olivier Stasse committed
  // Temporary fix. TODO: where should nbOfJoints_ be initialized from?
  if (ros::param::has("/sot/state_vector_map")) {
    angleEncoder_.resize(nbOfJoints_);
Joseph Mirabel's avatar
Joseph Mirabel committed
    angleControl_.resize(nbOfJoints_);
Olivier Stasse's avatar
Olivier Stasse committed
void SotLoader::fillSensors(map<string, dgs::SensorValues> &sensorsIn) {
  // Update joint values.w
  assert(angleControl_.size() == angleEncoder_.size());

  sensorsIn["joints"].setName("angle");
Guilhem Saurel's avatar
Guilhem Saurel committed
  for (unsigned int i = 0; i < angleControl_.size(); i++) angleEncoder_[i] = angleControl_[i];
Olivier Stasse's avatar
Olivier Stasse committed
  sensorsIn["joints"].setValues(angleEncoder_);
Olivier Stasse's avatar
Olivier Stasse committed
void SotLoader::readControl(map<string, dgs::ControlValues> &controlValues) {
  // Update joint values.
  angleControl_ = controlValues["control"].getValues();
Olivier Stasse's avatar
Olivier Stasse committed
  // Debug
Guilhem Saurel's avatar
Guilhem Saurel committed
  std::map<std::string, dgs::ControlValues>::iterator it = controlValues.begin();
Olivier Stasse's avatar
Olivier Stasse committed
  sotDEBUG(30) << "ControlValues to be broadcasted:" << std::endl;
  for (; it != controlValues.end(); it++) {
    sotDEBUG(30) << it->first << ":";
    std::vector<double> ctrlValues_ = it->second.getValues();
    std::vector<double>::iterator it_d = ctrlValues_.begin();
Olivier Stasse's avatar
Olivier Stasse committed
    for (; it_d != ctrlValues_.end(); it_d++) sotDEBUG(30) << *it_d << " ";
    sotDEBUG(30) << std::endl;
Olivier Stasse's avatar
Olivier Stasse committed
  sotDEBUG(30) << "End ControlValues" << std::endl;
  // Check if the size if coherent with the robot description.
Olivier Stasse's avatar
Olivier Stasse committed
  if (angleControl_.size() != (unsigned int)nbOfJoints_) {
Guilhem Saurel's avatar
Guilhem Saurel committed
    std::cerr << " angleControl_" << angleControl_.size() << " and nbOfJoints" << (unsigned int)nbOfJoints_
              << " are different !" << std::endl;
Olivier Stasse's avatar
Olivier Stasse committed
    exit(-1);
  }
  // Publish the data.
Olivier Stasse's avatar
Olivier Stasse committed
  joint_state_.header.stamp = ros::Time::now();
  for (int i = 0; i < nbOfJoints_; i++) {
    joint_state_.position[i] = angleControl_[i];
  }
  for (unsigned int i = 0; i < parallel_joints_to_state_vector_.size(); i++) {
    joint_state_.position[i + nbOfJoints_] =
Guilhem Saurel's avatar
Guilhem Saurel committed
        coefficient_parallel_joints_[i] * angleControl_[parallel_joints_to_state_vector_[i]];
Olivier Stasse's avatar
Olivier Stasse committed
  }
Olivier Stasse's avatar
Olivier Stasse committed
  // Publish robot pose
  // get the robot pose values
  std::vector<double> poseValue_ = controlValues["baseff"].getValues();

Joseph Mirabel's avatar
Joseph Mirabel committed
  freeFlyerPose_.transform.translation.x = poseValue_[0];
  freeFlyerPose_.transform.translation.y = poseValue_[1];
  freeFlyerPose_.transform.translation.z = poseValue_[2];

  freeFlyerPose_.transform.rotation.w = poseValue_[3];
  freeFlyerPose_.transform.rotation.x = poseValue_[4];
  freeFlyerPose_.transform.rotation.y = poseValue_[5];
  freeFlyerPose_.transform.rotation.z = poseValue_[6];

  freeFlyerPose_.header.stamp = joint_state_.header.stamp;
Olivier Stasse's avatar
Olivier Stasse committed
  // Publish
Joseph Mirabel's avatar
Joseph Mirabel committed
  freeFlyerPublisher_.sendTransform(freeFlyerPose_);
Olivier Stasse's avatar
Olivier Stasse committed
void SotLoader::setup() {
  fillSensors(sensorsIn_);
  sotController_->setupSetSensors(sensorsIn_);
Olivier Stasse's avatar
Olivier Stasse committed
  sotController_->getControl(controlValues_);
  readControl(controlValues_);
Olivier Stasse's avatar
Olivier Stasse committed
void SotLoader::oneIteration() {
  fillSensors(sensorsIn_);
Olivier Stasse's avatar
Olivier Stasse committed
  try {
    sotController_->nominalSetSensors(sensorsIn_);
    sotController_->getControl(controlValues_);
  } catch (std::exception &) {
    throw;
Olivier Stasse's avatar
Olivier Stasse committed
  }

  readControl(controlValues_);
}