collision_monitor.cpp
Go to the documentation of this file.
00001 #include <numeric>
00002 #include <math.h>
00003 
00004 #include <ros/ros.h>
00005 #include <trajectory_msgs/JointTrajectory.h>
00006 #include <std_msgs/Bool.h>
00007 #include <std_srvs/Empty.h>
00008 
00009 #include <pr2_collision_monitor/FingerState.h>
00010 #include <pr2_collision_monitor/FingerStateSrv.h>
00011 #include <pr2_collision_monitor/StartMonitor.h>
00012 #include <pr2_collision_monitor/JointDetectionStart.h>
00013 #include <sensor_msgs/JointState.h>
00014 
00015 using namespace std;
00016 using namespace boost;
00017 
00018 namespace pr2_collision_monitor {
00019 
00020     int JOINTSTATE_INDS_R[] = {17, 18, 16, 20, 19, 21, 22};
00021     int JOINTSTATE_INDS_L[] = {29, 30, 28, 32, 31, 33, 34};
00022     string JOINTNAMES[] = { "_shoulder_pan_joint",
00023                             "_shoulder_lift_joint",
00024                             "_upper_arm_roll_joint",
00025                             "_elbow_flex_joint",
00026                             "_forearm_roll_joint",
00027                             "_wrist_flex_joint",
00028                             "_wrist_roll_joint" };
00029 
00030     class CollisionMonitor {
00031         public:
00032             ros::NodeHandle nh;
00033             ros::ServiceServer start_srv, stop_srv;
00034             ros::ServiceClient joint_start_cli, joint_stop_cli;
00035             ros::Subscriber finger_coll_sub, joint_coll_sub, force_coll_sub, state_sub;
00036             ros::Publisher arm_stop_pub, collision_pub, heartbeat_pub;
00037             std::string arm;
00038             bool detection_on, joint_on, finger_on, force_on;
00039             double finger_last_time, joint_last_time, force_last_time;
00040             vector<double> cur_joint_pos;
00041 
00042             CollisionMonitor();
00043             void onInit();
00044             void fingerCollCallback(const std_msgs::Bool& msg);
00045             void jointCollCallback(const std_msgs::Bool& msg);
00046             void forceCollCallback(const std_msgs::Bool& msg);
00047             void stateCallback(sensor_msgs::JointState::ConstPtr);
00048             bool srvStartDetection(StartMonitor::Request&, 
00049                                    StartMonitor::Response&);
00050             bool srvStopDetection(std_srvs::Empty::Request&, std_srvs::Empty::Response&);
00051             void collisionProcess();
00052             void spinMonitor();
00053     };
00054 
00055     CollisionMonitor::CollisionMonitor() : nh("~"), cur_joint_pos(7) {
00056     }
00057 
00058     void CollisionMonitor::onInit() {
00059         nh.param<std::string>("arm", arm, std::string("r"));
00060 
00061         start_srv = nh.advertiseService("start_monitoring", 
00062                                              &CollisionMonitor::srvStartDetection, this);
00063         ROS_INFO("[collision_monitor] Service advertised at start_monitoring");
00064         stop_srv = nh.advertiseService("stop_monitoring", 
00065                                             &CollisionMonitor::srvStopDetection, this);
00066         ROS_INFO("[collision_monitor] Service advertised at stop_monitoring");
00067         joint_start_cli = nh.serviceClient<JointDetectionStart>(
00068                              "/" + arm + "_joint_coll_detect/start_detection", false);
00069         joint_stop_cli = nh.serviceClient<std_srvs::Empty>(
00070                              "/" + arm + "_joint_coll_detect/stop_detection", false);
00071 
00072         finger_coll_sub = nh.subscribe("/" + arm + "_fingertip_monitor/collision_detected", 1, 
00073                                        &CollisionMonitor::fingerCollCallback, this);
00074         joint_coll_sub = nh.subscribe(
00075                             "/" + arm + "_joint_coll_detect/arm_collision_detected", 1, 
00076                             &CollisionMonitor::jointCollCallback, this);
00077         force_coll_sub = nh.subscribe("/force_torque_monitor/collision_detected", 1, 
00078                                       &CollisionMonitor::forceCollCallback, this);
00079         state_sub = nh.subscribe("/joint_states", 2, 
00080                                  &CollisionMonitor::stateCallback, this);
00081         arm_stop_pub = nh.advertise<trajectory_msgs::JointTrajectory>(
00082                                                  "/" + arm + "_arm_controller/command", 1);
00083         // silent topic until a collision is detected
00084         collision_pub = nh.advertise<std_msgs::Bool>("collision_detected", 1);
00085         // publishes a boolean at 100hz which is false while detection is running and
00086         // true otherwise
00087         heartbeat_pub = nh.advertise<std_msgs::Bool>("collision_heartbeat", 1);
00088 
00089         ros::Duration(0.3).sleep();
00090         ROS_INFO("[collision_monitor] CollisionMonitor loaded.");
00091     }
00092 
00093     void CollisionMonitor::jointCollCallback(const std_msgs::Bool& msg) {
00094         if(detection_on && joint_on) {
00095             if(msg.data) {
00096                 ROS_INFO("[collision_monitor] Joint collision detected, stopping arm...");
00097                 collisionProcess();
00098             }
00099             joint_last_time = ros::Time::now().toSec();
00100         }
00101     }
00102 
00103     void CollisionMonitor::fingerCollCallback(const std_msgs::Bool& msg) {
00104         if(detection_on && finger_on) {
00105             if(msg.data) {
00106                 ROS_INFO("[collision_monitor] Finger collision detected, stopping arm...");
00107                 collisionProcess();
00108             }
00109             finger_last_time = ros::Time::now().toSec();
00110         }
00111     }
00112 
00113     void CollisionMonitor::forceCollCallback(const std_msgs::Bool& msg) {
00114         if(detection_on && force_on) {
00115             if(msg.data) {
00116                 ROS_INFO("[collision_monitor] Force collision detected, stopping arm...");
00117                 collisionProcess();
00118             }
00119             force_last_time = ros::Time::now().toSec();
00120         }
00121     }
00122 
00123     void CollisionMonitor::stateCallback(
00124             sensor_msgs::JointState::ConstPtr msg) {
00125         for(uint32_t i=0;i<7;i++) {
00126             int msg_ind;
00127             if(arm == "r")
00128                 msg_ind = JOINTSTATE_INDS_R[i];
00129             else
00130                 msg_ind = JOINTSTATE_INDS_L[i];
00131             cur_joint_pos[i] = msg->position[msg_ind];
00132         }
00133     }
00134 
00135     bool CollisionMonitor::srvStartDetection(StartMonitor::Request& req,
00136                                              StartMonitor::Response& resp) {
00137         joint_on = req.joint_detect;
00138         finger_on = req.finger_detect;
00139         force_on = req.force_detect;
00140 
00141         joint_last_time = ros::Time::now().toSec();
00142         finger_last_time = ros::Time::now().toSec();
00143         force_last_time = ros::Time::now().toSec();
00144         JointDetectionStart::Request jds_req; JointDetectionStart::Response jds_resp;
00145         joint_start_cli.call(jds_req, jds_resp);
00146         detection_on = true;
00147         return true;
00148     }
00149 
00150     bool CollisionMonitor::srvStopDetection(std_srvs::Empty::Request& req, 
00151                                             std_srvs::Empty::Response& resp) {
00152         ROS_INFO("[collision_monitor] Stop detection service called.");
00153         joint_stop_cli.call(req, resp);
00154         detection_on = false;
00155         return true;
00156     }
00157 
00158     void CollisionMonitor::collisionProcess() {
00159         if(detection_on) {
00160             detection_on = false;
00161             // publish collision message
00162             std_msgs::Bool coll_msg; coll_msg.data = true; collision_pub.publish(coll_msg);
00163 
00164             // turn off joint collision detection
00165             std_srvs::Empty::Request req; std_srvs::Empty::Response resp;
00166             joint_stop_cli.call(req, resp);
00167 
00168             // stop arm at current joint angles
00169             /* TODO LEAVE OR KEEP? TODO
00170             trajectory_msgs::JointTrajectory stop_arm_msg;
00171             stop_arm_msg.header.stamp = ros::Time::now() + ros::Duration(0.03);
00172             stop_arm_msg.points.resize(1);
00173             stop_arm_msg.joint_names.resize(7);
00174             for(uint32_t i=0;i<7;i++)
00175                 stop_arm_msg.joint_names[i] = arm + JOINTNAMES[i];
00176             stop_arm_msg.points[0].positions.resize(7);
00177             copy(cur_joint_pos.begin(), cur_joint_pos.end(), 
00178                  stop_arm_msg.points[0].positions.begin());
00179             stop_arm_msg.points[0].velocities.resize(7);
00180             stop_arm_msg.points[0].accelerations.resize(7);
00181             arm_stop_pub.publish(stop_arm_msg);
00182             */
00183         }
00184     }
00185 
00190     void CollisionMonitor::spinMonitor() {
00191         ros::Rate r(100);
00192         while(ros::ok()) {
00193             ros::spinOnce();
00194             if(detection_on) {
00195                 if(joint_on && ros::Time::now().toSec() - joint_last_time > 0.15) {
00196                     ROS_INFO("[collision_monitor] Joint detection timeout, stopping...");
00197                     collisionProcess();
00198                 }
00199                 if(finger_on && ros::Time::now().toSec() - finger_last_time > 0.15) {
00200                     ROS_INFO("[collision_monitor] Finger detection timeout, stopping...");
00201                     collisionProcess();
00202                 }
00203                 if(force_on && ros::Time::now().toSec() - force_last_time > 0.15) {
00204                     ROS_INFO("[collision_monitor] Force detection timeout, stopping...");
00205                     collisionProcess();
00206                 }
00207             }
00208             // publish a simple boolean at 100hz which is only false when detection is
00209             // running and no collision is detected
00210             std_msgs::Bool heartbeat_msg; heartbeat_msg.data = !detection_on;
00211             heartbeat_pub.publish(heartbeat_msg);
00212             r.sleep();
00213         }
00214     }
00215 
00216 };
00217 
00218 using namespace pr2_collision_monitor;
00219 
00220 int main(int argc, char **argv)
00221 {
00222     ros::init(argc, argv, "collision_monitor", ros::init_options::AnonymousName);
00223     CollisionMonitor cm;
00224     cm.onInit();
00225     cm.spinMonitor();
00226     return 0;
00227 }
00228 


pr2_collision_monitor
Author(s): Kelsey Hawkins, Advisor: Prof. Charlie Kemp (Healthcare Robotics Lab at Georgia Tech)
autogenerated on Wed Nov 27 2013 11:40:10