Go to the documentation of this file.00001
00002
00003 #include "ros/ros.h"
00004 #include "std_msgs/Bool.h"
00005 #include "std_srvs/Empty.h"
00006 #include "brics_actuator/JointPositions.h"
00007 #include "sensor_msgs/JointState.h"
00008 #include "geometry_msgs/Twist.h"
00009 #include "control_msgs/FollowJointTrajectoryActionGoal.h"
00010 #include "move_base_msgs/MoveBaseActionGoal.h"
00011 #include "actionlib_msgs/GoalID.h"
00012
00013 #include <boost/units/systems/si/length.hpp>
00014 #include <boost/units/systems/si/plane_angle.hpp>
00015 #include <boost/units/io.hpp>
00016 #include <boost/units/systems/angle/degrees.hpp>
00017 #include <boost/units/conversion.hpp>
00018
00019 #include <iostream>
00020 #include <math.h>
00021 #include <unistd.h>
00022
00023 using namespace std;
00024
00025 ros::Publisher cmd_vel_pub;
00026 ros::Publisher arm_pub;
00027 ros::Publisher gripper_pub;
00028 ros::Publisher trajectory_cancel_pub;
00029 ros::Publisher move_base_cancel_pub;
00030
00031 bool received_trajectory=false;
00032 std::string lastGoalID;
00033 bool received_move_base=false;
00034 std::string lastBaseGoalID;
00035
00036 double joint[5];
00037 double gripperr = 0;
00038 double gripperl = 0;
00039
00040 bool has_received_heartbeat=false;
00041 int heartbeat_timeout=0;
00042 const int heartbeat_timeout_max=50;
00043 bool bad=false;
00044
00045 ros::Time last_heartbeat_time;
00046
00047 void armCallback(const sensor_msgs::JointState::ConstPtr& msg)
00048 {
00049 if (msg->position.size()!=7) {
00050 if (msg->position.size()!=8) ROS_WARN_STREAM("Wrong number of joints in JointState message: " << msg->position.size() << ", expected 7");
00051 return;
00052 }
00053 joint[0] = msg->position[0];
00054 joint[1] = msg->position[1];
00055 joint[2] = msg->position[2];
00056 joint[3] = msg->position[3];
00057 joint[4] = msg->position[4];
00058
00059 gripperl = msg->position[5];
00060 gripperr = msg->position[6];
00061 }
00062
00063 void trajectoryCallback(const control_msgs::FollowJointTrajectoryActionGoal::ConstPtr& msg) {
00064 received_trajectory=true;
00065 lastGoalID = msg->goal_id.id;
00066 }
00067
00068 void moveBaseCallback(const move_base_msgs::MoveBaseActionGoal::ConstPtr& msg)
00069 {
00070 received_move_base=true;
00071 lastBaseGoalID = msg->goal_id.id;
00072 }
00073
00074 void heartbeatCallback(const std_msgs::Bool::ConstPtr& msg)
00075 {
00076 ros::Time now = ros::Time::now();
00077 if (!has_received_heartbeat) ROS_INFO("Got first heartbeat");
00078 else {
00079
00080 double secs = (now-last_heartbeat_time).toSec();
00081 if (secs>=heartbeat_timeout_max*0.01)
00082 {
00083 ROS_WARN_STREAM("Got heartbeat " << (now-last_heartbeat_time).toSec() << " seconds after last");
00084
00085
00086 std_srvs::Empty::Request req;
00087 std_srvs::Empty::Response res;
00088 if (ros::service::call("/reconnect",req,res)) {
00089 bad=false;
00090 now=ros::Time::now();
00091 }
00092 }
00093 else
00094 {
00095 ROS_INFO_STREAM("Got heartbeat " << (now-last_heartbeat_time).toSec() << " seconds after last");
00096 }
00097 }
00098 has_received_heartbeat=true;
00099 heartbeat_timeout=0;
00100 last_heartbeat_time=now;
00101 }
00102
00103 int main(int argc, char **argv)
00104 {
00105 ros::init(argc, argv, "youbot_network_estopper");
00106
00107 ros::NodeHandle n;
00108 ROS_INFO("Starting network estopper");
00109 std::fill_n(joint, 5, 0);
00110 gripperl = 0;
00111 gripperr = 0;
00112
00113 ROS_INFO("Subscribing to heartbeat");
00114 ros::Subscriber heartbeatSubscriber;
00115 heartbeatSubscriber = n.subscribe("youbot_network_estopper/heartbeat",1,heartbeatCallback);
00116
00117 ROS_INFO("Subscribing to joint states");
00118 ros::Subscriber armPositionSubscriber;
00119 armPositionSubscriber = n.subscribe("joint_states", 1, armCallback);
00120
00121 ROS_INFO("Subscribing to trajectory follower");
00122 ros::Subscriber jointFollowerSubscriber;
00123 jointFollowerSubscriber = n.subscribe("arm_1/arm_controller/follow_joint_trajectory/goal",1,trajectoryCallback);
00124
00125 ROS_INFO("Subscribing to move base commands");
00126 ros::Subscriber moveBaseSubscriber;
00127 moveBaseSubscriber = n.subscribe("move_base/goal", 1, moveBaseCallback);
00128
00129 ROS_INFO("Advertising publishers");
00130 cmd_vel_pub = n.advertise<geometry_msgs::Twist>("cmd_vel",1);
00131 arm_pub = n.advertise<brics_actuator::JointPositions>("arm_1/arm_controller/position_command", 1);
00132 gripper_pub = n.advertise<brics_actuator::JointPositions>("arm_1/gripper_controller/position_command", 1);
00133 trajectory_cancel_pub = n.advertise<actionlib_msgs::GoalID>("arm_1/arm_controller/follow_joint_trajectory/cancel",1);
00134 move_base_cancel_pub = n.advertise<actionlib_msgs::GoalID>("move_base/cancel",1);
00135
00136 ros::Rate rate(100);
00137
00138 while (n.ok()){
00139
00140 if (bad) {
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 if (received_trajectory) {
00186 actionlib_msgs::GoalID goal_id;
00187 goal_id.id=lastGoalID;
00188 trajectory_cancel_pub.publish(goal_id);
00189 }
00190
00191 if (received_move_base) {
00192 actionlib_msgs::GoalID goal_id;
00193 goal_id.id=lastBaseGoalID;
00194 move_base_cancel_pub.publish(goal_id);
00195 }
00196
00197
00198 std_srvs::Empty empty;
00199 ros::service::call("arm_1/switchOffMotors", empty);
00200 ros::service::call("base/switchOffMotors", empty);
00201
00202 ros::spinOnce();
00203
00204
00205
00206 }
00207
00208 if (has_received_heartbeat && !bad) {
00209 heartbeat_timeout++;
00210 if (heartbeat_timeout>heartbeat_timeout_max)
00211 {
00212 ROS_ERROR("HEARTBEAT TIMED OUT, spewing stop commands");
00213 bad=true;
00214 }
00215 }
00216
00217 ros::spinOnce();
00218 rate.sleep();
00219 }
00220
00221 return 0;
00222 }