Go to the documentation of this file.00001 #include <numeric>
00002 #include <math.h>
00003
00004 #include <ros/ros.h>
00005 #include <sensor_msgs/JointState.h>
00006 #include <std_msgs/Bool.h>
00007
00008 #include <pr2_collision_monitor/ArmMovingWait.h>
00009
00010 using namespace std;
00011
00012 namespace pr2_collision_monitor {
00013
00014 class ArmMovingWaitServer {
00015 public:
00016 ArmMovingWaitServer();
00017 void onInit();
00018 ~ArmMovingWaitServer();
00019
00020 protected:
00021 ros::NodeHandle nh;
00022 ros::NodeHandle nh_priv;
00023 ros::Publisher moving_pub;
00024 std::string arm;
00025 bool arm_is_moving;
00026 vector<vector<float> > joint_pos_past;
00027 int step;
00028 bool srvCheckArmMoving(ArmMovingWait::Request&, ArmMovingWait::Response&);
00029 void stateCallback(sensor_msgs::JointState::ConstPtr);
00030 ros::Subscriber state_sub;
00031 ros::ServiceServer moving_srv;
00032 };
00033
00034 ArmMovingWaitServer::ArmMovingWaitServer() : nh_priv("~"),
00035 arm_is_moving(true),
00036 joint_pos_past(7),
00037 step(0) {
00038 for(int i=0;i<7;i++)
00039 joint_pos_past[i].resize(10);
00040 onInit();
00041 }
00042
00043 void ArmMovingWaitServer::onInit() {
00044 nh_priv.param<std::string>("arm", arm, std::string("r"));
00045 moving_srv = nh_priv.advertiseService("arm_moving_wait",
00046 &ArmMovingWaitServer::srvCheckArmMoving, this);
00047 ROS_INFO("[arm_moving_server] Service advertised at arm_moving_wait");
00048 state_sub = nh.subscribe("/joint_states", 2,
00049 &ArmMovingWaitServer::stateCallback, this);
00050 moving_pub = nh_priv.advertise<std_msgs::Bool>("arm_moving", 1);
00051 }
00052
00053 bool ArmMovingWaitServer::srvCheckArmMoving(ArmMovingWait::Request& req, ArmMovingWait::Response& resp) {
00054 if(!req.block) {
00055 resp.is_moving = arm_is_moving;
00056 return true;
00057 }
00058 ros::Rate r(100);
00059 double start_time = ros::Time::now().toSec();
00060 while(ros::ok() && arm_is_moving &&
00061 ros::Time::now().toSec() - start_time < req.timeout) {
00062 ros::spinOnce();
00063 r.sleep();
00064 }
00065 resp.is_moving = arm_is_moving;
00066 return true;
00067 }
00068
00069 int JOINTSTATE_INDS_R[] = {17, 18, 16, 20, 19, 21, 22};
00070 int JOINTSTATE_INDS_L[] = {29, 30, 28, 32, 31, 33, 34};
00071
00072 void ArmMovingWaitServer::stateCallback(
00073 sensor_msgs::JointState::ConstPtr msg) {
00074
00075 bool arm_still_moving = false;
00076 for(int i=0;i<7;i++) {
00077 int msg_ind;
00078 if(arm == "r")
00079 msg_ind = JOINTSTATE_INDS_R[i];
00080 else
00081 msg_ind = JOINTSTATE_INDS_L[i];
00082 joint_pos_past[i][step%10] = msg->position[msg_ind];
00083 if(step < 10)
00084 continue;
00085 for(int j=0;j<10;j++)
00086 if(std::fabs(msg->position[msg_ind] - joint_pos_past[i][j]) > 0.001) {
00087 arm_still_moving = true;
00088 }
00089 }
00090 arm_is_moving = arm_still_moving;
00091 std_msgs::Bool moving_msg;
00092 moving_msg.data = arm_is_moving;
00093 moving_pub.publish(moving_msg);
00094 step++;
00095 }
00096
00097 ArmMovingWaitServer::~ArmMovingWaitServer() {
00098 }
00099
00100 };
00101
00102 int main(int argc, char **argv)
00103 {
00104 ros::init(argc, argv, "arm_moving_server", ros::init_options::AnonymousName);
00105 pr2_collision_monitor::ArmMovingWaitServer amws;
00106 ros::spin();
00107 return 0;
00108 }
00109