ArmJointStateSubscriber.cpp
Go to the documentation of this file.
00001 #ifdef DOXYGEN_SHOULD_SKIP_THIS
00002 
00021 #endif
00022 
00023 #include <arm_components_name_manager/ArmJointStateSubscriber.h>
00024 
00025 #define CHECK_UPDATE_RATE 50
00026 
00027 using arm_components_name_manager::ArmJointStateSubscriber;
00028 
00029 ArmJointStateSubscriber::ArmJointStateSubscriber(const ArmComponentsNameManager& _manager,
00030         ros::NodeHandle& n, const std::string& joint_states_topic):
00031     jointsManager(_manager),
00032     node(n),
00033     valid_arm(false),
00034     valid_grippers(false),
00035     // subscriber(n),
00036     subscriberActive(false),
00037     last_update_time(0)
00038 {
00039     subscriber = node.subscribe(joint_states_topic, 1000, &ArmJointStateSubscriber::callback, this);
00040 /*    subscriber.start(joint_states_topic);
00041     update_connection = n.createTimer(ros::Duration(1.0 / CHECK_UPDATE_RATE), &ArmJointStateSubscriber::process, this);*/
00042 }
00043 ArmJointStateSubscriber::~ArmJointStateSubscriber() {}
00044 
00045 void ArmJointStateSubscriber::setActive(bool flag)
00046 {
00047     unique_lock lock(mutex);
00048     subscriberActive = flag;
00049     // subscriber.setActive(flag);
00050 }
00051 
00052 bool ArmJointStateSubscriber::isActive() const
00053 {
00054     unique_lock lock(mutex);
00055     return subscriberActive;
00056     // return subscriber.isActive();
00057 }
00058 
00059 bool ArmJointStateSubscriber::waitForUpdate(float timeout, float checkStepTime) const
00060 {
00061     if (!isActive())
00062     {
00063         ROS_ERROR("Called ArmJointStateSubscriber::waitForUpdate() without calling ArmJointStateSubscriber::setActive(true) first");
00064         return false;
00065     }
00066     ros::Time start_time = ros::Time::now();
00067     float time_waited=0;
00068     while ((getLastUpdateTime() < start_time) && ((timeout < 0) || (time_waited < timeout)))
00069     {
00070         ROS_INFO("ArmJointStateSubscriber: Waiting...");
00071         // spin once so that callback() may still be called by the subscriber
00072         // in case the node is not running in multi-threaded mode.
00073         ros::spinOnce();
00074         ros::Duration(checkStepTime).sleep();
00075         ros::Time curr_time = ros::Time::now();
00076         time_waited = (curr_time - start_time).toSec();
00077     }
00078     if (getLastUpdateTime() >= start_time) return true;
00079     return false;
00080 }
00081 
00082 ros::Time ArmJointStateSubscriber::getLastUpdateTime() const
00083 {
00084     unique_lock lock(mutex);
00085     return last_update_time;
00086 }
00087 
00088 std::vector<float> ArmJointStateSubscriber::armAngles(bool& valid) const
00089 {
00090     unique_lock lock(mutex);
00091     valid = valid_arm;
00092     if (!valid) ROS_WARN("Arm angles were not complete in the last joint state callback");
00093     return arm_angles;
00094 }
00095 
00096 std::vector<float> ArmJointStateSubscriber::gripperAngles(bool& valid) const
00097 {
00098     unique_lock lock(mutex);
00099     valid = valid_grippers;
00100     if (!valid) ROS_WARN("Gripper angles were not complete in the last joint state callback");
00101     return gripper_angles;
00102 }
00103 
00104 std::string ArmJointStateSubscriber::toString() const
00105 {
00106     unique_lock lock(mutex);
00107     std::stringstream str;
00108     str << "Arm (valid=" << valid_arm << "): ";
00109     for (int i = 0; i < arm_angles.size(); ++i) str << arm_angles[i] << " / ";
00110     str << " Gripper (valid=" << valid_grippers << "): ";
00111     for (int i = 0; i < gripper_angles.size(); ++i) str << gripper_angles[i] << " / ";
00112     return str.str();
00113 }
00114 
00115 
00116 void ArmJointStateSubscriber::callback(const sensor_msgs::JointState& msg)
00117 //void ArmJointStateSubscriber::process(const ros::TimerEvent& t)
00118 {
00119     if (!isActive()) return;
00120 
00121     /*
00122     // get the newest message
00123     sensor_msgs::JointState msg;
00124     float rate = 1.0 / CHECK_UPDATE_RATE;
00125     float timeout = 5 * rate;
00126     float checkStepTime = timeout / 4.0;
00127     bool gotMessage = subscriber.waitForNextMessage(msg, timeout, checkStepTime);
00128     // do another thread loop, no new message has arrived so far
00129     if (!gotMessage) return;
00130     // ROS_INFO("Processing...");   
00131     */
00132 
00133     std::vector<int> idx;
00134     // Get joint indices in msg.
00135     // Returns 0 if all joints present, 1 if only arm joints present, and 2 if only gripper joints present.
00136     int idxGroup = jointsManager.getJointIndices(msg.name, idx);
00137 
00138     if (idxGroup < 0)
00139     {
00140         ROS_WARN("Could not obtain indices of the arm joints in joint state, skipping it.");
00141         return;
00142     }
00143 
00144     int numArmJnts = jointsManager.numArmJoints();
00145     int numGripperJnts = jointsManager.numGripperJoints();
00146 
00147     int numJnts = numArmJnts + numGripperJnts;
00148     if (idx.size() != numJnts)
00149     {
00150         ROS_ERROR("Inconsistency: joint_indices should be same size as all arm joints");
00151         return;
00152     }   
00153 
00154     unique_lock lock(mutex);
00155     bool _valid_grippers = false;
00156     bool _valid_arm = false;
00157 
00158     if ((idxGroup == 0) || (idxGroup == 1))
00159     {
00160         arm_angles.assign(numArmJnts, 0);
00161         bool allFound = true;
00162         for (int i = 0; i < numArmJnts; ++i)
00163         {
00164             if (idx[i] < 0)
00165             {
00166                 ROS_ERROR_STREAM("Arm joint "<<i<<" was not in joint state");
00167                 allFound = false;
00168                 continue;
00169             }
00170             if (msg.position.size() <= idx[i])
00171             {
00172                 ROS_ERROR_STREAM("Inconsistency: position size in message is "
00173                     <<msg.position.size()<<"< tying to index "<<idx[i]);
00174                 allFound = false;
00175                 continue;
00176             }
00177             arm_angles[i] = msg.position[idx[i]];
00178         }
00179         _valid_arm = allFound;
00180     }
00181 
00182     if ((idxGroup == 0) || (idxGroup == 2))
00183     {
00184         gripper_angles.assign(numGripperJnts, 0);
00185         bool allFound = true;
00186         int startIt = 0;
00187         if (idxGroup == 0) startIt = numArmJnts;
00188         for (int i = startIt; i < numJnts; ++i)
00189         {
00190             if (idx[i] < 0)
00191             {
00192                 ROS_ERROR_STREAM("Gripper joint " << (i - startIt) << " was not in joint state");
00193                 allFound = false;
00194                 continue;
00195             }
00196             if ((i-startIt) >= gripper_angles.size())
00197             {
00198                 ROS_ERROR_STREAM("Consistency: index of gripper is too large. startIt="<<startIt<<", i="<<i);
00199                 allFound = false;
00200                 continue;
00201             }
00202             if (msg.position.size() <= idx[i])
00203             {
00204                 ROS_ERROR_STREAM("Inconsistency: position size in message is "
00205                     <<msg.position.size()<<"< tying to index "<<idx[i]);
00206                 allFound = false;
00207                 continue;
00208             }
00209             // ROS_INFO_STREAM("Grippers at "<<i-startIt);
00210             // ROS_INFO_STREAM("msg pos: "<<msg.position[idx[i]]);
00211             gripper_angles[i-startIt] = msg.position[idx[i]];
00212         }
00213         _valid_grippers = allFound;
00214     }
00215 
00216     if (_valid_grippers || _valid_arm)
00217     {
00218         // Some joints were present, so assuming that we got a message related to this arm.
00219         // Otherwise, maybe this was just a joint state from another package.
00220         // Then, leave the current states untouched.
00221         valid_grippers = _valid_grippers;
00222         valid_arm = _valid_arm;
00223     }
00224     last_update_time = ros::Time::now();
00225 }


arm_components_name_manager
Author(s): Jennifer Buehler
autogenerated on Sat Mar 2 2019 03:21:40