00001
00062 #include "ros/ros.h"
00063 #include <sensor_msgs/JointState.h>
00064 #include <pr2_controllers_msgs/JointTrajectoryControllerState.h>
00065 #include <actionlib/server/simple_action_server.h>
00066 #include <pr2_controllers_msgs/JointTrajectoryAction.h>
00067 #include <brics_actuator/JointVelocities.h>
00068 #include <cob_trajectory_controller/genericArmCtrl.h>
00069
00070 #include <cob_srvs/Trigger.h>
00071 #include <cob_srvs/SetOperationMode.h>
00072
00073
00074
00075 #define HZ 100
00076
00077 class cob_trajectory_controller
00078 {
00079 private:
00080 ros::NodeHandle n_;
00081 ros::Publisher joint_pos_pub_;
00082 ros::Publisher joint_vel_pub_;
00083 ros::Subscriber controller_state_;
00084 ros::Subscriber operation_mode_;
00085 ros::ServiceServer srvServer_Stop_;
00086 ros::ServiceClient srvClient_SetOperationMode;
00087 actionlib::SimpleActionServer<pr2_controllers_msgs::JointTrajectoryAction> as_;
00088 std::string action_name_;
00089 std::string current_operation_mode_;
00090 bool executing_;
00091 int watchdog_counter;
00092 genericArmCtrl* traj_generator_;
00093 trajectory_msgs::JointTrajectory traj_;
00094 std::vector<double> q_current, startposition_, joint_distance_;
00095
00096 public:
00097 cob_trajectory_controller():as_(n_, "joint_trajectory_action", boost::bind(&cob_trajectory_controller::executeTrajectory, this, _1), true),
00098 action_name_("joint_trajectory_action")
00099 {
00100 joint_pos_pub_ = n_.advertise<sensor_msgs::JointState>("target_joint_pos", 1);
00101 joint_vel_pub_ = n_.advertise<brics_actuator::JointVelocities>("command_vel", 1);
00102 controller_state_ = n_.subscribe("state", 1, &cob_trajectory_controller::state_callback, this);
00103 operation_mode_ = n_.subscribe("current_operationmode", 1, &cob_trajectory_controller::operationmode_callback, this);
00104 srvServer_Stop_ = n_.advertiseService("stop", &cob_trajectory_controller::srvCallback_Stop, this);
00105 srvClient_SetOperationMode = n_.serviceClient<cob_srvs::SetOperationMode>("set_operation_mode");
00106 while(!srvClient_SetOperationMode.exists())
00107 {
00108 ROS_INFO("Waiting for operationmode service to become available");
00109 sleep(1);
00110 }
00111 executing_ = false;
00112 watchdog_counter = 0;
00113 current_operation_mode_ = "undefined";
00114 q_current.resize(7);
00115 traj_generator_ = new genericArmCtrl(7);
00116
00117 }
00118
00119 bool srvCallback_Stop(cob_srvs::Trigger::Request &req, cob_srvs::Trigger::Response &res)
00120 {
00121 ROS_INFO("Stopping powercubes...");
00122
00123
00124 executing_ = false;
00125 res.success.data = true;
00126 ROS_INFO("...stopping cob_trajectory_controller.");
00127 traj_generator_->isMoving = false;
00128
00129 return true;
00130 }
00131
00132 void operationmode_callback(const std_msgs::StringPtr& message)
00133 {
00134 current_operation_mode_ = message->data;
00135 }
00136 void state_callback(const pr2_controllers_msgs::JointTrajectoryControllerStatePtr& message)
00137 {
00138 std::vector<double> positions = message->actual.positions;
00139 for(unsigned int i = 0; i < positions.size(); i++)
00140 {
00141 q_current[i] = positions[i];
00142 }
00143 }
00144 void executeTrajectory(const pr2_controllers_msgs::JointTrajectoryGoalConstPtr &goal)
00145 {
00146 ROS_INFO("Received new goal trajectory with %d points",goal->trajectory.points.size());
00147 if(!executing_)
00148 {
00149
00150 cob_srvs::SetOperationMode opmode;
00151 opmode.request.operation_mode.data = "velocity";
00152 srvClient_SetOperationMode.call(opmode);
00153 while(current_operation_mode_ != "velocity")
00154 {
00155 ROS_INFO("waiting for arm to go to velocity mode");
00156 usleep(100000);
00157 }
00158 traj_ = goal->trajectory;
00159 if(traj_.points.size() == 1)
00160 {
00161 traj_generator_->moveThetas(traj_.points[0].positions, q_current);
00162 }
00163 else
00164 {
00165
00166 trajectory_msgs::JointTrajectoryPoint p;
00167 p.positions.resize(7);
00168 p.velocities.resize(7);
00169 p.accelerations.resize(7);
00170 for(unsigned int i = 0; i<7; i++)
00171 {
00172 p.positions.at(i) = q_current.at(i);
00173 p.velocities.at(i) = 0.0;
00174 p.accelerations.at(i) = 0.0;
00175 }
00176 std::vector<trajectory_msgs::JointTrajectoryPoint>::iterator it;
00177 it = traj_.points.begin();
00178 traj_.points.insert(it,p);
00179 traj_generator_->moveTrajectory(traj_, q_current);
00180 }
00181 executing_ = true;
00182 startposition_ = q_current;
00183
00184
00185 }
00186 else
00187 {
00188
00189 }
00190 while(executing_)
00191 {
00192 sleep(1);
00193 }
00194 as_.setSucceeded();
00195 }
00196
00197 void run()
00198 {
00199 if(executing_)
00200 {
00201 watchdog_counter = 0;
00202 if (as_.isPreemptRequested() || !ros::ok() || current_operation_mode_ != "velocity")
00203 {
00204
00205
00206 executing_ = false;
00207 traj_generator_->isMoving = false;
00208
00209 ROS_INFO("Preempted trajectory action");
00210 return;
00211 }
00212 std::vector<double> des_vel;
00213 if(traj_generator_->step(q_current, des_vel))
00214 {
00215 if(!traj_generator_->isMoving)
00216 {
00217 executing_ = false;
00218 }
00219 brics_actuator::JointVelocities target_joint_vel;
00220 target_joint_vel.velocities.resize(7);
00221 for(unsigned int i=0; i<7; i++)
00222 {
00223 std::stringstream joint_name;
00224 joint_name << "arm_" << (i+1) << "_joint";
00225 target_joint_vel.velocities[i].joint_uri = joint_name.str();
00226 target_joint_vel.velocities[i].unit = "rad";
00227 target_joint_vel.velocities[i].value = des_vel.at(i);
00228
00229 }
00230
00231
00232 joint_vel_pub_.publish(target_joint_vel);
00233 }
00234 else
00235 {
00236 ROS_INFO("An controller error occured!");
00237 executing_ = false;
00238 }
00239 }
00240 else
00241 {
00242 if(watchdog_counter < 10)
00243 {
00244 sensor_msgs::JointState target_joint_position;
00245 target_joint_position.position.resize(7);
00246 brics_actuator::JointVelocities target_joint_vel;
00247 target_joint_vel.velocities.resize(7);
00248 for (unsigned int i = 0; i < 7; i += 1)
00249 {
00250 std::stringstream joint_name;
00251 joint_name << "arm_" << (i+1) << "_joint";
00252 target_joint_vel.velocities[i].joint_uri = joint_name.str();
00253 target_joint_position.position[i] = 0;
00254 target_joint_vel.velocities[i].unit = "rad";
00255 target_joint_vel.velocities[i].value = 0;
00256 }
00257 joint_vel_pub_.publish(target_joint_vel);
00258 joint_pos_pub_.publish(target_joint_position);
00259 }
00260 watchdog_counter++;
00261 }
00262 }
00263
00264 };
00265
00266
00267
00268 int main(int argc, char ** argv)
00269 {
00270 ros::init(argc, argv, "cob_trajectory_controller");
00271 cob_trajectory_controller tm;
00272 ros::Rate loop_rate(HZ);
00273 while (ros::ok())
00274 {
00275 tm.run();
00276 ros::spinOnce();
00277 loop_rate.sleep();
00278 }
00279
00280 }
00281
00282
00283
00284
00285
00286