Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <katana_joint_movement_adapter/joint_movement_adapter.h>
00028 #include <fstream>
00029 #include <iostream>
00030 #include <cstdio>
00031
00032 namespace katana_joint_movement_adapter
00033 {
00034
00035 JointMovementAdapter::JointMovementAdapter(std::string name) :
00036 as_(ros::NodeHandle(), "joint_movement_action", boost::bind(&JointMovementAdapter::executeCB, this, _1), false),
00037 ac_("joint_trajectory_action"), got_state_(false)
00038 {
00039 ros::NodeHandle n;
00040 state_sub_ = n.subscribe("state", 1, &JointMovementAdapter::jointStateCb, this);
00041
00042 ros::NodeHandle pn("~");
00043 pn.param("max_acc", max_acc_, 0.5);
00044 pn.param("max_vel", max_vel_, 5.0);
00045
00046
00047 ROS_DEBUG("Loading robot model");
00048 std::string xml_string;
00049 ros::NodeHandle nh_toplevel;
00050 if (!nh_toplevel.getParam(std::string("/robot_description"), xml_string))
00051 throw ros::Exception("Could not find parameter robot_description on parameter server");
00052
00053 if (!robot_model_.initString(xml_string))
00054 throw ros::Exception("Could not parse robot model");
00055
00056 ros::Rate r(10.0);
00057 while (!got_state_)
00058 {
00059 ros::spinOnce();
00060 r.sleep();
00061 }
00062
00063
00064
00065
00066 ac_.waitForServer();
00067 as_.start();
00068 ROS_INFO("%s: Initialized",name.c_str());
00069 }
00070
00071 JointMovementAdapter::~JointMovementAdapter()
00072 {
00073 }
00074
00075 void JointMovementAdapter::jointStateCb(const pr2_controllers_msgs::JointTrajectoryControllerStateConstPtr& state)
00076 {
00077 boost::mutex::scoped_lock lock(mutex_);
00078 for (unsigned int i = 0; i < state->joint_names.size(); ++i)
00079 {
00080 current_state_[state->joint_names[i]] = state->actual.positions[i];
00081 }
00082 got_state_ = true;
00083 }
00084
00085 void JointMovementAdapter::executeCB(const JMAS::GoalConstPtr &movement_goal)
00086 {
00087 ROS_DEBUG("Got a goal");
00088
00089
00090
00091
00092
00093
00094 sensor_msgs::JointState limited_joint_states = limitJointStates(movement_goal->jointGoal);
00095
00096
00097 pr2_controllers_msgs::JointTrajectoryGoal rough_trajectory_goal = makeRoughTrajectory(limited_joint_states);
00098
00099
00100 pr2_controllers_msgs::JointTrajectoryGoal full_trajectory_goal;
00101 try
00102 {
00103 full_trajectory_goal = makeFullTrajectory(rough_trajectory_goal);
00104 }
00105 catch (ros::Exception ex)
00106 {
00107 ROS_ERROR_STREAM(ex.what());
00108 as_.setAborted();
00109 return;
00110 }
00111
00112
00113 ac_.sendGoal(full_trajectory_goal);
00114
00115
00116 while (ros::ok() && !ac_.waitForResult(ros::Duration(0.05)))
00117 {
00118 if (as_.isPreemptRequested())
00119 {
00120 ROS_DEBUG("Preempted");
00121 ac_.cancelGoal();
00122 }
00123 }
00124
00125
00126 if (!ros::ok())
00127 {
00128 as_.setAborted();
00129 return;
00130 }
00131
00132
00133 actionlib::SimpleClientGoalState state = ac_.getState();
00134
00135 if (state == actionlib::SimpleClientGoalState::PREEMPTED)
00136 {
00137 ROS_DEBUG("Preempted");
00138 as_.setPreempted();
00139 }
00140 else if (state == actionlib::SimpleClientGoalState::SUCCEEDED)
00141 {
00142 ROS_DEBUG("Succeeded");
00143 as_.setSucceeded();
00144 }
00145 else if (state == actionlib::SimpleClientGoalState::ABORTED)
00146 {
00147 ROS_DEBUG("Aborted");
00148 as_.setAborted();
00149 }
00150 else
00151 as_.setAborted(katana_msgs::JointMovementResult(), "Unknown result from joint_trajectory_action");
00152 }
00153
00154 pr2_controllers_msgs::JointTrajectoryGoal JointMovementAdapter::makeRoughTrajectory(
00155 const sensor_msgs::JointState &jointGoal)
00156 {
00157 pr2_controllers_msgs::JointTrajectoryGoal result;
00158
00159 if (jointGoal.name.size() != jointGoal.position.size())
00160 ROS_FATAL("joint goal: name and position array have different size!");
00161
00162
00163 std::map<std::string, double> target_state = std::map<std::string, double>(current_state_);
00164
00165
00166 for (size_t i = 0; i < jointGoal.name.size(); ++i)
00167 {
00168 if (target_state.find(jointGoal.name[i]) == target_state.end())
00169 ROS_WARN("joint name %s is not one of our controlled joints, ignoring", jointGoal.name[i].c_str());
00170 else
00171 target_state[jointGoal.name[i]] = jointGoal.position[i];
00172 }
00173
00174
00175
00176 result.trajectory.header = jointGoal.header;
00177 result.trajectory.points.resize(1);
00178
00179
00180
00181 result.trajectory.points[0].time_from_start = ros::Duration(0.0);
00182
00183
00184 for (std::map<std::string, double>::iterator it = target_state.begin(); it != target_state.end(); ++it)
00185 {
00186 result.trajectory.joint_names.push_back(it->first);
00187 result.trajectory.points[0].positions.push_back(it->second);
00188
00189
00190
00191 result.trajectory.points[0].velocities.push_back(0.0);
00192 result.trajectory.points[0].accelerations.push_back(0.0);
00193 }
00194
00195 return result;
00196 }
00197
00198 pr2_controllers_msgs::JointTrajectoryGoal JointMovementAdapter::makeFullTrajectory(
00199 const pr2_controllers_msgs::JointTrajectoryGoal& goal)
00200 {
00201 pr2_controllers_msgs::JointTrajectoryGoal new_goal;
00202 new_goal.trajectory.header = goal.trajectory.header;
00203 new_goal.trajectory.joint_names = goal.trajectory.joint_names;
00204
00205 size_t n_traj_points = goal.trajectory.points.size(), n_joint_names = goal.trajectory.joint_names.size();
00206
00207
00208 ROS_DEBUG_STREAM("Initial trajectory has "<<n_traj_points<<" points.");
00209 new_goal.trajectory.points.resize(n_traj_points + 1);
00210
00211
00212 for (size_t i = 0; i < n_traj_points + 1; i++)
00213 {
00214 new_goal.trajectory.points[i].positions.resize(n_joint_names);
00215 }
00216
00217 {
00218 boost::mutex::scoped_lock lock(mutex_);
00219
00220 for (unsigned int i = 0; i < n_joint_names; ++i)
00221 {
00222
00223 if (current_state_.find(new_goal.trajectory.joint_names[i]) == current_state_.end())
00224 {
00225 ROS_FATAL_STREAM("Joint names in goal and controller don't match. Something is very wrong. Goal joint name: "<<new_goal.trajectory.joint_names[i]);
00226 throw std::runtime_error("Joint names in goal and controller don't match. Something is very wrong.");
00227 }
00228 new_goal.trajectory.points[0].positions[i] = current_state_[new_goal.trajectory.joint_names[i]];
00229
00230
00231 boost::shared_ptr<const urdf::Joint> joint = robot_model_.getJoint(new_goal.trajectory.joint_names[i]);
00232 double offset = 0;
00233
00234 double goal_position = goal.trajectory.points[0].positions[i], current_position =
00235 new_goal.trajectory.points[0].positions[i];
00236
00237 if (joint->type == urdf::Joint::REVOLUTE)
00238 {
00239 offset = 0;
00240 }
00241 else if (joint->type == urdf::Joint::CONTINUOUS)
00242 {
00243 offset = current_position - goal_position - angles::shortest_angular_distance(goal_position, current_position);
00244 }
00245 else
00246 {
00247 ROS_WARN("Unknown joint type in joint trajectory. This joint might not be unwrapped properly. Supported joint types are urdf::Joint::REVOLUTE and urdf::Joint::CONTINUOUS");
00248 offset = 0;
00249 }
00250
00251
00252 for (unsigned int j = 0; j < n_traj_points; j++)
00253 {
00254 new_goal.trajectory.points[j + 1].time_from_start = goal.trajectory.points[j].time_from_start;
00255 new_goal.trajectory.points[j + 1].positions[i] = goal.trajectory.points[j].positions[i] + offset;
00256 }
00257 }
00258 }
00259
00260
00261 trajectory::TrajectoryGenerator g(max_vel_, max_acc_, new_goal.trajectory.joint_names.size());
00262
00263
00264 g.generate(new_goal.trajectory, new_goal.trajectory);
00265
00266 return new_goal;
00267 }
00268
00269 sensor_msgs::JointState JointMovementAdapter::limitJointStates(const sensor_msgs::JointState &jointGoal)
00270 {
00271 sensor_msgs::JointState adjustedJointGoal;
00272
00273 adjustedJointGoal.name = jointGoal.name;
00274 adjustedJointGoal.position = jointGoal.position;
00275
00276
00277
00278
00279
00280
00281 for (size_t i = 0; i < jointGoal.name.size(); i++)
00282 {
00283 boost::shared_ptr<const urdf::Joint> joint = robot_model_.getJoint(jointGoal.name[i]);
00284 if (!joint)
00285 ROS_FATAL("Joint %s not found in URDF!", jointGoal.name[i].c_str());
00286
00287 if (jointGoal.position[i] < joint->limits->lower)
00288 {
00289 adjustedJointGoal.position[i] = joint->limits->lower;
00290 }
00291
00292 if (jointGoal.position[i] > joint->limits->upper)
00293 {
00294 adjustedJointGoal.position[i] = joint->limits->upper;
00295 }
00296 }
00297
00298 return adjustedJointGoal;
00299 }
00300 }
00301
00302 int main(int argc, char** argv)
00303 {
00304 ros::init(argc, argv, "joint_movement_adapter");
00305 katana_joint_movement_adapter::JointMovementAdapter jma(ros::this_node::getName());
00306
00307 ros::spin();
00308
00309 return 0;
00310 }