00001
00062 #include "ros/ros.h"
00063 #include <sensor_msgs/JointState.h>
00064 #include <control_msgs/JointTrajectoryControllerState.h>
00065 #include <actionlib/server/simple_action_server.h>
00066 #include <control_msgs/FollowJointTrajectoryAction.h>
00067
00068 #include <brics_actuator/JointVelocities.h>
00069 #include <cob_trajectory_controller/genericArmCtrl.h>
00070
00071 #include <cob_srvs/Trigger.h>
00072 #include <cob_srvs/SetOperationMode.h>
00073 #include <cob_trajectory_controller/SetFloat.h>
00074
00075
00076 #define HZ 100
00077
00078 class cob_trajectory_controller_node
00079 {
00080 private:
00081 ros::NodeHandle n_;
00082
00083 ros::Publisher joint_vel_pub_;
00084 ros::Subscriber controller_state_;
00085 ros::Subscriber operation_mode_;
00086 ros::ServiceServer srvServer_Stop_;
00087 ros::ServiceServer srvServer_SetVel_;
00088 ros::ServiceServer srvServer_SetAcc_;
00089 ros::ServiceClient srvClient_SetOperationMode;
00090
00091 actionlib::SimpleActionServer<control_msgs::FollowJointTrajectoryAction> as_follow_;
00092
00093
00094
00095 std::string action_name_follow_;
00096 std::string current_operation_mode_;
00097 XmlRpc::XmlRpcValue JointNames_param_;
00098 std::vector<std::string> JointNames_;
00099 bool executing_;
00100 bool failure_;
00101 bool rejected_;
00102 bool preemted_;
00103 int DOF;
00104 double velocity_timeout_;
00105
00106 int watchdog_counter;
00107 genericArmCtrl* traj_generator_;
00108 trajectory_msgs::JointTrajectory traj_;
00109 trajectory_msgs::JointTrajectory traj_2_;
00110 std::vector<double> q_current, startposition_, joint_distance_;
00111
00112 public:
00113
00114
00115 cob_trajectory_controller_node():
00116
00117 as_follow_(n_, "follow_joint_trajectory", boost::bind(&cob_trajectory_controller_node::executeFollowTrajectory, this, _1), true),
00118
00119 action_name_follow_("follow_joint_trajectory")
00120
00121 {
00122 joint_vel_pub_ = n_.advertise<brics_actuator::JointVelocities>("command_vel", 1);
00123 controller_state_ = n_.subscribe("state", 1, &cob_trajectory_controller_node::state_callback, this);
00124 operation_mode_ = n_.subscribe("current_operationmode", 1, &cob_trajectory_controller_node::operationmode_callback, this);
00125 srvServer_Stop_ = n_.advertiseService("stop", &cob_trajectory_controller_node::srvCallback_Stop, this);
00126 srvServer_SetVel_ = n_.advertiseService("set_joint_velocity", &cob_trajectory_controller_node::srvCallback_setVel, this);
00127 srvServer_SetAcc_ = n_.advertiseService("set_joint_acceleration", &cob_trajectory_controller_node::srvCallback_setAcc, this);
00128 srvClient_SetOperationMode = n_.serviceClient<cob_srvs::SetOperationMode>("set_operation_mode");
00129 while(!srvClient_SetOperationMode.exists())
00130 {
00131 ROS_INFO("Waiting for operationmode service to become available");
00132 sleep(1);
00133 }
00134 executing_ = false;
00135 failure_ = false;
00136 rejected_ = false;
00137 preemted_ = false;
00138 watchdog_counter = 0;
00139 current_operation_mode_ = "undefined";
00140 double PTPvel = 0.7;
00141 double PTPacc = 0.2;
00142 double maxError = 0.7;
00143 double overlap_time = 0.4;
00144 velocity_timeout_ = 2.0;
00145 DOF = 7;
00146
00147 ROS_INFO("getting JointNames from parameter server");
00148 if (n_.hasParam("joint_names"))
00149 {
00150 n_.getParam("joint_names", JointNames_param_);
00151 }
00152 else
00153 {
00154 ROS_ERROR("Parameter joint_names not set");
00155 }
00156 JointNames_.resize(JointNames_param_.size());
00157 for (int i = 0; i<JointNames_param_.size(); i++ )
00158 {
00159 JointNames_[i] = (std::string)JointNames_param_[i];
00160 }
00161 DOF = JointNames_param_.size();
00162 if (n_.hasParam("ptp_vel"))
00163 {
00164 n_.getParam("ptp_vel", PTPvel);
00165 }
00166 if (n_.hasParam("ptp_acc"))
00167 {
00168 n_.getParam("ptp_acc", PTPacc);
00169 }
00170 if (n_.hasParam("max_error"))
00171 {
00172 n_.getParam("max_error", maxError);
00173 }
00174 if (n_.hasParam("overlap_time"))
00175 {
00176 n_.getParam("overlap_time", overlap_time);
00177 }
00178 q_current.resize(DOF);
00179 ROS_INFO("starting controller with DOF: %d PTPvel: %f PTPAcc: %f maxError %f", DOF, PTPvel, PTPacc, maxError);
00180 traj_generator_ = new genericArmCtrl(DOF, PTPvel, PTPacc, maxError);
00181 traj_generator_->overlap_time = overlap_time;
00182 }
00183
00184 double getFrequency()
00185 {
00186 double frequency;
00187 if (n_.hasParam("frequency"))
00188 {
00189 n_.getParam("frequency", frequency);
00190 ROS_INFO("Setting controller frequency to %f HZ", frequency);
00191 }
00192 else
00193 {
00194 frequency = 100;
00195 ROS_WARN("Parameter frequency not available, setting to default value: %f Hz", frequency);
00196 }
00197 return frequency;
00198 }
00199
00200 bool srvCallback_Stop(cob_srvs::Trigger::Request &req, cob_srvs::Trigger::Response &res)
00201 {
00202 ROS_INFO("Stopping trajectory controller.");
00203
00204
00205 executing_ = false;
00206 res.success.data = true;
00207 traj_generator_->isMoving = false;
00208
00209 failure_ = true;
00210 return true;
00211 }
00212 bool srvCallback_setVel(cob_trajectory_controller::SetFloat::Request &req, cob_trajectory_controller::SetFloat::Response &res)
00213 {
00214 ROS_INFO("Setting velocity to %f", req.value.data);
00215 traj_generator_->SetPTPvel(req.value.data);
00216 res.success.data = true;
00217 return true;
00218 }
00219 bool srvCallback_setAcc(cob_trajectory_controller::SetFloat::Request &req, cob_trajectory_controller::SetFloat::Response &res)
00220 {
00221 ROS_INFO("Setting acceleration to %f", req.value.data);
00222 traj_generator_->SetPTPacc(req.value.data);
00223 res.success.data = true;
00224 return true;
00225 }
00226
00227 void operationmode_callback(const std_msgs::StringPtr& message)
00228 {
00229 current_operation_mode_ = message->data;
00230 }
00231 void state_callback(const control_msgs::JointTrajectoryControllerStatePtr& message)
00232 {
00233 std::vector<double> positions = message->actual.positions;
00234 for(unsigned int i = 0; i < positions.size(); i++)
00235 {
00236 q_current[i] = positions[i];
00237 }
00238 }
00239
00240 void spawnTrajector(trajectory_msgs::JointTrajectory trajectory)
00241 {
00242 if(!executing_ || preemted_)
00243 {
00244
00245 cob_srvs::SetOperationMode opmode;
00246 opmode.request.operation_mode.data = "velocity";
00247 srvClient_SetOperationMode.call(opmode);
00248 ros::Time begin = ros::Time::now();
00249 while(current_operation_mode_ != "velocity")
00250 {
00251 ROS_INFO("waiting for component to go to velocity mode");
00252 usleep(100000);
00253
00254 if((ros::Time::now() - begin).toSec() > velocity_timeout_)
00255 {
00256 rejected_ = true;
00257 return;
00258 }
00259 }
00260
00261 std::vector<double> traj_start;
00262 if(preemted_ == true)
00263 {
00264 ROS_INFO("There is a old trajectory currently running");
00265 traj_start = traj_generator_->last_q;
00266 trajectory_msgs::JointTrajectory temp_traj;
00267 temp_traj = trajectory;
00268
00269 trajectory_msgs::JointTrajectoryPoint p;
00270 p.positions.resize(DOF);
00271 p.velocities.resize(DOF);
00272 p.accelerations.resize(DOF);
00273 for(int i = 0; i<DOF; i++)
00274 {
00275 p.positions.at(i) = traj_start.at(i);
00276 p.velocities.at(i) = 0.0;
00277 p.accelerations.at(i) = 0.0;
00278 }
00279 std::vector<trajectory_msgs::JointTrajectoryPoint>::iterator it;
00280 it = temp_traj.points.begin();
00281 temp_traj.points.insert(it,p);
00282
00283 for(int i = 0; i<DOF; i++)
00284 {
00285 p.positions.at(i) = traj_generator_->last_q1.at(i);
00286 p.velocities.at(i) = 0.0;
00287 p.accelerations.at(i) = 0.0;
00288 }
00289 it = temp_traj.points.begin();
00290 temp_traj.points.insert(it,p);
00291 for(int i = 0; i<DOF; i++)
00292 {
00293 p.positions.at(i) = traj_generator_->last_q2.at(i);
00294 p.velocities.at(i) = 0.0;
00295 p.accelerations.at(i) = 0.0;
00296 }
00297 it = temp_traj.points.begin();
00298 temp_traj.points.insert(it,p);
00299 for(int i = 0; i<DOF; i++)
00300 {
00301 p.positions.at(i) = traj_generator_->last_q3.at(i);
00302 p.velocities.at(i) = 0.0;
00303 p.accelerations.at(i) = 0.0;
00304 }
00305 it = temp_traj.points.begin();
00306 temp_traj.points.insert(it,p);
00307 for(int i = 0; i<DOF; i++)
00308 {
00309 p.positions.at(i) = q_current.at(i);
00310 p.velocities.at(i) = 0.0;
00311 p.accelerations.at(i) = 0.0;
00312 }
00313 it = temp_traj.points.begin();
00314 temp_traj.points.insert(it,p);
00315 traj_generator_->isMoving = false ;
00316 traj_generator_->moveTrajectory(temp_traj, traj_start);
00317 }
00318 else
00319 {
00320 traj_start = q_current;
00321 trajectory_msgs::JointTrajectory temp_traj;
00322 temp_traj = trajectory;
00323 if(temp_traj.points.size() == 1)
00324 {
00325 traj_generator_->isMoving = false ;
00326 traj_generator_->moveThetas(temp_traj.points[0].positions, traj_start);
00327 }
00328 else
00329 {
00330
00331 trajectory_msgs::JointTrajectoryPoint p;
00332 p.positions.resize(DOF);
00333 p.velocities.resize(DOF);
00334 p.accelerations.resize(DOF);
00335 for(int i = 0; i<DOF; i++)
00336 {
00337 p.positions.at(i) = traj_start.at(i);
00338 p.velocities.at(i) = 0.0;
00339 p.accelerations.at(i) = 0.0;
00340 }
00341 std::vector<trajectory_msgs::JointTrajectoryPoint>::iterator it;
00342 it = temp_traj.points.begin();
00343 temp_traj.points.insert(it,p);
00344 traj_generator_->isMoving = false ;
00345 traj_generator_->moveTrajectory(temp_traj, traj_start);
00346 }
00347 }
00348
00349 executing_ = true;
00350 startposition_ = q_current;
00351 preemted_ = false;
00352
00353 }
00354 else
00355 {
00356 }
00357 while(executing_)
00358 {
00359 if(!preemted_)
00360 {
00361 usleep(1000);
00362 }
00363 else{
00364 return;
00365 }
00366 }
00367
00368
00369 }
00370
00371
00372 void executeFollowTrajectory(const control_msgs::FollowJointTrajectoryGoalConstPtr &goal)
00373 {
00374 ROS_INFO("Received new goal trajectory with %lu points",goal->trajectory.points.size());
00375 spawnTrajector(goal->trajectory);
00376
00377 if(rejected_)
00378 as_follow_.setAborted();
00379 else
00380 {
00381 if(failure_)
00382 as_follow_.setAborted();
00383 else
00384 as_follow_.setSucceeded();
00385 }
00386 rejected_ = false;
00387 failure_ = false;
00388 }
00389
00390 void run()
00391 {
00392 if(executing_)
00393 {
00394 failure_ = false;
00395 watchdog_counter = 0;
00396
00397 if (!ros::ok() || current_operation_mode_ != "velocity")
00398 {
00399
00400
00401 executing_ = false;
00402 traj_generator_->isMoving = false;
00403
00404 failure_ = true;
00405 return;
00406 }
00407 if (as_follow_.isPreemptRequested())
00408 {
00409
00410
00411 failure_ = true;
00412 preemted_ = true;
00413 ROS_INFO("Preempted trajectory action");
00414 return;
00415 }
00416 std::vector<double> des_vel;
00417 if(traj_generator_->step(q_current, des_vel))
00418 {
00419 if(!traj_generator_->isMoving)
00420 {
00421 executing_ = false;
00422 preemted_ = false;
00423 }
00424 brics_actuator::JointVelocities target_joint_vel;
00425 target_joint_vel.velocities.resize(DOF);
00426 for(int i=0; i<DOF; i++)
00427 {
00428 target_joint_vel.velocities[i].joint_uri = JointNames_[i].c_str();
00429 target_joint_vel.velocities[i].unit = "rad";
00430 target_joint_vel.velocities[i].value = des_vel.at(i);
00431
00432 }
00433
00434
00435 joint_vel_pub_.publish(target_joint_vel);
00436 }
00437 else
00438 {
00439 ROS_INFO("An controller error occured!");
00440 failure_ = true;
00441 executing_ = false;
00442 }
00443 }
00444 else
00445 {
00446 if(watchdog_counter < 10)
00447 {
00448 brics_actuator::JointVelocities target_joint_vel;
00449 target_joint_vel.velocities.resize(DOF);
00450 for (int i = 0; i < DOF; i += 1)
00451 {
00452 target_joint_vel.velocities[i].joint_uri = JointNames_[i].c_str();
00453 target_joint_vel.velocities[i].unit = "rad";
00454 target_joint_vel.velocities[i].value = 0;
00455 }
00456 joint_vel_pub_.publish(target_joint_vel);
00457 }
00458 watchdog_counter++;
00459 }
00460 }
00461
00462 };
00463
00464
00465
00466 int main(int argc, char ** argv)
00467 {
00468 ros::init(argc, argv, "cob_trajectory_controller");
00469
00470 cob_trajectory_controller_node tm;
00471
00473 double frequency = tm.getFrequency();
00474
00475 ros::Rate loop_rate(frequency);
00476 while (ros::ok())
00477 {
00478 tm.run();
00479 ros::spinOnce();
00480 loop_rate.sleep();
00481 }
00482
00483 }
00484
00485
00486
00487
00488
00489