MultiJointTrackerNode.cpp
Go to the documentation of this file.
00001 #include <boost/foreach.hpp>
00002 
00003 #include "joint_tracker/MultiJointTrackerNode.h"
00004 #include "joint_tracker/MultiJointTracker.h"
00005 
00006 #include "geometry_msgs/PoseArray.h"
00007 
00008 #include <vector>
00009 
00010 #include <geometry_msgs/PoseWithCovarianceStamped.h>
00011 
00012 #include <stdio.h>
00013 
00014 #include <rosbag/message_instance.h>
00015 
00016 #include <rosbag/query.h>
00017 
00018 #include <rosbag/view.h>
00019 
00020 #include <ros/package.h>
00021 
00022 #include <Eigen/Eigen>
00023 
00024 #include <Eigen/Geometry>
00025 
00026 #include <std_msgs/String.h>
00027 
00028 #include <sensor_msgs/JointState.h>
00029 
00030 #include <omip_msgs/JointMsg.h>
00031 
00032 #define LINES_OF_TERMINAL_JT 20
00033 
00034 using namespace omip;
00035 
00036 MultiJointTrackerNode::MultiJointTrackerNode() :
00037     RecursiveEstimatorNodeInterface(1),
00038     _loop_period_ns(0.),
00039     _sensor_fps(0.0),
00040     _processing_factor(0)
00041 
00042 {
00043     this->_namespace = std::string("joint_tracker");
00044     this->ReadParameters();
00045     this->_measurement_subscriber= this->_measurements_node_handle.subscribe( "/rb_tracker/state", 1, &MultiJointTrackerNode::measurementCallback, this);
00046 
00047     this->_state_publisher = this->_measurements_node_handle.advertise<omip_msgs::KinematicStructureMsg>(this->_namespace + "/state", 100);
00048 
00049     this->_state_publisher_rviz_markers = this->_measurements_node_handle.advertise<visualization_msgs::MarkerArray>(this->_namespace + "/markers", 100);
00050 
00051     this->_measurement_prediction_publisher = this->_measurements_node_handle.advertise<rbt_state_t>( "/rb_tracker/predicted_measurement", 100);
00052 
00053 
00054     this->_urdf_pub_service = this->_measurements_node_handle.advertiseService("/joint_tracker/urdf_publisher_srv", &MultiJointTrackerNode::publishURDF, this);
00055 
00056     this->_state_publisher_urdf = this->_measurements_node_handle.advertise<std_msgs::String>(this->_namespace + "/state_urdf", 100);
00057 
00058     this->_state_publisher_joint_states = this->_measurements_node_handle.advertise<sensor_msgs::JointState>(this->_namespace + "/joint_states", 100);
00059 
00060     // This is used to build URDF models that link to the reconstructed shapes
00061     this->_sr_path = ros::package::getPath("shape_reconstruction");
00062 
00063 }
00064 
00065 MultiJointTrackerNode::~MultiJointTrackerNode()
00066 {
00067 }
00068 
00069 void MultiJointTrackerNode::ReadParameters()
00070 {
00071     int ks_analysis_type;
00072     this->getROSParameter<int>(this->_namespace + std::string("/ks_analysis_type"), ks_analysis_type);
00073     double disconnected_j_ne;
00074     this->getROSParameter<double>(this->_namespace + std::string("/disconnected_ne"), disconnected_j_ne);
00075     int likelihood_sample_num;
00076     this->getROSParameter<int>(this->_namespace + std::string("/likelihood_sample_num"), likelihood_sample_num);
00077     double sigma_delta_meas_uncertainty_linear;
00078     this->getROSParameter<double>(this->_namespace + std::string("/sigma_delta_meas_uncertainty_linear"), sigma_delta_meas_uncertainty_linear);
00079     double sigma_delta_meas_uncertainty_angular;
00080     this->getROSParameter<double>(this->_namespace + std::string("/sigma_delta_meas_uncertainty_angular"), sigma_delta_meas_uncertainty_angular);
00081 
00082     double prism_prior_cov_vel;
00083     this->getROSParameter<double>(this->_namespace + std::string("/prism_prior_cov_vel"), prism_prior_cov_vel);
00084     double prism_sigma_sys_noise_phi;
00085     this->getROSParameter<double>(this->_namespace + std::string("/prism_sigma_sys_noise_phi"), prism_sigma_sys_noise_phi);
00086     double prism_sigma_sys_noise_theta;
00087     this->getROSParameter<double>(this->_namespace + std::string("/prism_sigma_sys_noise_theta"), prism_sigma_sys_noise_theta);
00088     double prism_sigma_sys_noise_pv;
00089     this->getROSParameter<double>(this->_namespace + std::string("/prism_sigma_sys_noise_pv"), prism_sigma_sys_noise_pv);
00090     double prism_sigma_sys_noise_pvd;
00091     this->getROSParameter<double>(this->_namespace + std::string("/prism_sigma_sys_noise_pvd"), prism_sigma_sys_noise_pvd);
00092     double prism_sigma_meas_noise;
00093     this->getROSParameter<double>(this->_namespace + std::string("/prism_sigma_meas_noise"), prism_sigma_meas_noise);
00094 
00095     double rev_prior_cov_vel;
00096     this->getROSParameter<double>(this->_namespace + std::string("/rev_prior_cov_vel"), rev_prior_cov_vel);
00097     double rev_sigma_sys_noise_phi;
00098     this->getROSParameter<double>(this->_namespace + std::string("/rev_sigma_sys_noise_phi"), rev_sigma_sys_noise_phi);
00099     double rev_sigma_sys_noise_theta;
00100     this->getROSParameter<double>(this->_namespace + std::string("/rev_sigma_sys_noise_theta"), rev_sigma_sys_noise_theta);
00101     double rev_sigma_sys_noise_px;
00102     this->getROSParameter<double>(this->_namespace + std::string("/rev_sigma_sys_noise_px"), rev_sigma_sys_noise_px);
00103     double rev_sigma_sys_noise_py;
00104     this->getROSParameter<double>(this->_namespace + std::string("/rev_sigma_sys_noise_py"), rev_sigma_sys_noise_py);
00105     double rev_sigma_sys_noise_pz;
00106     this->getROSParameter<double>(this->_namespace + std::string("/rev_sigma_sys_noise_pz"), rev_sigma_sys_noise_pz);
00107     double rev_sigma_sys_noise_rv;
00108     this->getROSParameter<double>(this->_namespace + std::string("/rev_sigma_sys_noise_rv"), rev_sigma_sys_noise_rv);
00109     double rev_sigma_sys_noise_rvd;
00110     this->getROSParameter<double>(this->_namespace + std::string("/rev_sigma_sys_noise_rvd"), rev_sigma_sys_noise_rvd);
00111     double rev_sigma_meas_noise;
00112     this->getROSParameter<double>(this->_namespace + std::string("/rev_sigma_meas_noise"), rev_sigma_meas_noise);
00113     double rev_min_rot_for_ee;
00114     this->getROSParameter<double>(this->_namespace + std::string("/rev_min_rot_for_ee"), rev_min_rot_for_ee);
00115     double rev_max_joint_distance_for_ee;
00116     this->getROSParameter<double>(this->_namespace + std::string("/rev_max_joint_distance_for_ee"), rev_max_joint_distance_for_ee);
00117 
00118     double rig_max_translation;
00119     this->getROSParameter<double>(this->_namespace + std::string("/rig_max_translation"), rig_max_translation);
00120     double rig_max_rotation;
00121     this->getROSParameter<double>(this->_namespace + std::string("/rig_max_rotation"), rig_max_rotation);
00122 
00123     this->getROSParameter<int>(this->_namespace + std::string("/min_joint_age_for_ee"), this->_min_joint_age_for_ee);
00124 
00125     this->getROSParameter<double>(std::string("/omip/sensor_fps"), this->_sensor_fps);
00126     this->getROSParameter<int>(std::string("/omip/processing_factor"), this->_processing_factor);
00127     this->_loop_period_ns = 1e9/(this->_sensor_fps/(double)this->_processing_factor);
00128 
00129     int min_num_frames_for_new_rb;
00130     this->getROSParameter<int>(std::string("/rb_tracker/min_num_frames_for_new_rb"), min_num_frames_for_new_rb);
00131 
00132     ROS_INFO_STREAM_NAMED( "MultiJointTrackerNode.ReadParameters", "MultiJointTrackerNode Parameters: " << std::endl << //
00133                            "\tType of kinematic analysis: " << ks_analysis_type << std::endl << //
00134                            "\tDisconnected joint normalized error (joint classification threshold): " << disconnected_j_ne << std::endl << //
00135                            "\tNumber of samples to estimate likelihood: " << likelihood_sample_num << std::endl << //
00136                            "\tSigma of the delta of measurements (linear): " << sigma_delta_meas_uncertainty_linear << std::endl << //
00137                            "\tSigma of the delta of measurements (angular): " << sigma_delta_meas_uncertainty_angular << std::endl <<
00138                            "\tSigma of the prior of the velocity prismatic joint: " << prism_prior_cov_vel << std::endl <<
00139                            "\tSigma of the system noise phi prismatic joint: " << prism_sigma_sys_noise_phi << std::endl <<
00140                            "\tSigma of the system noise theta prismatic joint: " << prism_sigma_sys_noise_theta << std::endl <<
00141                            "\tSigma of the system noise pv prismatic joint: " << prism_sigma_sys_noise_pv << std::endl <<
00142                            "\tSigma of the system noise pvd prismatic joint: " << prism_sigma_sys_noise_pvd << std::endl <<
00143                            "\tSigma of the measurement noise prismatic joint: " << prism_sigma_meas_noise << std::endl <<
00144                            "\tSigma of the prior of the velocity revolute joint: " << rev_prior_cov_vel << std::endl <<
00145                            "\tSigma of the system noise phi revolute joint: " << rev_sigma_sys_noise_phi << std::endl <<
00146                            "\tSigma of the system noise theta revolute joint: " << rev_sigma_sys_noise_theta << std::endl <<
00147                            "\tSigma of the system noise px revolute joint: " << rev_sigma_sys_noise_px << std::endl <<
00148                            "\tSigma of the system noise py revolute joint: " << rev_sigma_sys_noise_py << std::endl <<
00149                            "\tSigma of the system noise pz revolute joint: " << rev_sigma_sys_noise_pz << std::endl <<
00150                            "\tSigma of the system noise rv revolute joint: " << rev_sigma_sys_noise_rv << std::endl <<
00151                            "\tSigma of the system noise rvd revolute joint: " << rev_sigma_sys_noise_rvd << std::endl <<
00152                            "\tSigma of the measurement noise revolute joint: " << rev_sigma_meas_noise << std::endl <<
00153                            "\tMax translation to reject the rigid joint hyp: " << rig_max_translation << std::endl <<
00154                            "\tMax rotation to reject the rigid joint hyp: " << rig_max_rotation << std::endl <<
00155                            "\tMinimum joint age for ee: " << _min_joint_age_for_ee <<
00156                            "\tMinimum num frames for new rb: " << min_num_frames_for_new_rb
00157                            );
00158 
00159     this->_re_filter = new MultiJointTracker(this->_loop_period_ns, (ks_analysis_t)ks_analysis_type, disconnected_j_ne);
00160     this->_re_filter->setNumSamplesLikelihoodEstimation(likelihood_sample_num);
00161     this->_re_filter->setSigmaDeltaMeasurementUncertaintyLinear(sigma_delta_meas_uncertainty_linear);
00162     this->_re_filter->setSigmaDeltaMeasurementUncertaintyAngular(sigma_delta_meas_uncertainty_angular);
00163 
00164     this->_re_filter->setPrismaticPriorCovarianceVelocity(prism_prior_cov_vel);
00165     this->_re_filter->setPrismaticSigmaSystemNoisePhi(prism_sigma_sys_noise_phi);
00166     this->_re_filter->setPrismaticSigmaSystemNoiseTheta(prism_sigma_sys_noise_theta);
00167     this->_re_filter->setPrismaticSigmaSystemNoisePV(prism_sigma_sys_noise_pv);
00168     this->_re_filter->setPrismaticSigmaSystemNoisePVd(prism_sigma_sys_noise_pvd);
00169     this->_re_filter->setPrismaticSigmaMeasurementNoise(prism_sigma_meas_noise);
00170 
00171     this->_re_filter->setRevolutePriorCovarianceVelocity(rev_prior_cov_vel);
00172     this->_re_filter->setRevoluteSigmaSystemNoisePhi(rev_sigma_sys_noise_phi);
00173     this->_re_filter->setRevoluteSigmaSystemNoiseTheta(rev_sigma_sys_noise_theta);
00174     this->_re_filter->setRevoluteSigmaSystemNoisePx(rev_sigma_sys_noise_px);
00175     this->_re_filter->setRevoluteSigmaSystemNoisePy(rev_sigma_sys_noise_py);
00176     this->_re_filter->setRevoluteSigmaSystemNoisePz(rev_sigma_sys_noise_pz);
00177     this->_re_filter->setRevoluteSigmaSystemNoiseRV(rev_sigma_sys_noise_rv);
00178     this->_re_filter->setRevoluteSigmaSystemNoiseRVd(rev_sigma_sys_noise_rvd);
00179     this->_re_filter->setRevoluteSigmaMeasurementNoise(rev_sigma_meas_noise);
00180 
00181     this->_re_filter->setRevoluteMinimumRotForEstimation(rev_min_rot_for_ee);
00182     this->_re_filter->setRevoluteMaximumJointDistanceForEstimation(rev_max_joint_distance_for_ee);
00183 
00184     this->_re_filter->setRigidMaxTranslation(rig_max_translation);
00185     this->_re_filter->setRigidMaxRotation(rig_max_rotation);
00186 
00187     this->_re_filter->setMinimumJointAgeForEE(this->_min_joint_age_for_ee);
00188 
00189     this->_re_filter->setMinimumNumFramesForNewRB(min_num_frames_for_new_rb);
00190 }
00191 
00192 void MultiJointTrackerNode::measurementCallback(const boost::shared_ptr<ks_measurement_ros_t const> &poses_and_vels)
00193 {   
00194     ros::Time tinit = ros::Time::now();
00195 
00196     // Get the time of the measurement as reference time
00197     this->_current_measurement_time = poses_and_vels->header.stamp;
00198 
00199     this->_re_filter->setMeasurement(*poses_and_vels, (double)poses_and_vels->header.stamp.toNSec());
00200 
00201     // Measure the time interval between the previous measurement and the current measurement
00202     ros::Duration time_between_meas = this->_current_measurement_time - this->_previous_measurement_time;
00203 
00204     // The time interval between frames is the inverse of the max_framerate
00205     double period_between_frames = 1.0/this->_sensor_fps;
00206 
00207     // The number of frames elapsed is the time elapsed divided by the period between frames
00208     int frames_between_meas = round((time_between_meas.toSec())/period_between_frames);
00209 
00210     // Processing fps: ignore (this->_processing_factor - 1) frames and process one. This gives effectively the desired processing fps: _sensor_fps/_processing_factor
00211     if( this->_previous_measurement_time.toSec() == 0.)
00212     {
00213         ROS_ERROR("Initial prediction of state and measurements (in KS estimation)!");
00214 
00215         // In the first iteration we clear the markers of the previous run (if the user wants that)
00216         bool clear_rviz_markers;
00217         this->getROSParameter<bool>(this->_namespace + std::string("/clear_rviz_markers"), clear_rviz_markers);
00218         if(clear_rviz_markers)
00219         {
00220             ROS_INFO_STREAM("Clearing RVIZ markers");
00221             // Clear all previous markers
00222             // Create a map of the most probable joints
00223             visualization_msgs::MarkerArray cleaning_markers;
00224             for (int num_rbs=0; num_rbs<100; num_rbs++)
00225             {
00226                 for(int num_joint_markers=0; num_joint_markers < 3; num_joint_markers++)
00227                 {
00228                     visualization_msgs::Marker cleaning_joint_marker;
00229                     cleaning_joint_marker.ns = "kinematic_structure";
00230                     cleaning_joint_marker.action = visualization_msgs::Marker::DELETE;
00231                     cleaning_joint_marker.type = visualization_msgs::Marker::ARROW;
00232 
00233                     cleaning_joint_marker.header.stamp = ros::Time::now();
00234                     cleaning_joint_marker.id = 3*num_rbs + num_joint_markers;
00235 
00236                     cleaning_markers.markers.push_back(cleaning_joint_marker);
00237 
00238                     cleaning_joint_marker.ns = "kinematic_structure_uncertainty";
00239                     cleaning_markers.markers.push_back(cleaning_joint_marker);
00240                 }
00241             }
00242             this->_state_publisher_rviz_markers.publish(cleaning_markers);
00243         }
00244     }
00245     else if( frames_between_meas != this->_processing_factor)
00246     {
00247         ROS_ERROR("Lost frames:%3d. Need to predict state and measurement again.", frames_between_meas - this->_processing_factor);
00248 
00249         // Predict next RE state
00250         this->_re_filter->predictState((double)time_between_meas.toNSec());
00251 
00252         // Predict next measurement based on the predicted state
00253         this->_re_filter->predictMeasurement();
00254     }else{
00255         ROS_INFO("Frames between measurements:%3d.", frames_between_meas);
00256     }
00257 
00258     // In the first iteration we cannot correct the state because we have only one measurement
00259     if(this->_previous_measurement_time.toSec() != 0.)
00260     {
00261         // Use the predicted measurement and the received measurement to correct the state
00262         this->_re_filter->correctState();
00263     }
00264 
00265     this->_re_filter->estimateJointFiltersProbabilities();
00266     this->_publishState();
00267     this->_PrintResults();
00268     this->_re_filter->predictState(this->_loop_period_ns);
00269     this->_re_filter->predictMeasurement();
00270 
00271     this->_publishPredictedMeasurement();
00272 
00273     this->_previous_measurement_time = this->_current_measurement_time;
00274     ros::Time tend = ros::Time::now();
00275     ROS_WARN_STREAM("Time between meas: " << time_between_meas.toSec()*1000 << " ms");
00276     ROS_WARN_STREAM("Total meas processing time: " << (tend-tinit).toSec()*1000 << " ms");
00277 }
00278 
00279 bool MultiJointTrackerNode::publishURDF(joint_tracker::publish_urdf::Request& request, joint_tracker::publish_urdf::Response& response)
00280 {
00281     std_msgs::String urdf_string_msg;
00282     sensor_msgs::JointState joint_states_msg;
00283     this->_generateURDF(urdf_string_msg, joint_states_msg);
00284     response.urdf_str = urdf_string_msg.data;
00285 
00286 
00287     if(request.write_to_file)
00288     {
00289         struct stat buffer2;
00290         struct stat buffer3;
00291         std::string urdf_file_path_dir = ros::package::getPath("joint_tracker");
00292         std::string urdf_file_path_old = urdf_file_path_dir + std::string("/urdf/km1.urdf");
00293         std::string urdf_file_path_new = urdf_file_path_dir + std::string("/urdf/km2.urdf");
00294 
00295 
00296         if (stat (urdf_file_path_old.c_str(), &buffer2) == 0)
00297         {
00298             if (stat (urdf_file_path_new.c_str(), &buffer3) == 0)
00299             {
00300                 std::remove(urdf_file_path_new.c_str());
00301             }
00302             std::rename(urdf_file_path_old.c_str(), urdf_file_path_new.c_str());
00303         }
00304         std::ofstream new_urdf_file(urdf_file_path_old.c_str());
00305         new_urdf_file << response.urdf_str;
00306         new_urdf_file.close();
00307     }
00308 
00309     return true;
00310 }
00311 
00312 void MultiJointTrackerNode::_generateURDF(std_msgs::String& urdf_string_msg, sensor_msgs::JointState& joint_state_msg) const
00313 {
00314     std::ostringstream urdf_stream;
00315     int RB_id_first;
00316     int RB_id_second;
00317     KinematicModel kinematic_model_original = this->_re_filter->getState();
00318 
00319     typedef std::map<std::pair<int, int>, JointFilterPtr> map_type_temp;
00320     map_type_temp kinematic_model;
00321     std::map<std::pair<int, int>, JointCombinedFilterPtr>::const_iterator joint_combined_filters_it = kinematic_model_original.begin();
00322     std::map<std::pair<int, int>, JointCombinedFilterPtr>::const_iterator joint_combined_filters_it_end = kinematic_model_original.end();
00323     for (; joint_combined_filters_it != joint_combined_filters_it_end; joint_combined_filters_it++)
00324     {
00325         JointFilterPtr joint_hypothesis = joint_combined_filters_it->second->getMostProbableJointFilter();
00326         kinematic_model[joint_combined_filters_it->first] = joint_hypothesis;
00327     }
00328 
00329 
00330     urdf_stream << "<?xml version=\"1.0\"?>" << std::endl;
00331     urdf_stream << "<robot name=\"KinematicStructure\">" << std::endl;
00332 
00333     // First add the joints
00334     // We need to add first the joints because this gives us the transformations we need to apply to the link visual's to bring them back to the origin
00335     bool prism_or_rev = false;
00336     std::map<int, std::pair<Eigen::Vector3d, Eigen::Vector3d> > link_visuals_origin;
00337     double joint_state = 0.;
00338     double joint_velocity = 0.;
00339     Eigen::Vector3d joint_position(0.,0.,0.);
00340     Eigen::Vector3d joint_orientation_rpy(0.,0.,0.);
00341     Eigen::Vector3d joint_orientation_axis(0.,0.,0.);
00342     BOOST_FOREACH(map_type_temp::value_type km_it, kinematic_model)
00343     {
00344         prism_or_rev = false;
00345         RB_id_first = km_it.first.first;
00346         RB_id_second = km_it.first.second;
00347         joint_state = km_it.second->getJointState();
00348         joint_velocity = km_it.second->getJointVelocity();
00349         joint_position = km_it.second->getJointPositionInRRBFrame();
00350         joint_orientation_rpy = km_it.second->getJointOrientationRPYInRRBFrame();
00351         joint_orientation_axis = km_it.second->getJointOrientationUnitaryVector();
00352 
00353         std::ostringstream joint_unique_name;
00354 
00355         joint_unique_name << "joint" << km_it.second->getJointId();
00356 
00357         urdf_stream << "  <joint name=\"" << joint_unique_name.str() << "\" type=\"";
00358 
00359         switch(km_it.second->getJointFilterType())
00360         {
00361         case RIGID_JOINT:
00362             urdf_stream << "fixed\">" << std::endl;
00363             break;
00364         case PRISMATIC_JOINT:
00365             prism_or_rev = true;
00366             urdf_stream << "prismatic\">" << std::endl;
00367             joint_state_msg.name.push_back(joint_unique_name.str());
00368             joint_state_msg.position.push_back(joint_state);
00369             joint_state_msg.velocity.push_back(joint_velocity);
00370             joint_state_msg.effort.push_back(0.0);
00371             break;
00372         case REVOLUTE_JOINT:
00373             prism_or_rev = true;
00374             urdf_stream << "revolute\">" << std::endl;
00375             joint_state_msg.name.push_back(joint_unique_name.str());
00376             joint_state_msg.position.push_back(joint_state);
00377             joint_state_msg.velocity.push_back(joint_velocity);
00378             joint_state_msg.effort.push_back(0.0);
00379             break;
00380         case DISCONNECTED_JOINT:
00381             urdf_stream << "floating\">" << std::endl;
00382             break;
00383         default:
00384             std::cout << "ERROR deparsing the results into a urdf string. Joint type not defined" << std::endl;
00385             return;
00386             break;
00387         }
00388 
00389         // Set the parent link
00390         if(RB_id_first == 0)
00391         {
00392             urdf_stream << "    <parent link=\"static_environment\"/>" << std::endl;
00393         }
00394         else{
00395             urdf_stream << "    <parent link=\"rb" << RB_id_first << "\"/>"<< std::endl;
00396         }
00397 
00398         // Set the child link
00399         urdf_stream << "    <child link=\"rb" << RB_id_second << "\"/>"<< std::endl;
00400 
00401         // Set the properties of the link for revolute and prismatic joints
00402         // We define the joint frame using the parameters of the joint
00403         // The joint axis is always a unitary vector pointing in the z direction
00404         if(prism_or_rev)
00405         {
00406             urdf_stream << "    <origin xyz=\"" << joint_position.x() << " " << joint_position.y() << " "<< joint_position.z() <<
00407                            "\" rpy=\"" << 0.0 << " "<< 0.0 << " "<< 0.0 << "\"/>" << std::endl;
00408             urdf_stream << "    <axis xyz=\"" << joint_orientation_axis.x() << " " << joint_orientation_axis.y() << " " << joint_orientation_axis.z() << "\"/>" << std::endl;
00409             link_visuals_origin[RB_id_second] = std::pair<Eigen::Vector3d,Eigen::Vector3d>(-joint_position, Eigen::Vector3d(0.,0.,0.));
00410 
00411 
00412             // With rotation:
00413             //            urdf_stream << "    <origin xyz=\"" << joint_position.x() << " " << joint_position.y() << " "<< joint_position.z() <<
00414             //                           "\" rpy=\"" << joint_orientation_rpy.x() << " "<< joint_orientation_rpy.y() << " "<< joint_orientation_rpy.z() << "\"/>" << std::endl;
00415             //            urdf_stream << "    <axis xyz=\"1 0 0\"/>" << std::endl;
00416 
00417 
00418 
00419             urdf_stream << "    <limit effort=\"30\" velocity=\"1.0\" lower=\"-3.1416\" upper=\"3.1416\"/>" << std::endl;
00420         }
00421 
00422         urdf_stream << "  </joint>" << std::endl;
00423     }
00424 
00425     // We add all the links to the model
00426     std::vector<omip::RB_id_t> all_rb_ids;
00427     BOOST_FOREACH(map_type_temp::value_type km_it, kinematic_model)
00428     {
00429         RB_id_first = km_it.first.first;
00430         RB_id_second = km_it.first.second;
00431 
00432         if(std::find(all_rb_ids.begin(), all_rb_ids.end(), RB_id_first) == all_rb_ids.end())
00433         {
00434             all_rb_ids.push_back(RB_id_first);
00435         }
00436 
00437         if(std::find(all_rb_ids.begin(), all_rb_ids.end(), RB_id_second) == all_rb_ids.end())
00438         {
00439             all_rb_ids.push_back(RB_id_second);
00440         }
00441     }
00442 
00443     std::vector<Eigen::Vector3d > rgb_colors;
00444     rgb_colors.push_back(Eigen::Vector3d(255,255,255)/255.0); // white
00445     rgb_colors.push_back(Eigen::Vector3d(255,0,0)/255.0); // red
00446     rgb_colors.push_back(Eigen::Vector3d(0,0,255)/255.0); // blue
00447     rgb_colors.push_back(Eigen::Vector3d(0,255,0)/255.0); // green
00448     rgb_colors.push_back(Eigen::Vector3d(255,255,0)/255.0); // yellow
00449     rgb_colors.push_back(Eigen::Vector3d(255,0,255)/255.0); // violet
00450     rgb_colors.push_back(Eigen::Vector3d(0,255,255)/255.0); // turquese
00451     rgb_colors.push_back(Eigen::Vector3d(255,128,0)/255.0); // orange
00452     rgb_colors.push_back(Eigen::Vector3d(153,153,255)/255.0); // pink
00453     rgb_colors.push_back(Eigen::Vector3d(128,128,128)/255.0); // gray
00454 
00455 
00456     for(int links_idx = 0; links_idx < all_rb_ids.size(); links_idx++)
00457     {
00458         // Static environment
00459         if(all_rb_ids.at(links_idx) == 0)
00460         {
00461             urdf_stream << "  <link name=\"static_environment\"";
00462         }
00463         else{
00464             urdf_stream << "  <link name=\"rb" << all_rb_ids.at(links_idx) << "\"";
00465         }
00466 
00467         std::string sr_path = this->_sr_path;
00468 
00469         sr_path += std::string("/meshes/");
00470         std::stringstream name_ss;
00471 
00472         if(all_rb_ids.at(links_idx) == 0)
00473         {
00474             name_ss << "shape_static_env" << all_rb_ids.at(links_idx) << ".stl";
00475         }else{
00476             name_ss << "shape_rb" << all_rb_ids.at(links_idx) << ".stl";
00477         }
00478 
00479         sr_path += name_ss.str();
00480 
00481         std::string sr_path_urdf = std::string("          <mesh filename=\"package://shape_reconstruction/meshes/");
00482         sr_path_urdf += name_ss.str();
00483 
00484         // We check if there exists a mesh file for this link and if it exists we add it
00485         struct stat buffer;
00486 
00487         if (stat (sr_path.c_str(), &buffer) == 0)
00488         {
00489             urdf_stream << ">" << std::endl;
00490             urdf_stream << "    <visual>" << std::endl <<
00491                            // "      <origin xyz=\"0 0 0\" rpy=\"0 0 0\" />" << std::endl <<
00492                            "      <origin xyz=\"" << link_visuals_origin[all_rb_ids.at(links_idx)].first.x() << " "
00493                         << link_visuals_origin[all_rb_ids.at(links_idx)].first.y() << " "
00494                         << link_visuals_origin[all_rb_ids.at(links_idx)].first.z() << "\" rpy=\""
00495                         << link_visuals_origin[all_rb_ids.at(links_idx)].second.x() << " "
00496                         << link_visuals_origin[all_rb_ids.at(links_idx)].second.y() << " "
00497                         << link_visuals_origin[all_rb_ids.at(links_idx)].second.z() << "\"/>" << std::endl <<
00498                            "      <geometry>" << std::endl <<
00499                            sr_path_urdf << "\"/>"<< std::endl <<
00500                            "      </geometry>" << std::endl <<
00501                            "      <material name=\"" << "shape_rb" << all_rb_ids.at(links_idx) << "_color\">" << std::endl <<
00502                            "        <color rgba=\"" << rgb_colors.at(all_rb_ids.at(links_idx)%rgb_colors.size()).x() << " "<<
00503                            rgb_colors.at(all_rb_ids.at(links_idx)%rgb_colors.size()).y() << " "<<
00504                            rgb_colors.at(all_rb_ids.at(links_idx)%rgb_colors.size()).z() << " 1\"/>" << std::endl <<
00505                            "      </material>" << std::endl<<
00506                            "    </visual>"<<std::endl <<
00507                            "  </link>" << std::endl;
00508         }else
00509         {
00510             urdf_stream << "/>" << std::endl;
00511         }
00512     }
00513 
00514     urdf_stream << "</robot>" << std::endl;
00515 
00516     urdf_string_msg.data = urdf_stream.str();
00517 
00518     joint_state_msg.header.stamp = ros::Time::now();
00519 }
00520 
00521 void MultiJointTrackerNode::_publishState() const
00522 {
00523     visualization_msgs::MarkerArray cleaning_markers;
00524     for (int num_rbs=0; num_rbs<100; num_rbs++)
00525     {
00526         for(int num_joint_markers=0; num_joint_markers < 3; num_joint_markers++)
00527         {
00528             visualization_msgs::Marker cleaning_joint_marker;
00529             cleaning_joint_marker.ns = "kinematic_structure";
00530             cleaning_joint_marker.action = visualization_msgs::Marker::DELETE;
00531             cleaning_joint_marker.type = visualization_msgs::Marker::ARROW;
00532 
00533             cleaning_joint_marker.header.stamp = ros::Time::now();
00534             cleaning_joint_marker.id = 3*num_rbs + num_joint_markers;
00535 
00536             cleaning_markers.markers.push_back(cleaning_joint_marker);
00537 
00538             cleaning_joint_marker.ns = "kinematic_structure_uncertainty";
00539             cleaning_markers.markers.push_back(cleaning_joint_marker);
00540         }
00541     }
00542     this->_state_publisher_rviz_markers.publish(cleaning_markers);
00543 
00544     ks_state_ros_t kinematic_structure;
00545     visualization_msgs::MarkerArray markers_of_most_probable_structure;
00546 
00547     ros::Time time_markers = this->_current_measurement_time;
00548     int RB_id;
00549     KinematicModel kinematic_model = this->_re_filter->getState();
00550 
00551     omip_msgs::KinematicStructureMsg ks_msg;
00552     // Populate a ros state message containing the kinematic structure (most probable joint and all others)
00553     BOOST_FOREACH(KinematicModel::value_type km_it, kinematic_model)
00554     {
00555         omip_msgs::JointMsg joint_msg;
00556         joint_msg.parent_rb_id = km_it.first.first;
00557         joint_msg.child_rb_id = km_it.first.second;
00558 
00559         joint_msg.rigid_probability = km_it.second->getJointFilter(RIGID_JOINT)->getProbabilityOfJointFilter();
00560         joint_msg.discon_probability = km_it.second->getJointFilter(DISCONNECTED_JOINT)->getProbabilityOfJointFilter();
00561         joint_msg.rev_probability = km_it.second->getJointFilter(REVOLUTE_JOINT)->getProbabilityOfJointFilter();
00562         joint_msg.prism_probability = km_it.second->getJointFilter(PRISMATIC_JOINT)->getProbabilityOfJointFilter();
00563 
00564         Eigen::Vector3d temp_eigen = km_it.second->getJointFilter(PRISMATIC_JOINT)->getJointPositionInRRBFrame();
00565         geometry_msgs::Point temp_ros;
00566         temp_ros.x = temp_eigen.x();
00567         temp_ros.y = temp_eigen.y();
00568         temp_ros.z = temp_eigen.z();
00569         joint_msg.prism_position = temp_ros;
00570 
00571         geometry_msgs::Vector3 temp_ros_vect;
00572         temp_eigen = km_it.second->getJointFilter(PRISMATIC_JOINT)->getJointOrientationUnitaryVector();
00573         temp_ros_vect.x = temp_eigen.x();
00574         temp_ros_vect.y = temp_eigen.y();
00575         temp_ros_vect.z = temp_eigen.z();
00576         joint_msg.prism_orientation = temp_ros_vect;
00577 
00578         joint_msg.prism_ori_phi = km_it.second->getJointFilter(PRISMATIC_JOINT)->getOrientationPhiInRRBFrame();
00579         joint_msg.prism_ori_theta = km_it.second->getJointFilter(PRISMATIC_JOINT)->getOrientationThetaInRRBFrame();
00580 
00581         joint_msg.prism_ori_cov[0] = km_it.second->getJointFilter(PRISMATIC_JOINT)->getCovarianceOrientationPhiPhiInRRBFrame();
00582         joint_msg.prism_ori_cov[1] = km_it.second->getJointFilter(PRISMATIC_JOINT)->getCovarianceOrientationPhiThetaInRRBFrame();
00583         joint_msg.prism_ori_cov[2] = km_it.second->getJointFilter(PRISMATIC_JOINT)->getCovarianceOrientationPhiThetaInRRBFrame();
00584         joint_msg.prism_ori_cov[3] = km_it.second->getJointFilter(PRISMATIC_JOINT)->getCovarianceOrientationThetaThetaInRRBFrame();
00585 
00586         joint_msg.prism_joint_value = km_it.second->getJointFilter(PRISMATIC_JOINT)->getJointState();
00587 
00588         temp_eigen = km_it.second->getJointFilter(REVOLUTE_JOINT)->getJointPositionInRRBFrame();
00589         temp_ros.x = temp_eigen.x();
00590         temp_ros.y = temp_eigen.y();
00591         temp_ros.z = temp_eigen.z();
00592         joint_msg.rev_position = temp_ros;
00593 
00594         temp_eigen = km_it.second->getJointFilter(REVOLUTE_JOINT)->getJointOrientationUnitaryVector();
00595         temp_ros_vect.x = temp_eigen.x();
00596         temp_ros_vect.y = temp_eigen.y();
00597         temp_ros_vect.z = temp_eigen.z();
00598         joint_msg.rev_orientation = temp_ros_vect;
00599 
00600         joint_msg.rev_ori_phi = km_it.second->getJointFilter(REVOLUTE_JOINT)->getOrientationPhiInRRBFrame();
00601         joint_msg.rev_ori_theta = km_it.second->getJointFilter(REVOLUTE_JOINT)->getOrientationThetaInRRBFrame();
00602 
00603         joint_msg.rev_ori_cov[0] = km_it.second->getJointFilter(REVOLUTE_JOINT)->getCovarianceOrientationPhiPhiInRRBFrame();
00604         joint_msg.rev_ori_cov[1] = km_it.second->getJointFilter(REVOLUTE_JOINT)->getCovarianceOrientationPhiThetaInRRBFrame();
00605         joint_msg.rev_ori_cov[2] = km_it.second->getJointFilter(REVOLUTE_JOINT)->getCovarianceOrientationPhiThetaInRRBFrame();
00606         joint_msg.rev_ori_cov[3] = km_it.second->getJointFilter(REVOLUTE_JOINT)->getCovarianceOrientationThetaThetaInRRBFrame();
00607 
00608         joint_msg.rev_joint_value = km_it.second->getJointFilter(REVOLUTE_JOINT)->getJointState();
00609 
00610         joint_msg.most_likely_joint =  (int)km_it.second->getMostProbableJointFilter()->getJointFilterType();
00611 
00612         ks_msg.kinematic_structure.push_back(joint_msg);
00613     }
00614     ks_msg.header.stamp = time_markers;
00615     this->_state_publisher.publish(ks_msg);
00616 
00617     // Create a map of the most probable joints
00618     std::map<std::pair<int, int>, boost::shared_ptr<JointFilter> > most_probable_joints;
00619     std::map<std::pair<int, int>, JointCombinedFilterPtr>::const_iterator joint_combined_filters_it = kinematic_model.begin();
00620     std::map<std::pair<int, int>, JointCombinedFilterPtr>::const_iterator joint_combined_filters_it_end = kinematic_model.end();
00621     for (; joint_combined_filters_it != joint_combined_filters_it_end; joint_combined_filters_it++)
00622     {
00623 
00624         JointFilterPtr joint_hypothesis = joint_combined_filters_it->second->getMostProbableJointFilter();
00625         most_probable_joints[joint_combined_filters_it->first] = joint_hypothesis;
00626 
00627         RB_id = joint_combined_filters_it->first.first;
00628         std::ostringstream oss;
00629 
00630         // Static environment
00631         if(RB_id == 0)
00632         {
00633             oss << "static_environment";
00634         }
00635         else{
00636             oss << "ip/rb" << RB_id;
00637         }
00638         std::vector<visualization_msgs::Marker> joint_markers = joint_hypothesis->getJointMarkersInRRBFrame();
00639         for (size_t markers_idx = 0; markers_idx < joint_markers.size(); markers_idx++)
00640         {
00641             joint_markers.at(markers_idx).header.stamp = time_markers;
00642             joint_markers.at(markers_idx).header.frame_id = oss.str();
00643 
00644             markers_of_most_probable_structure.markers.push_back(joint_markers.at(markers_idx));
00645         }
00646     }
00647     this->_state_publisher_rviz_markers.publish(markers_of_most_probable_structure);
00648 
00649     std_msgs::String urdf_string_msg;
00650     sensor_msgs::JointState joint_states_msg;
00651     this->_generateURDF(urdf_string_msg, joint_states_msg);
00652     this->_state_publisher_urdf.publish(urdf_string_msg);
00653     this->_state_publisher_joint_states.publish(joint_states_msg);
00654 }
00655 
00656 void MultiJointTrackerNode::_publishPredictedMeasurement() const
00657 {
00658     omip_msgs::RigidBodyPosesAndVelsMsg hypotheses = this->_re_filter->getPredictedMeasurement();
00659     hypotheses.header.frame_id = "/camera_rgb_optical_frame";
00660     hypotheses.header.stamp = this->_current_measurement_time + ros::Duration(this->_loop_period_ns/1e9);
00661     this->_measurement_prediction_publisher.publish(hypotheses);
00662 }
00663 
00664 void MultiJointTrackerNode::_PrintResults() const
00665 {
00666     KinematicModel kinematic_model = this->_re_filter->getState();
00667     int combined_filter_idx = 0;
00668     BOOST_FOREACH(KinematicModel::value_type km_it, kinematic_model)
00669     {
00670         JointCombinedFilterPtr cf_ptr = this->_re_filter->getCombinedFilter(combined_filter_idx);
00671         JointFilterPtr joint_hypothesis = km_it.second->getMostProbableJointFilter();
00672         ROS_INFO_NAMED( "MultiJointTrackerNode::PrintAndPublishResults",
00673                         "Joint between RB%3d and RB%3d  (JointID =%3d) of type %s (P=%2.2f, Rev=%2.2f, Rig=%2.2f, D=%2.2f)",
00674                         (int)km_it.first.first,
00675                         (int)km_it.first.second,
00676                         (int)km_it.second->getJointCombinedFilterId(),
00677                         joint_hypothesis->getJointFilterTypeStr().c_str(),
00678                         cf_ptr->getJointFilter(PRISMATIC_JOINT)->getProbabilityOfJointFilter(),
00679                         cf_ptr->getJointFilter(REVOLUTE_JOINT)->getProbabilityOfJointFilter(),
00680                         cf_ptr->getJointFilter(RIGID_JOINT)->getProbabilityOfJointFilter(),
00681                         cf_ptr->getJointFilter(DISCONNECTED_JOINT)->getProbabilityOfJointFilter());
00682         combined_filter_idx++;
00683     }
00684 }
00685 
00686 int main(int argc, char** argv)
00687 {
00688     ros::init(argc, argv, "joint_tracker");
00689     MultiJointTrackerNode ks_tracker_node;
00690     ks_tracker_node.run();
00691 
00692     return (0);
00693 }


joint_tracker
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:26:46