Skip to content
Snippets Groups Projects
robot_model.cpp 4.62 KiB
Newer Older
#include "robot_model.hh"
#include <dynamic-graph/all-commands.h>
Thomas Moulard's avatar
Thomas Moulard committed
#include <dynamic-graph/factory.h>
#include <pinocchio/multibody/parser/urdf.hpp>
#include <pinocchio/multibody/model.hpp>
Thomas Moulard's avatar
Thomas Moulard committed

#include "dynamic_graph_bridge/ros_init.hh"

#include <ros/package.h>

Olivier Stasse's avatar
Olivier Stasse committed
namespace dynamicgraph {
RosRobotModel::RosRobotModel(const std::string& name)
Olivier Stasse's avatar
Olivier Stasse committed
    : Dynamic(name), jointsParameterName_("jrl_map"), ns_("sot_controller") {
  std::string docstring;

  docstring =
      "\n"
      "  Load the robot model from the parameter server.\n"
      "\n"
      "  This is the recommended method.\n"
      "\n";
  addCommand("loadFromParameterServer",
Guilhem Saurel's avatar
Guilhem Saurel committed
             command::makeCommandVoid0(*this, &RosRobotModel::loadFromParameterServer, docstring));
Olivier Stasse's avatar
Olivier Stasse committed

  docstring =
      "\n"
      "  Load the robot model from an URDF file.\n"
      "\n";
Guilhem Saurel's avatar
Guilhem Saurel committed
  addCommand("loadUrdf", command::makeCommandVoid1(*this, &RosRobotModel::loadUrdf, docstring));
Olivier Stasse's avatar
Olivier Stasse committed

  docstring =
      "\n"
      "  Set the controller namespace."
      "\n";
Guilhem Saurel's avatar
Guilhem Saurel committed
  addCommand("setNamespace", command::makeCommandVoid1(*this, &RosRobotModel::setNamespace, docstring));
Olivier Stasse's avatar
Olivier Stasse committed

  docstring =
      "\n"
      "  Get current configuration of the robot.\n"
      "\n";
Guilhem Saurel's avatar
Guilhem Saurel committed
  addCommand("curConf", new command::Getter<RosRobotModel, Vector>(*this, &RosRobotModel::curConf, docstring));
Olivier Stasse's avatar
Olivier Stasse committed

  docstring =
      "\n"
      "  Maps a link name in the URDF parser to actual robot link name.\n"
      "\n";
Guilhem Saurel's avatar
Guilhem Saurel committed
  addCommand("addJointMapping", command::makeCommandVoid2(*this, &RosRobotModel::addJointMapping, docstring));
Olivier Stasse's avatar
Olivier Stasse committed
RosRobotModel::~RosRobotModel() {}
Olivier Stasse's avatar
Olivier Stasse committed
void RosRobotModel::loadUrdf(const std::string& filename) {
  rosInit(false);
  m_model = se3::urdf::buildModel(filename);
  this->m_urdfPath = filename;
  if (m_data) delete m_data;
  m_data = new se3::Data(m_model);
Olivier Stasse's avatar
Olivier Stasse committed
  init = true;

  //  m_HDR = parser.parse(filename);
  ros::NodeHandle nh(ns_);
Olivier Stasse's avatar
Olivier Stasse committed

  XmlRpc::XmlRpcValue JointsNamesByRank_;
  JointsNamesByRank_.setSize(m_model.names.size());
Olivier Stasse's avatar
Olivier Stasse committed
  std::vector<std::string>::const_iterator it =
Guilhem Saurel's avatar
Guilhem Saurel committed
      m_model.names.begin() + 2;  // first joint is universe, second is freeflyer
  for (int i = 0; it != m_model.names.end(); ++it, ++i) JointsNamesByRank_[i] = (*it);
  nh.setParam(jointsParameterName_, JointsNamesByRank_);
Olivier Stasse's avatar
Olivier Stasse committed
void RosRobotModel::setNamespace(const std::string& ns) { ns_ = ns; }

void RosRobotModel::loadFromParameterServer() {
  rosInit(false);
  std::string robotDescription;
  ros::param::param<std::string>("/robot_description", robotDescription, "");
Guilhem Saurel's avatar
Guilhem Saurel committed
  if (robotDescription.empty()) throw std::runtime_error("No model available as ROS parameter. Fail.");
Olivier Stasse's avatar
Olivier Stasse committed
  ::urdf::ModelInterfacePtr urdfTree = ::urdf::parseURDF(robotDescription);
  if (urdfTree)
Guilhem Saurel's avatar
Guilhem Saurel committed
    se3::urdf::parseTree(urdfTree->getRoot(), this->m_model, se3::SE3::Identity(), false);
Olivier Stasse's avatar
Olivier Stasse committed
  else {
Guilhem Saurel's avatar
Guilhem Saurel committed
    const std::string exception_message("robot_description not parsed correctly.");
Olivier Stasse's avatar
Olivier Stasse committed
    throw std::invalid_argument(exception_message);
  }
Olivier Stasse's avatar
Olivier Stasse committed
  this->m_urdfPath = "";
  if (m_data) delete m_data;
  m_data = new se3::Data(m_model);
  init = true;
  ros::NodeHandle nh(ns_);
Olivier Stasse's avatar
Olivier Stasse committed
  XmlRpc::XmlRpcValue JointsNamesByRank_;
  JointsNamesByRank_.setSize(m_model.names.size());
  // first joint is universe, second is freeflyer
  std::vector<std::string>::const_iterator it = m_model.names.begin() + 2;
Guilhem Saurel's avatar
Guilhem Saurel committed
  for (int i = 0; it != m_model.names.end(); ++it, ++i) JointsNamesByRank_[i] = (*it);
Olivier Stasse's avatar
Olivier Stasse committed
  nh.setParam(jointsParameterName_, JointsNamesByRank_);
Olivier Stasse's avatar
Olivier Stasse committed
Vector RosRobotModel::curConf() const {
  // The first 6 dofs are associated to the Freeflyer frame
  // Freeflyer reference frame should be the same as global
  // frame so that operational point positions correspond to
  // position in freeflyer frame.
  XmlRpc::XmlRpcValue ffpose;
  ros::NodeHandle nh(ns_);
  std::string param_name = "ffpose";
Olivier Stasse's avatar
Olivier Stasse committed
  if (nh.hasParam(param_name)) {
    nh.getParam(param_name, ffpose);
    ROS_ASSERT(ffpose.getType() == XmlRpc::XmlRpcValue::TypeArray);
    ROS_ASSERT(ffpose.size() == 6);
    for (int32_t i = 0; i < ffpose.size(); ++i) {
      ROS_ASSERT(ffpose[i].getType() == XmlRpc::XmlRpcValue::TypeDouble);
Olivier Stasse's avatar
Olivier Stasse committed
  } else {
Olivier Stasse's avatar
Olivier Stasse committed
    for (int32_t i = 0; i < ffpose.size(); ++i) ffpose[i] = 0.0;
Olivier Stasse's avatar
Olivier Stasse committed

  if (!m_data)
    throw std::runtime_error("no robot loaded");
Olivier Stasse's avatar
Olivier Stasse committed
    // TODO: confirm accesscopy is for asynchronous commands
    Vector currConf = jointPositionSIN.accessCopy();
Guilhem Saurel's avatar
Guilhem Saurel committed
    for (int32_t i = 0; i < ffpose.size(); ++i) currConf(i) = static_cast<double>(ffpose[i]);
Olivier Stasse's avatar
Olivier Stasse committed

Guilhem Saurel's avatar
Guilhem Saurel committed
void RosRobotModel::addJointMapping(const std::string& link, const std::string& repName) {
Olivier Stasse's avatar
Olivier Stasse committed
  specialJoints_[link] = repName;
}

DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(RosRobotModel, "RosRobotModel");
Olivier Stasse's avatar
Olivier Stasse committed
}  // end of namespace dynamicgraph.