sr_ros_wrapper.cpp
Go to the documentation of this file.
00001 #include "sr_standalone/sr_ros_wrapper.hpp"
00002 #include <std_msgs/Float64.h>
00003 #include <pr2_mechanism_msgs/LoadController.h>
00004 #include <pr2_mechanism_msgs/SwitchController.h>
00005 #include <boost/algorithm/string/case_conv.hpp>
00006 #include <algorithm>
00007 
00008 using namespace std;
00009 using boost::algorithm::to_upper_copy;
00010 static const size_t JOINTS_WITH_STATE = 20;
00011 
00012 namespace shadow_robot_standalone
00013 {
00014 
00015 static const string ctrl_joints[JOINTS_WITH_STATE] = {"ffj0", "ffj3", "ffj4",
00016                                                       "lfj0", "lfj3", "lfj4", "lfj5",
00017                                                       "mfj0", "mfj3", "mfj4",
00018                                                       "rfj0", "rfj3", "rfj4",
00019                                                       "thj1", "thj2", "thj3", "thj4", "thj5",
00020                                                       "wrj1", "wrj2"};
00021 
00022 ShadowHand::SrRosWrapper::SrRosWrapper()
00023 {
00024   int _argc = 0;
00025   char **_argv = NULL;
00026   ros::init(_argc, _argv, "sh_standalone_node");
00027   nh_.reset(new ros::NodeHandle());
00028   n_tilde_.reset(new ros::NodeHandle("~"));
00029 
00030   string pr;
00031   n_tilde_->searchParam("prefix", pr);
00032 
00033   joint_states_sub_ = nh_->subscribe(pr + "/joint_states", 1, &SrRosWrapper::joint_state_cb, this);
00034   joint0_states_sub_ = nh_->subscribe(pr + "joint_0s/joint_states", 1, &SrRosWrapper::joint_state_cb, this);
00035   tactile_sub_ = nh_->subscribe(pr + "/tactile", 1, &SrRosWrapper::tactile_cb, this);
00036 
00037   hand_commander_.reset(new shadowrobot::HandCommander());
00038 
00039   for (size_t i = 0; i < JOINTS_WITH_STATE; ++i)
00040   {
00041     pr2_mechanism_msgs::LoadController pos_to_load;
00042     pos_to_load.request.name = string("/sh_") + ctrl_joints[i] + "_position_controller";
00043     ros::service::call("pr2_controller_manager/load_controller", pos_to_load);
00044 
00045     pr2_mechanism_msgs::LoadController eff_to_load;
00046     eff_to_load.request.name = string("/sh_") + ctrl_joints[i] + "_effort_controller";
00047     ros::service::call("pr2_controller_manager/load_controller", eff_to_load);
00048 
00049     torque_pubs_[to_upper_copy(ctrl_joints[i])] =
00050       nh_->advertise<std_msgs::Float64>(eff_to_load.request.name + "/command", 1, true);
00051   }
00052 }
00053 
00054 void ShadowHand::SrRosWrapper::spin(void)
00055 {
00056   if (ros::ok())
00057   {
00058     ros::Duration(0.01).sleep();
00059     ros::spinOnce();
00060   }
00061 }
00062 
00063 bool ShadowHand::SrRosWrapper::get_control_type(ControlType &current_ctrl_type)
00064 {
00065   spin();
00066   sr_robot_msgs::ChangeControlType change_ctrl_type;
00067   change_ctrl_type.request.control_type.control_type = sr_robot_msgs::ControlType::QUERY;
00068   if (ros::service::call("realtime_loop/change_control_type", change_ctrl_type))
00069   {
00070     if (change_ctrl_type.response.result.control_type == sr_robot_msgs::ControlType::PWM)
00071     {
00072       current_ctrl_type = POSITION_PWM;
00073       return true;
00074     }
00075     else if (change_ctrl_type.response.result.control_type == sr_robot_msgs::ControlType::FORCE)
00076     {
00077       current_ctrl_type = EFFORT_TORQUE;
00078       return true;
00079     }
00080   }
00081 
00082   ROS_ERROR_STREAM("Failed to get current control type.");
00083   return false;
00084 }
00085 
00086 bool ShadowHand::SrRosWrapper::set_control_type(const ControlType &new_ctrl_type)
00087 {
00088   sr_robot_msgs::ChangeControlType change_ctrl_type;
00089   if (new_ctrl_type == POSITION_PWM)
00090     change_ctrl_type.request.control_type.control_type = sr_robot_msgs::ControlType::PWM;
00091   else if (new_ctrl_type == EFFORT_TORQUE)
00092     change_ctrl_type.request.control_type.control_type = sr_robot_msgs::ControlType::FORCE;
00093   else
00094   {
00095     ROS_ERROR_STREAM("Unknown control type: " << new_ctrl_type);
00096     return false;
00097   }
00098   if (!ros::service::call("realtime_loop/change_control_type", change_ctrl_type))
00099   {
00100     ROS_ERROR_STREAM("Failed to change control type to " << new_ctrl_type);
00101     return false;
00102   }
00103 
00104   sleep(3);
00105 
00106   ControlType current_ctrl_type;
00107   if (get_control_type(current_ctrl_type) && current_ctrl_type == new_ctrl_type)
00108   {
00109     pr2_mechanism_msgs::SwitchController cswitch;
00110     cswitch.request.strictness = pr2_mechanism_msgs::SwitchController::Request::STRICT;
00111 
00112     for (size_t i = 0; i < JOINTS_WITH_STATE; ++i)
00113     {
00114       string pos_ctrl_name = "/sh_" + ctrl_joints[i] + "_position_controller";
00115       string eff_ctrl_name = "/sh_" + ctrl_joints[i] + "_effort_controller";
00116       if (current_ctrl_type == POSITION_PWM)
00117       {
00118         cswitch.request.start_controllers.push_back(pos_ctrl_name);
00119         cswitch.request.stop_controllers.push_back(eff_ctrl_name);
00120       }
00121       else if (current_ctrl_type == EFFORT_TORQUE)
00122       {
00123         cswitch.request.start_controllers.push_back(eff_ctrl_name);
00124         cswitch.request.stop_controllers.push_back(pos_ctrl_name);
00125       }
00126       if (ros::service::call("pr2_controller_manager/switch_controller", cswitch))
00127         ROS_INFO("switched controllers");
00128       else
00129         ROS_INFO("failed on switching");
00130     }
00131     return true;
00132   }
00133 
00134   ROS_ERROR_STREAM("Failed to change control type to " << new_ctrl_type);
00135   return false;
00136 }
00137 
00138 void ShadowHand::SrRosWrapper::send_position(const string &joint_name, double target)
00139 {
00140   if (torque_pubs_.count(joint_name) == 0)
00141   {
00142     ROS_ERROR_STREAM("Unknown joint name : " << joint_name);
00143     return;
00144   }
00145 
00146   sr_robot_msgs::joint joint_command;
00147   joint_command.joint_name = joint_name;
00148   joint_command.joint_target = target * (180 / M_PI); // convert to degrees
00149   hand_commander_->sendCommands(vector<sr_robot_msgs::joint>(1, joint_command));
00150   spin();
00151 }
00152 
00153 void ShadowHand::SrRosWrapper::send_all_positions(const vector<double> &targets)
00154 {
00155   if (targets.size() != torque_pubs_.size())
00156   {
00157     ROS_ERROR_STREAM("targets size should be " << torque_pubs_.size());
00158     return;
00159   }
00160 
00161   vector<sr_robot_msgs::joint> joint_commands;
00162   sr_robot_msgs::joint joint_command;
00163 
00164   boost::unordered_map<string, ros::Publisher>::const_iterator pit = torque_pubs_.begin();
00165   vector<double>::const_iterator tit = targets.begin();
00166   while (pit != torque_pubs_.end())
00167   {
00168     joint_command.joint_name = pit->first;
00169     joint_command.joint_target = *tit * (180 / M_PI); // convert to degrees
00170     joint_commands.push_back(joint_command);
00171 
00172     ++pit;
00173     ++tit;
00174   }
00175   hand_commander_->sendCommands(joint_commands);
00176   spin();
00177 }
00178 
00179 void ShadowHand::SrRosWrapper::send_torque(const string &joint_name, double target)
00180 {
00181   if (!torque_pubs_.count(joint_name))
00182   {
00183     ROS_ERROR_STREAM("Unknown joint name : " << joint_name);
00184     return;
00185   }
00186 
00187   std_msgs::Float64 msg;
00188   msg.data = target;
00189   torque_pubs_[joint_name].publish(msg);
00190   spin();
00191 }
00192 
00193 void ShadowHand::SrRosWrapper::send_all_torques(const vector<double> &targets)
00194 {
00195   if (targets.size() != torque_pubs_.size())
00196   {
00197     ROS_ERROR_STREAM("targets size should be " << torque_pubs_.size());
00198     return;
00199   }
00200 
00201   boost::unordered_map<string, ros::Publisher>::const_iterator pit = torque_pubs_.begin();
00202   vector<double>::const_iterator tit = targets.begin();
00203   while (pit != torque_pubs_.end())
00204   {
00205     std_msgs::Float64 msg;
00206     msg.data = *tit;
00207     pit->second.publish(msg);
00208 
00209     ++pit;
00210     ++tit;
00211   }
00212   spin();
00213 }
00214 
00215 void ShadowHand::SrRosWrapper::joint_state_cb(const sensor_msgs::JointStateConstPtr& msg)
00216 {
00217   for (size_t i = 0; i < msg->name.size(); ++i)
00218     joint_states_[msg->name[i]] = JointState(msg->position[i], msg->velocity[i], msg->effort[i]);
00219 }
00220 
00221 void ShadowHand::SrRosWrapper::tactile_cb(const sr_robot_msgs::BiotacAllConstPtr& msg)
00222 {
00223   //initialise the vector to the correct size if empty (first time)
00224   if (tactiles_.empty())
00225     tactiles_.resize(msg->tactiles.size());
00226 
00227   //fills the data with the incoming biotacs
00228   for (size_t i = 0; i < tactiles_.size(); ++i)
00229   {
00230     tactiles_[i].pac0 = msg->tactiles[i].pac0;
00231     tactiles_[i].pac1 = msg->tactiles[i].pac1;
00232     tactiles_[i].pdc = msg->tactiles[i].pdc;
00233 
00234     tactiles_[i].tac = msg->tactiles[i].tac;
00235     tactiles_[i].tdc = msg->tactiles[i].tdc;
00236 
00237     if (Tactile::no_of_electrodes == msg->tactiles[i].electrodes.size())
00238     {
00239       for (size_t elec_i = 0; elec_i < msg->tactiles[i].electrodes.size(); ++elec_i)
00240         tactiles_[i].electrodes[elec_i] = msg->tactiles[i].electrodes[elec_i];
00241     }
00242     else
00243     {
00244       ROS_ERROR_STREAM("Verify the size of msg->tactiles[i].electrodes. \n"
00245                        << "It is " << msg->tactiles[i].electrodes.size()
00246                        << ", but it should be " << Tactile::no_of_electrodes << ".");
00247     }
00248   }
00249 }
00250 
00251 } // namespace


sr_standalone
Author(s): Manos Nikolaidis , Yi Li
autogenerated on Fri Aug 28 2015 13:10:49