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 ¤t_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);
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);
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
00224 if (tactiles_.empty())
00225 tactiles_.resize(msg->tactiles.size());
00226
00227
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 }