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
00084 collision_pub = nh.advertise<std_msgs::Bool>("collision_detected", 1);
00085
00086
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
00162 std_msgs::Bool coll_msg; coll_msg.data = true; collision_pub.publish(coll_msg);
00163
00164
00165 std_srvs::Empty::Request req; std_srvs::Empty::Response resp;
00166 joint_stop_cli.call(req, resp);
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
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
00209
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