00001 #ifndef SCHUNKSERVER_H_
00002 #define SCHUNKSERVER_H_
00003
00004 #include <boost/thread.hpp>
00005 #include <boost/noncopyable.hpp>
00006
00007 #include <ros/ros.h>
00008 #include <actionlib/server/simple_action_server.h>
00009
00010 #include <urdf/model.h>
00011 #include <tf/transform_broadcaster.h>
00012
00013 #include <std_msgs/Int8.h>
00014
00015 #include <metralabs_msgs/IDAndFloat.h>
00016 #include <metralabs_msgs/SchunkStatus.h>
00017
00018 #include <sensor_msgs/JointState.h>
00019
00020 #include <trajectory_msgs/JointTrajectory.h>
00021 #include <control_msgs/JointTrajectoryControllerState.h>
00022 #include <control_msgs/FollowJointTrajectoryAction.h>
00023
00024 #include "RobotArm.h"
00025 #include "AmtecProtocolArm.h"
00026 #include "SchunkProtocolArm.h"
00027 #include "LWA3ArmUASHH.h"
00028 #include "PowerCubeArmUUISRC.h"
00029
00030 using namespace std;
00031
00032
00033 #define DEG_TO_RAD(d) ((d)*M_PI/180.0)
00034 #define RAD_TO_DEG(r) ((r)*180.0/M_PI)
00035
00036 #define SLOWEST_REASONABLE_JOINT_SPEED 0.015f // the slowest reasonable speed for our joints (IMHO)
00037 #define TOO_SLOW 0.002f //
00038
00039
00040
00041 class TrajectoryExecuter : private boost::noncopyable {
00042 public:
00043 TrajectoryExecuter(ros::NodeHandle& nh) :
00044 nh_(nh),
00045 as_(NULL),
00046 arm_(NULL)
00047 {
00048 run_ = false;
00049 waiting_ = false;
00050 }
00051
00052 void init(RobotArm* arm, std::map<std::string, unsigned int>& joints_name_to_number_map) {
00053
00054 arm_ = arm;
00055 joints_name_to_number_map_ = joints_name_to_number_map;
00056
00057 state_publisher_ = nh_.advertise<control_msgs::JointTrajectoryControllerState>("trajectory_state", 5);
00058
00059 std::map<std::string, unsigned int>::iterator it;
00060 for (it = joints_name_to_number_map_.begin(); it != joints_name_to_number_map_.end(); ++it) {
00061 state_msg_.joint_names.push_back(it->first);
00062 }
00063 int num_of_joints = joints_name_to_number_map_.size();
00064 state_msg_.desired.positions.resize(num_of_joints);
00065 state_msg_.desired.velocities.resize(num_of_joints);
00066 state_msg_.desired.accelerations.resize(num_of_joints);
00067 state_msg_.actual.positions.resize(num_of_joints);
00068 state_msg_.actual.velocities.resize(num_of_joints);
00069 state_msg_.error.positions.resize(num_of_joints);
00070 state_msg_.error.velocities.resize(num_of_joints);
00071
00072
00073 nh_.param<std::string>("follow_joint_trajectory_action_name", action_name_, "follow_joint_trajectory");
00074 as_ = new ActionServerType(nh_, action_name_,
00075 boost::bind(&TrajectoryExecuter::trajectoryActionCallback, this, _1), false);
00076 as_->start();
00077 }
00078 ~TrajectoryExecuter() {
00079
00080 delete as_;
00081 }
00082
00083 void main() {
00084 while (true) {
00085 {
00086 boost::unique_lock<boost::mutex> lock(mut_);
00087 waiting_ = true;
00088 bool gotit = false;
00089 while (!run_){
00090 if(!nh_.ok()) {
00091 return;
00092 }
00093 try {
00094 boost::this_thread::interruption_point();
00095 gotit = cond_.timed_wait(lock, boost::posix_time::milliseconds(100));
00096 }
00097 catch(const boost::thread_interrupted&) {
00098 ROS_INFO("Trajectory thread was interrupted and returns, stopping the arm.");
00099 arm_->normalStopAll();
00100 return;
00101 }
00102 if (! gotit) {
00103
00104 for (unsigned int joint_i = 0; joint_i<joints_name_to_number_map_.size(); ++joint_i) {
00105
00106 state_msg_.desired = state_msg_.actual;
00107 state_msg_.actual.positions[joint_i] = arm_->getPosition(joint_i);
00108 state_msg_.actual.velocities[joint_i] = 0;
00109 state_msg_.actual.time_from_start = ros::Duration(0);
00110 }
00111
00112
00113 state_msg_.header.stamp = ros::Time::now();
00114 state_publisher_.publish(state_msg_);
00115 }
00116
00117 }
00118 }
00119
00120 {
00121 boost::unique_lock<boost::mutex> lock(mut_);
00122 waiting_ = false;
00123 }
00124
00125 ROS_INFO("Trajectory thread is starting its job");
00126 followTrajectory();
00127 arm_->normalStopAll();
00128
00129 {
00130
00131 boost::unique_lock<boost::mutex> lock(mut_);
00132 run_ = false;
00133 }
00134 ROS_INFO("Trajectory thread has finished its job");
00135 }
00136 }
00137
00138 void start(const trajectory_msgs::JointTrajectory& newtraj) {
00139 {
00140 boost::unique_lock<boost::mutex> lock(mut_);
00141 if (run_) {
00142 ROS_WARN("You need to stop a trajectory before issuing a new command. Ignoring the new command");
00143 return;
00144 }
00145
00146 traj_ = newtraj;
00147 run_ = true;
00148 }
00149 ROS_INFO("Waking up the thread");
00150 cond_.notify_one();
00151 }
00152
00153 void stop() {
00154 boost::unique_lock<boost::mutex> lock(mut_);
00155 run_ = false;
00156 }
00157
00158 bool isRunning() {
00159 boost::unique_lock<boost::mutex> lock(mut_);
00160 return run_;
00161 }
00162
00163 bool isWaiting() {
00164 boost::unique_lock<boost::mutex> lock(mut_);
00165 return waiting_;
00166 }
00167
00168
00169 void trajectoryActionCallback(const control_msgs::FollowJointTrajectoryGoalConstPtr& goal)
00170 {
00171 bool success = true;
00172 ros::Time trajStartTime = ros::Time::now();
00173 const trajectory_msgs::JointTrajectory& traj = goal->trajectory;
00174
00175
00176 feedback_.joint_names = traj.joint_names;
00177 int num_of_joints = traj.joint_names.size();
00178 feedback_.desired.positions.resize(num_of_joints);
00179 feedback_.desired.velocities.resize(num_of_joints);
00180 feedback_.desired.accelerations.resize(num_of_joints);
00181 feedback_.actual.positions.resize(num_of_joints);
00182 feedback_.actual.velocities.resize(num_of_joints);
00183 feedback_.actual.accelerations.resize(num_of_joints);
00184 feedback_.error.positions.resize(num_of_joints);
00185 feedback_.error.velocities.resize(num_of_joints);
00186 feedback_.error.accelerations.resize(num_of_joints);
00187
00188
00189 unsigned int steps = traj.points.size();
00190 for (unsigned int step_i = 0; step_i < steps; ++step_i) {
00191
00192
00193 if (as_->isPreemptRequested() || !ros::ok()) {
00194 ROS_INFO("%s: Preempted", action_name_.c_str());
00195
00196 as_->setPreempted();
00197 success = false;
00198 arm_->normalStopAll();
00199 break;
00200 }
00201
00202
00203
00204 const trajectory_msgs::JointTrajectoryPoint& trajStep = traj.points[step_i];
00205 feedback_.desired = trajStep;
00206
00207 ROS_INFO_STREAM("Trajectory thread executing step "<<step_i<<"+1/"<<steps<<" until "<<trajStep.time_from_start<<" s / "<<(trajStartTime+trajStep.time_from_start));
00208
00209
00210 for (unsigned int joint_i = 0; joint_i < traj.joint_names.size(); ++joint_i) {
00211
00212 int id = joints_name_to_number_map_[traj.joint_names[joint_i]];
00213
00214 float acceleration = trajStep.accelerations[joint_i];
00215 float velocity = trajStep.velocities[joint_i];
00216 float position = trajStep.positions[joint_i];
00217
00218
00219
00220
00222 #define SIGN_TOLERANT_MAX(value, def) ( (value)==0 ? 0 : \
00223 ( \
00224 (value)>0 ? \
00225 std::max((value), (def)) : \
00226 std::min((value), -(def)) \
00227 ) \
00228 )
00229
00230 #define SIGN_TOLERANT_CUT(value, lim) ( (value)==0 ? 0 : \
00231 ( \
00232 (value)>0 ? \
00233 ( (value) > (lim) ? (value) : (0) ) : \
00234 ( (value) < -(lim) ? (value) : (0) ) \
00235 ) \
00236 )
00237
00238
00239
00240
00241 acceleration = 0.21;
00242
00243 if(step_i == steps-1) {
00244 velocity = SLOWEST_REASONABLE_JOINT_SPEED;
00245 }
00246
00247
00248
00249
00250
00251 ROS_INFO_STREAM("Moving module "<<id<<" with "<< velocity<<" rad/s and "<<acceleration<<" rad/s*s to "<<position<<" rad");
00252
00253 #if SCHUNK_NOT_AMTEC != 0
00254
00255
00256 #else
00257 arm_->setAcceleration(id, acceleration);
00258 arm_->setVelocity(id, velocity);
00259 arm_->movePosition(id, position);
00260
00261
00262
00263
00264
00265
00266
00268
00269
00270 #endif
00271
00272
00273
00274 feedback_.actual.positions[id] = arm_->getPosition(id);
00275 feedback_.actual.velocities[id] = arm_->getVelocity(id);
00276
00277 }
00278
00279
00280 feedback_.header.stamp = ros::Time::now();
00281 feedback_.actual.time_from_start = ros::Time::now() - trajStartTime;
00282 as_->publishFeedback(feedback_);
00283
00284
00285 ros::Time::sleepUntil(trajStartTime + trajStep.time_from_start);
00286 }
00287
00288 if(success) {
00289 ROS_INFO("Trajectory done, waiting for joints to stop...");
00290 bool all_joints_stopped;
00291 do {
00292 ros::WallDuration(0.06).sleep();
00293 all_joints_stopped = true;
00294 for (unsigned int joint_i = 0; joint_i < traj.joint_names.size(); ++joint_i) {
00295 uint8_t moving, brake, foo;
00296 float foofl;
00297 arm_->getModuleStatus(joint_i, foo, moving, foo, foo, foo, brake, foo, foo, foo, foofl);
00298
00299 if(!brake) {
00300 all_joints_stopped = false;
00301 break;
00302 }
00303
00304
00305 }
00306 } while (!all_joints_stopped);
00307
00308 result_.error_code = control_msgs::FollowJointTrajectoryResult::SUCCESSFUL;
00309 ROS_INFO("%s: Succeeded", action_name_.c_str());
00310
00311 as_->setSucceeded(result_);
00312 }
00313 }
00314
00315
00316
00317 protected:
00318 ros::NodeHandle nh_;
00319 typedef actionlib::SimpleActionServer<control_msgs::FollowJointTrajectoryAction> ActionServerType;
00320 ActionServerType* as_;
00321 std::string action_name_;
00322
00323 control_msgs::FollowJointTrajectoryFeedback feedback_;
00324 control_msgs::FollowJointTrajectoryResult result_;
00325
00326
00327 private:
00328
00329 void followTrajectory() {
00330
00331 ros::Time trajStartTime = ros::Time::now();
00332 for (unsigned int step = 0; step < traj_.points.size(); ++step) {
00333 trajectory_msgs::JointTrajectoryPoint& point = traj_.points[step];
00334
00335 ROS_INFO_STREAM("Trajectory thread executing step "<<step);
00336
00337 for (unsigned int joint_i = 0; joint_i < traj_.joint_names.size(); ++joint_i) {
00338
00339 unsigned int id = joints_name_to_number_map_[traj_.joint_names[joint_i]];
00340 float velocity = point.velocities[joint_i];
00341
00342 ROS_INFO_STREAM("Moving module "<<id<<" with "<<velocity<<" rad/s = "<<RAD_TO_DEG(velocity)<<" deg/s");
00343 arm_->moveVelocity(id, velocity);
00344
00345
00346 state_msg_.desired = state_msg_.actual;
00347 state_msg_.actual.positions[joint_i] = arm_->getPosition(joint_i);
00348 state_msg_.actual.velocities[joint_i] = arm_->getVelocity(joint_i);
00349 state_msg_.actual.time_from_start = point.time_from_start;
00350 }
00351
00352
00353 state_msg_.header.stamp = ros::Time::now();
00354 state_publisher_.publish(state_msg_);
00355
00356
00357
00358 while (ros::Time::now() < trajStartTime + point.time_from_start) {
00359 ;
00360 {
00361 boost::unique_lock<boost::mutex> lock(mut_);
00362 if (!run_) {
00363 ROS_INFO("Trajectory thread has been commanded to stop");
00364 return;
00365 }
00366 }
00367 }
00368 }
00369 }
00370
00371 RobotArm* arm_;
00372 std::map<std::string, unsigned int> joints_name_to_number_map_;
00373 trajectory_msgs::JointTrajectory traj_;
00374 bool run_;
00375 bool waiting_;
00376 boost::condition_variable cond_;
00377 boost::mutex mut_;
00378 control_msgs::JointTrajectoryControllerState state_msg_;
00379 ros::Publisher state_publisher_;
00380 };
00381
00382
00383
00384 class SchunkServer : private boost::noncopyable {
00385 public:
00386 SchunkServer(ros::NodeHandle &nh) :
00387 node_handle_(nh),
00388 arm_(NULL),
00389 trajectory_executer_(nh)
00390 {
00391 init();
00392 }
00393
00394 ~SchunkServer() {
00395 trajectory_executer_.stop();
00396 trajectory_executer_thread_.interrupt();
00397 trajectory_executer_thread_.join();
00398 if(arm_ != NULL)
00399 delete arm_;
00400 }
00401
00402 private:
00403 void renewRobotArm() {
00404
00405 if(arm_ != NULL)
00406 delete arm_;
00407
00408 std::string robot_arm_class;
00409 ros::NodeHandle nh_private("~");
00410 if(!nh_private.getParam("robot_arm_class", robot_arm_class)) {
00411 ROS_WARN_STREAM("Parameter robot arm class not set, defaulting to AmtecProtocolArm.");
00412 robot_arm_class = "AmtecProtocolArm";
00413 }
00414
00415
00416 if(robot_arm_class == "AmtecProtocolArm")
00417 arm_ = new AmtecProtocolArm();
00418 else if(robot_arm_class == "SchunkProtocolArm")
00419 arm_ = new SchunkProtocolArm();
00420 else if(robot_arm_class == "LWA3ArmUASHH")
00421 arm_ = new LWA3ArmUASHH();
00422 else if(robot_arm_class == "PowerCubeArmUUISRC")
00423 arm_ = new PowerCubeArmUUISRC();
00424 else {
00425 ROS_FATAL_STREAM("Cannot load unknown robot arm class: "<<robot_arm_class);
00426 exit(1);
00427 }
00428 }
00429
00430 void init() {
00431
00432 arm_model_.initParam("robot_description");
00433 std::map<std::string, boost::shared_ptr<urdf::Joint> >::const_iterator mapElement;
00434 for (mapElement = arm_model_.joints_.begin(); mapElement != arm_model_.joints_.end(); ++mapElement) {
00435 boost::shared_ptr<urdf::Joint> joint = mapElement->second;
00436 ROS_DEBUG_STREAM("Joint: Name="<<joint->name<<" MimicPtr="<<joint->mimic);
00437 if (joint->type != urdf::Joint::FIXED &&
00438 joint->mimic == 0)
00439 joints_list_.push_back(joint);
00440 }
00441 ROS_INFO("URDF specifies %d non-fixed non-mimicking joints.", joints_list_.size());
00442
00443
00444 renewRobotArm();
00445 arm_->init();
00446
00447
00448 while(arm_->getModulesCount() != joints_list_.size()) {
00449 ROS_WARN("Reinitialising robot arm... found %d joints but need %d", arm_->getModulesCount(), joints_list_.size());
00450 renewRobotArm();
00451 ros::WallDuration(1).sleep();
00452 arm_->init();
00453 }
00454
00455
00456 ROS_WARN("Didn't check that the modules in the description match modules in reality.");
00457
00458
00459
00460 current_JointState_.name.resize(joints_list_.size());
00461 current_JointState_.position.resize(joints_list_.size());
00462 current_JointState_.velocity.resize(joints_list_.size());
00463 for (unsigned int i = 0; i < joints_list_.size(); ++i) {
00464 current_JointState_.name[i] = joints_list_[i]->name;
00465 joints_name_to_number_map_[joints_list_[i]->name] = i;
00466 ROS_INFO("%d is mapping to %s", i, joints_list_[i]->name.c_str());
00467 }
00468 current_JointState_publisher_ = node_handle_.advertise<sensor_msgs::JointState>("/joint_states", 1);
00469
00470
00471 current_SchunkStatus_publisher_ = node_handle_.advertise<metralabs_msgs::SchunkStatus>("status", 1);
00472 for (uint i = 0; i < joints_list_.size(); ++i) {
00473 metralabs_msgs::SchunkJointStatus status;
00474 status.jointName = joints_list_[i]->name;
00475 current_SchunkStatus_.joints.push_back(status);
00476 }
00477
00478 trajectory_executer_.init(arm_, joints_name_to_number_map_);
00479
00480 ROS_INFO("Starting the trajectory executer thread");
00481 trajectory_executer_thread_ = boost::thread(boost::bind(&TrajectoryExecuter::main, &trajectory_executer_));
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491 ROS_INFO("Subscribing schunk topics...");
00492
00493
00494 emergency_subscriber_ = node_handle_.subscribe("emergency", 1, &SchunkServer::cb_emergency, this);
00495 stop_subscriber_ = node_handle_.subscribe("stop", 1, &SchunkServer::cb_stop, this);
00496 ack_subscriber_ = node_handle_.subscribe("ack", 10, &SchunkServer::cb_ack, this);
00497 ack_all_subscriber_ = node_handle_.subscribe("ack_all", 1, &SchunkServer::cb_ackAll, this);
00498 ref_subscriber_ = node_handle_.subscribe("ref", 10, &SchunkServer::cb_ref, this);
00499 ref_all_subscriber_ = node_handle_.subscribe("ref_all", 1, &SchunkServer::cb_refAll, this);
00500
00501 set_velocity_subscriber_ = node_handle_.subscribe("set_velocity", 10, &SchunkServer::cb_setVelocity, this);
00502 set_acceleration_subscriber_ = node_handle_.subscribe("set_acceleration", 10, &SchunkServer::cb_setAcceleration, this);
00503 set_current_subscriber_ = node_handle_.subscribe("set_current", 10, &SchunkServer::cb_setCurrent, this);
00504 set_currents_max_all_subscriber_ = node_handle_.subscribe("set_current_max_all", 1, &SchunkServer::cb_setCurrentsMaxAll, this);
00505
00506 move_position_subscriber_ = node_handle_.subscribe("move_position", 10, &SchunkServer::cb_movePosition, this);
00507 move_velocity_subscriber_ = node_handle_.subscribe("move_velocity", 10, &SchunkServer::cb_moveVelocity, this);
00508 move_all_position_subscriber_ = node_handle_.subscribe("move_all_position", 1, &SchunkServer::cb_moveAllPosition, this);
00509 move_all_velocity_subscriber_ = node_handle_.subscribe("move_all_velocity", 1, &SchunkServer::cb_moveAllVelocity, this);
00510 trajectory_command_subscriber_ = node_handle_.subscribe("trajectory_command", 1, &SchunkServer::cb_commandTrajectory, this);
00511
00512 boost::thread(&SchunkServer::publishingLoop, this, ros::Rate(30));
00513
00514 ROS_INFO("SchunkServer Ready");
00515
00516 }
00517
00518 void cb_emergency(const std_msgs::Empty::ConstPtr& dummy) {
00519 ROS_INFO("emergency");
00520 arm_->emergencyStopAll();
00521 }
00522
00523 void cb_stop(const std_msgs::Empty::ConstPtr& dummy) {
00524 ROS_INFO("stop");
00525 arm_->normalStopAll();
00526 }
00527
00528 void cb_ack(const std_msgs::Int8::ConstPtr& id) {
00529 ROS_INFO("cb_ack: [%d]", id->data);
00530 arm_->ackJoint(id->data);
00531 }
00532
00533 void cb_ackAll(const std_msgs::Empty::ConstPtr& dummy) {
00534 ROS_INFO("cb_ackAll");
00535 arm_->ackAll();
00536 }
00537
00538 void cb_ref(const std_msgs::Int8::ConstPtr& id) {
00539 ROS_INFO("cb_ref: [%d]", id->data);
00540 arm_->refJoint(id->data);
00541 }
00542
00543 void cb_refAll(const std_msgs::Empty::ConstPtr& dummy) {
00544 ROS_INFO("cb_refAll");
00545 arm_->refAll();
00546 }
00547
00548
00549 void cb_setVelocity(const metralabs_msgs::IDAndFloat::ConstPtr& data) {
00550 ROS_INFO("cb_setVelocity: [%d, %f]", data->id, data->value);
00551 arm_->setVelocity(data->id, data->value);
00552 }
00553
00554 void cb_setAcceleration(const metralabs_msgs::IDAndFloat::ConstPtr& data) {
00555 ROS_INFO("cb_setAcceleration: [%d, %f]", data->id, data->value);
00556 arm_->setAcceleration(data->id, data->value);
00557 }
00558
00559 void cb_setCurrent(const metralabs_msgs::IDAndFloat::ConstPtr& data) {
00560 ROS_INFO("cb_setCurrent: [%d, %f]", data->id, data->value);
00561 arm_->setCurrent(data->id, data->value);
00562 }
00563
00564 void cb_setCurrentsMaxAll(const std_msgs::Empty::ConstPtr& dummy) {
00565 ROS_INFO("cb_setCurrentsMaxAll");
00566 arm_->setCurrentsToMax();
00567 }
00568
00569
00570 void cb_movePosition(const metralabs_msgs::IDAndFloat::ConstPtr& data) {
00571 ROS_INFO("cb_movePosition: [%d, %f]", data->id, data->value);
00572 arm_->movePosition(data->id, data->value);
00573 }
00574
00575 void cb_moveVelocity(const metralabs_msgs::IDAndFloat::ConstPtr& data) {
00576 ROS_INFO("cb_moveVelocity: [%d, %f]", data->id, data->value);
00577 if (data->value == 0.0)
00578 arm_->normalStopJoint(data->id);
00579 else
00580 arm_->moveVelocity(data->id, data->value);
00581 }
00582
00583 void cb_moveAllPosition(const sensor_msgs::JointState::ConstPtr& data) {
00584
00585
00586
00587 for (uint i = 0; i < data.get()->name.size(); ++i) {
00588 string joint_name = data.get()->name[i];
00589 int joint_number = joints_name_to_number_map_[joint_name];
00590 ROS_INFO_STREAM("cb_PositionControl: joint "<<joint_name<<" (#"<<joint_number<<")");
00591
00592 arm_->setCurrentsToMax();
00593 if (data.get()->position.size()!=0) {
00594 double pos = data.get()->position[i];
00595 ROS_INFO_STREAM(" to position "<<pos);
00596 arm_->movePosition(joint_number, pos);
00597 }
00598 if (data.get()->velocity.size()!=0) {
00599 double vel = data.get()->velocity[i];
00600 ROS_INFO_STREAM(" with velocity "<<vel);
00601 arm_->setVelocity(joint_number, vel);
00602 }
00603 if (data.get()->effort.size()!=0) {
00604 double eff = data.get()->effort[i];
00605 ROS_INFO_STREAM(" with effort "<<eff);
00606 arm_->setCurrent(joint_number, eff);
00607 }
00608 }
00609 }
00610
00611 void cb_moveAllVelocity(const sensor_msgs::JointState::ConstPtr& data) {
00612
00613
00614
00615 for (uint i = 0; i < data.get()->name.size(); ++i) {
00616 string joint_name = data.get()->name[i];
00617 int joint_number = joints_name_to_number_map_[joint_name];
00618 ROS_INFO_STREAM("cb_VelocityControl: joint "<<joint_name<<" (#"<<joint_number<<")");
00619
00620
00621
00622 if (data.get()->velocity.size() != 0) {
00623 double vel = data.get()->velocity[i];
00624 ROS_INFO_STREAM(" with velocity "<<vel);
00625 if (vel == 0.0)
00626 arm_->normalStopJoint(joint_number);
00627 else
00628 arm_->moveVelocity(joint_number, vel);
00629 }
00630 if (data.get()->effort.size()!=0) {
00631 double eff = data.get()->effort[i];
00632 ROS_INFO_STREAM(" with effort "<<eff);
00633 arm_->setCurrent(joint_number, eff);
00634 }
00635 }
00636 }
00637
00638 void cb_commandTrajectory(const trajectory_msgs::JointTrajectory traj) {
00639 ROS_INFO("Schunk Server: received a new trajectory");
00640 trajectory_executer_.stop();
00641 while (! trajectory_executer_.isWaiting() ) {
00642 ROS_INFO("Waiting for the controller to be ready..");
00643 }
00644 trajectory_executer_.start(traj);
00645 }
00646
00647 private:
00648 void publishingLoop(ros::Rate loop_rate) {
00649 while (node_handle_.ok()) {
00650 publishCurrentJointState();
00651 publishCurrentSchunkStatus();
00652
00653 loop_rate.sleep();
00654 }
00655 }
00656
00657 void publishCurrentJointState() {
00658 current_JointState_.header.stamp = ros::Time::now();
00659 for (unsigned int i = 0; i < current_JointState_.name.size(); ++i) {
00660 current_JointState_.position[i] = arm_->getPosition(i);
00661 current_JointState_.velocity[i] = arm_->getVelocity(i);
00662 }
00663 current_JointState_publisher_.publish(current_JointState_);
00664 }
00665
00666 void publishCurrentSchunkStatus() {
00667 std::vector<metralabs_msgs::SchunkJointStatus>::iterator it;
00668 uint module_number;
00669 for (it = current_SchunkStatus_.joints.begin(); it != current_SchunkStatus_.joints.end(); ++it) {
00670 module_number = joints_name_to_number_map_[it->jointName];
00671 arm_->getModuleStatus(module_number, it->referenced, it->moving, it->progMode, it->warning,
00672 it->error, it->brake, it->moveEnd, it->posReached, it->errorCode, it->current);
00673 }
00674 current_SchunkStatus_publisher_.publish(current_SchunkStatus_);
00675 }
00676
00677
00678 private:
00679 ros::NodeHandle node_handle_;
00680 RobotArm* arm_;
00681 urdf::Model arm_model_;
00682 std::vector<boost::shared_ptr<urdf::Joint> > joints_list_;
00683 std::map<std::string, unsigned int> joints_name_to_number_map_;
00684
00685 sensor_msgs::JointState current_JointState_;
00686 metralabs_msgs::SchunkStatus current_SchunkStatus_;
00687 ros::Publisher current_JointState_publisher_;
00688 ros::Publisher current_SchunkStatus_publisher_;
00689
00690 TrajectoryExecuter trajectory_executer_;
00691 boost::thread trajectory_executer_thread_;
00692
00693 ros::Subscriber emergency_subscriber_;
00694 ros::Subscriber stop_subscriber_;
00695 ros::Subscriber first_ref_subscriber_;
00696 ros::Subscriber ack_subscriber_;
00697 ros::Subscriber ack_all_subscriber_;
00698 ros::Subscriber ref_subscriber_;
00699 ros::Subscriber ref_all_subscriber_;
00700
00701 ros::Subscriber set_velocity_subscriber_;
00702 ros::Subscriber set_acceleration_subscriber_;
00703 ros::Subscriber set_current_subscriber_;
00704 ros::Subscriber set_currents_max_all_subscriber_;
00705
00706 ros::Subscriber move_position_subscriber_;
00707 ros::Subscriber move_velocity_subscriber_;
00708 ros::Subscriber move_all_position_subscriber_;
00709 ros::Subscriber move_all_velocity_subscriber_;
00710 ros::Subscriber trajectory_command_subscriber_;
00711 };
00712
00713
00714 #endif