00001
00002
00003 #include <sbpl_arm_planner_node/visualize_arm.h>
00004 #include <time.h>
00005
00006 using namespace sbpl_arm_planner;
00007
00008 void HSVtoRGB( double *r, double *g, double *b, double h, double s, double v )
00009 {
00010 int i;
00011 double f, p, q, t;
00012 if( s == 0 ) {
00013
00014 *r = *g = *b = v;
00015 return;
00016 }
00017 h /= 60;
00018 i = floor(h);
00019 f = h - i;
00020 p = v * ( 1 - s );
00021 q = v * ( 1 - s * f );
00022 t = v * ( 1 - s * ( 1 - f ) );
00023 switch( i ) {
00024 case 0:
00025 *r = v;
00026 *g = t;
00027 *b = p;
00028 break;
00029 case 1:
00030 *r = q;
00031 *g = v;
00032 *b = p;
00033 break;
00034 case 2:
00035 *r = p;
00036 *g = v;
00037 *b = t;
00038 break;
00039 case 3:
00040 *r = p;
00041 *g = q;
00042 *b = v;
00043 break;
00044 case 4:
00045 *r = t;
00046 *g = p;
00047 *b = v;
00048 break;
00049 default:
00050 *r = v;
00051 *g = p;
00052 *b = q;
00053 break;
00054 }
00055 }
00056
00057 VisualizeArm::VisualizeArm(std::string arm_name) : ph_("~"), arm_name_(arm_name)
00058 {
00059 num_joints_ = 7;
00060 reference_frame_ = "torso_lift_link";
00061 chain_root_name_ = "torso_lift_link";
00062 chain_tip_name_ = "_gripper_r_finger_tip_link";
00063
00064 srand (time(NULL));
00065
00066 joint_names_.push_back("_shoulder_pan_joint");
00067 joint_names_.push_back("_shoulder_lift_joint");
00068 joint_names_.push_back("_upper_arm_roll_joint");
00069 joint_names_.push_back("_elbow_flex_joint");
00070 joint_names_.push_back("_forearm_roll_joint");
00071 joint_names_.push_back("_wrist_flex_joint");
00072 joint_names_.push_back("_wrist_roll_joint");
00073
00074 link_names_.push_back("_shoulder_pan_link");
00075 link_names_.push_back("_shoulder_lift_link");
00076 link_names_.push_back("_upper_arm_roll_link");
00077 link_names_.push_back("_elbow_flex_link");
00078 link_names_.push_back("_forearm_roll_link");
00079 link_names_.push_back("_wrist_flex_link");
00080 link_names_.push_back("_wrist_roll_link");
00081
00082 if(arm_name == "left_arm")
00083 {
00084 side_ = "l";
00085 side_full_ = "left";
00086 }
00087 else
00088 {
00089 side_ = "r";
00090 side_full_ = "right";
00091 }
00092
00093 for(size_t i = 0; i < joint_names_.size(); ++i)
00094 joint_names_[i] = side_ + joint_names_[i];
00095
00096 for(size_t i = 0; i < link_names_.size(); ++i)
00097 link_names_[i] = side_ + link_names_[i];
00098
00099 fk_service_name_ = "pr2_" + side_full_ + "_arm_kinematics/get_fk";
00100 ik_service_name_ = "pr2_" + side_full_ + "_arm_kinematics/get_ik";
00101 chain_tip_name_ = side_ + chain_tip_name_;
00102
00103
00104 pr2_arm_meshes_.push_back("package://pr2_description/meshes/shoulder_v0/shoulder_yaw.stl");
00105 pr2_arm_meshes_.push_back("package://pr2_description/meshes/shoulder_v0/shoulder_lift.stl");
00106 pr2_arm_meshes_.push_back("package://pr2_description/meshes/upper_arm_v0/upper_arm.stl");
00107 pr2_arm_meshes_.push_back("package://pr2_description/meshes/upper_arm_v0/elbow_flex.stl");
00108
00109 pr2_arm_meshes_.push_back("package://pr2_description/meshes/forearm_v0/forearm.stl");
00110 pr2_arm_meshes_.push_back("package://pr2_description/meshes/forearm_v0/wrist_flex.stl");
00111 pr2_arm_meshes_.push_back("package://pr2_description/meshes/forearm_v0/wrist_roll.stl");
00112 pr2_arm_meshes_.push_back("package://pr2_description/meshes/gripper_v0/gripper_palm.stl");
00113
00114
00115 pr2_gripper_meshes_.push_back("package://pr2_description/meshes/gripper_v0/upper_finger_r.stl");
00116 pr2_gripper_meshes_.push_back("package://pr2_description/meshes/gripper_v0/finger_tip_r.stl");
00117 pr2_gripper_meshes_.push_back("package://pr2_description/meshes/gripper_v0/upper_finger_l.stl");
00118 pr2_gripper_meshes_.push_back("package://pr2_description/meshes/gripper_v0/finger_tip_l.stl");
00119
00120 initKDLChain();
00121
00122
00123 traj_client_ = new TrajClient("r_arm_controller/joint_trajectory_action", true);
00124
00125
00126
00127
00128
00129 marker_array_publisher_ = nh_.advertise<visualization_msgs::MarkerArray>("visualization_marker_array", 500);
00130 marker_publisher_ = nh_.advertise<visualization_msgs::Marker>("visualization_marker", 500);
00131 display_trajectory_publisher_ = nh_.advertise<motion_planning_msgs::DisplayTrajectory>("arm_viz", 200);
00132 }
00133
00134 VisualizeArm::~VisualizeArm()
00135 {
00136 delete traj_client_;
00137 delete fk_solver_;
00138 delete gripper_l_fk_solver_;
00139 }
00140
00141 void VisualizeArm::setReferenceFrame(std::string &frame)
00142 {
00143 reference_frame_=frame;
00144 }
00145
00146 void VisualizeArm::sendArmToConfiguration(const std::vector<double> &angles)
00147 {
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 }
00168
00169 bool VisualizeArm::parsePoseFile(std::string filename, std::vector<std::vector<double> > &poses)
00170 {
00171 std::ifstream input_file(filename.c_str());
00172 if(!input_file.good())
00173 {
00174 printf("[parseCSVFile] Unable to open '%s' for reading.\n",filename.c_str());
00175 return false;
00176 }
00177
00178 int row(0), col(0);
00179 char line[256];
00180 input_file.seekg(0);
00181
00182 row = -1;
00183 poses.clear();
00184
00185 while (input_file.getline(line, 256, ','))
00186 {
00187 poses.resize(poses.size()+1);
00188 poses[++row].resize(6);
00189 poses[row][0] = atof(line);
00190 printf("%d poses_size: %d\n", row, (int)poses.size());
00191 printf("%0.3f ", poses[row][0]);
00192
00193 for(col = 1; col < 6; col++)
00194 {
00195 input_file.getline(line, 256, ',');
00196 poses[row][col] = atof(line);
00197 printf("%0.3f ",poses[row][col]);
00198 }
00199
00200
00201
00202 printf("\n");
00203 }
00204 printf("num rows: %d\n",(int)poses.size());
00205 return true;
00206 }
00207
00208 bool VisualizeArm::parseCSVFile(std::string filename, int num_cols, std::vector<std::vector<double> > &data)
00209 {
00210 std::ifstream input_file(filename.c_str());
00211 if(!input_file.good())
00212 {
00213 printf("[parseCSVFile] Unable to open '%s' for reading.\n",filename.c_str());
00214 return false;
00215 }
00216
00217 int row(0), col(0);
00218 char line[256];
00219 input_file.seekg(0);
00220
00221 std::vector<std::vector<double> > raw_data;
00222
00223 row = -1;
00224 raw_data.clear();
00225
00226 while (input_file.getline(line, 256, ','))
00227 {
00228 raw_data.resize(raw_data.size()+1);
00229 raw_data[++row].resize(num_cols);
00230 raw_data[row][0] = atof(line);
00231
00232 for(col = 1; col < num_cols; col++)
00233 {
00234 input_file.getline(line, 256, ',');
00235 raw_data[row][col] = atof(line);
00236 }
00237 }
00238
00239 std::vector<double> zero_line(num_cols,0);
00240 for(int i = 0; i < int(raw_data.size()); i++)
00241 {
00242 if(raw_data[i] != zero_line)
00243 data.push_back(raw_data[i]);
00244 }
00245
00246 ROS_DEBUG("[parseCSVFile] raw_data: num rows: %d",(int)raw_data.size());
00247 ROS_DEBUG("[parseCSVFile] data: num rows: %d",(int)data.size());
00248 return true;
00249 }
00250
00251 bool VisualizeArm::parseEnvironmentFile(std::string filename)
00252 {
00253 std::ifstream input_file(filename.c_str());
00254 if(!input_file.good())
00255 {
00256 printf("[parseEnvironmentFile] Unable to open %s for reading.\n",filename.c_str());
00257 return false;
00258 }
00259
00260 char line[256];
00261 input_file.seekg(0);
00262 std::vector<double> cube_temp(6,0);
00263
00264 goal_pose_.resize(6,0);
00265 start_config_.resize(7,0);
00266
00267 while (input_file.getline(line, 256,' ') && strlen(line) > 0)
00268 {
00269 if(strcmp(line,"linkstartangles(radians):") == 0)
00270 {
00271 for(int i=0; i < num_joints_; i++)
00272 {
00273 if(input_file.getline(line, 256, ' '))
00274 start_config_[i] = atof(line);
00275 }
00276 input_file.getline(line,256);
00277 }
00278 else if(strcmp(line,"endeffectorgoal(meters):") == 0)
00279 {
00280 if(input_file.getline(line, 256))
00281 {
00282 for(int i=0; i < atoi(line); i++)
00283 {
00284 for(int j = 0; j < 6; j++)
00285 if(input_file.getline(line, 256, ' '))
00286 goal_pose_[j] = atof(line);
00287
00288 if(input_file.getline(line, 256))
00289 goal_is_6dof_ = atoi(line);
00290 }
00291 }
00292 }
00293 else if(strcmp(line,"goal_tolerance(meters,radians):") == 0)
00294 {
00295 if(input_file.getline(line, 256, ' '))
00296 position_tolerance_ = atof(line);
00297
00298 if(input_file.getline(line, 256, ' '))
00299 orientation_tolerance_ = atof(line);
00300 input_file.getline(line,256);
00301 }
00302 else if(strcmp(line,"cube:") == 0)
00303 {
00304 for(int i=0; i < 6; i++)
00305 {
00306 if(input_file.getline(line, 256, ' '))
00307 cube_temp[i] = atof(line);
00308 }
00309 cubes_.push_back(cube_temp);
00310 input_file.getline(line,256);
00311 }
00312 else
00313 {
00314 ROS_ERROR("[parseEnvironmentFile] Error: unrecognized text in environment file.");
00315 input_file.getline(line,256);
00316 }
00317 }
00318 return true;
00319 }
00320
00321 void VisualizeArm::displayArmConfiguration(std::vector<double> angles)
00322 {
00323
00324 while(display_trajectory_publisher_.getNumSubscribers() < 1 && nh_.ok())
00325 {
00326 ROS_INFO("Waiting for subscriber");
00327 ros::Duration(0.3).sleep();
00328 }
00329
00330 motion_planning_msgs::DisplayTrajectory display_trajectory;
00331
00332 display_trajectory.model_id = "pr2";
00333 display_trajectory.trajectory.joint_trajectory.header.frame_id = "base_link";
00334 display_trajectory.trajectory.joint_trajectory.header.stamp = ros::Time::now();
00335 display_trajectory.trajectory.joint_trajectory.joint_names = joint_names_;
00336 display_trajectory.trajectory.joint_trajectory.points.resize(2);
00337 display_trajectory.trajectory.joint_trajectory.points[0].positions.resize(joint_names_.size());
00338 display_trajectory.trajectory.joint_trajectory.points[1].positions.resize(joint_names_.size());
00339
00340
00341 for(unsigned int i=0; i < joint_names_.size(); i++)
00342 {
00343 display_trajectory.trajectory.joint_trajectory.points[0].positions[i] = angles[i];
00344 display_trajectory.trajectory.joint_trajectory.points[1].positions[i] = angles[i];
00345 }
00346
00347 display_trajectory.robot_state.joint_state = joint_state_monitor_.getJointStateRealJoints();
00348 ROS_INFO("Publishing path for display");
00349 display_trajectory_publisher_.publish(display_trajectory);
00350 joint_state_monitor_.stop();
00351 }
00352
00353 void VisualizeArm::printEnvironmentInfo(FILE *fid)
00354 {
00355 fprintf(fid, "start configuration: ");
00356 for(int i = 0; i < (int)start_config_.size(); i++)
00357 fprintf(fid, "%0.3f ",start_config_[i]);
00358 fprintf(fid, "\n");
00359
00360 fprintf(fid, "goal pose: ");
00361 for(int i = 0; i < (int)goal_pose_.size(); i++)
00362 fprintf(fid, "%0.3f ",goal_pose_[i]);
00363 fprintf(fid, "\n");
00364
00365 fprintf(fid,"position tolerance (m): %0.3f\n", position_tolerance_);
00366 fprintf(fid,"orientation tolerance (m): %0.3f\n", orientation_tolerance_);
00367 fprintf(fid,"goal is 6dof constraint: %d\n", goal_is_6dof_);
00368
00369 fprintf(fid, "obstacles: %d\n", int(cubes_.size()));
00370 for(int j = 0; j < int(cubes_.size()); j++)
00371 {
00372 for(int i = 0; i < int(cubes_[j].size()); i++)
00373 fprintf(fid, "%0.3f ",cubes_[j][i]);
00374 fprintf(fid, "\n");
00375 }
00376 }
00377
00378 bool VisualizeArm::computeFKforVisualization(const std::vector<double> &jnt_pos, std::vector<geometry_msgs::PoseStamped> &poses)
00379 {
00380 kinematics_msgs::GetPositionFK::Request request;
00381 kinematics_msgs::GetPositionFK::Response response;
00382
00383 request.header.stamp = ros::Time();
00384 request.header.frame_id = reference_frame_;
00385
00386 request.robot_state.joint_state.name = joint_names_;
00387
00388 ROS_DEBUG("%d joints", (int)jnt_pos.size());
00389
00390 for(unsigned int j = 0 ; j < jnt_pos.size(); ++j)
00391 request.robot_state.joint_state.position.push_back(jnt_pos[j]);
00392
00393 ROS_DEBUG("%d joints, %d positions",int(request.robot_state.joint_state.name.size()),int(request.robot_state.joint_state.position.size()));
00394
00395 request.fk_link_names.push_back(link_names_[0]);
00396 request.fk_link_names.push_back(link_names_[1]);
00397 request.fk_link_names.push_back(link_names_[2]);
00398 request.fk_link_names.push_back(link_names_[3]);
00399 request.fk_link_names.push_back(link_names_[4]);
00400 request.fk_link_names.push_back(link_names_[5]);
00401 request.fk_link_names.push_back(link_names_[6]);
00402 request.fk_link_names.push_back(link_names_[6]);
00403
00404 ros::service::waitForService("pr2_right_arm_kinematics/get_fk");
00405 ros::ServiceClient client = nh_.serviceClient<kinematics_msgs::GetPositionFK>("pr2_right_arm_kinematics/get_fk");
00406
00407 ROS_DEBUG("[computeFKforVisualization] about to call service...");
00408 if(client.call(request, response))
00409 {
00410 if(response.error_code.val == response.error_code.SUCCESS)
00411 {
00412 poses = response.pose_stamped;
00413 return true;
00414 }
00415 else
00416 {
00417 ROS_ERROR("[computeFKforVisualization] FK service failed with error code %d", response.error_code.val);
00418 return false;
00419 }
00420 }
00421 else
00422 {
00423 ROS_ERROR("FK service failed");
00424 return false;
00425 }
00426 }
00427
00428 bool VisualizeArm::initKDLChain()
00429 {
00430 std::string robot_description;
00431 std::string robot_param;
00432 nh_.searchParam("robot_description",robot_param);
00433 nh_.param<std::string>(robot_param,robot_description,"robot_description");
00434
00435 if (!kdl_parser::treeFromString(robot_description, kdl_tree_))
00436 {
00437 printf("Failed to parse tree from manipulator description file.\n");
00438 return false;
00439 }
00440
00441 if (!kdl_tree_.getChain(chain_root_name_, chain_tip_name_, chain_))
00442 {
00443 printf("Error: could not fetch the KDL chain for the desired manipulator. Exiting.\n");
00444 return false;
00445 }
00446
00447 fk_solver_ = new KDL::ChainFkSolverPos_recursive(chain_);
00448 jnt_pos_in_.resize(chain_.getNrOfJoints());
00449 jnt_pos_out_.resize(chain_.getNrOfJoints());
00450
00451 double jnt_pos = 0;
00452 for(unsigned int j = 0; j < chain_.getNrOfSegments(); ++j)
00453 {
00454 ROS_DEBUG("frame %2d: segment: %0.3f %0.3f %0.3f joint: %0.3f %0.3f %0.3f joint_type: %s",j,
00455 chain_.getSegment(j).pose(jnt_pos).p.x(),
00456 chain_.getSegment(j).pose(jnt_pos).p.y(),
00457 chain_.getSegment(j).pose(jnt_pos).p.z(),
00458 chain_.getSegment(j).getJoint().pose(jnt_pos).p.x(),
00459 chain_.getSegment(j).getJoint().pose(jnt_pos).p.y(),
00460 chain_.getSegment(j).getJoint().pose(jnt_pos).p.z(),
00461 chain_.getSegment(j).getJoint().getTypeName().c_str());
00462 }
00463
00464 ROS_DEBUG("[initKDLChain] the arm chain has %d segments with %d joints", chain_.getNrOfSegments(), chain_.getNrOfJoints());
00465
00466
00467 if (!kdl_tree_.getChain(chain_root_name_, "r_gripper_l_finger_tip_link", gripper_l_chain_))
00468 {
00469 printf("Error: could not fetch the KDL chain for the desired manipulator. Exiting.\n");
00470 return false;
00471 }
00472 ROS_DEBUG("left finger KDL chain:\n");
00473 for(unsigned int j = 0; j < gripper_l_chain_.getNrOfSegments(); ++j)
00474 {
00475 ROS_DEBUG("frame %2d: segment: %0.3f %0.3f %0.3f joint: %0.3f %0.3f %0.3f joint_type: %s\n",j,
00476 gripper_l_chain_.getSegment(j).pose(jnt_pos).p.x(),
00477 gripper_l_chain_.getSegment(j).pose(jnt_pos).p.y(),
00478 gripper_l_chain_.getSegment(j).pose(jnt_pos).p.z(),
00479 gripper_l_chain_.getSegment(j).getJoint().pose(jnt_pos).p.x(),
00480 gripper_l_chain_.getSegment(j).getJoint().pose(jnt_pos).p.y(),
00481 gripper_l_chain_.getSegment(j).getJoint().pose(jnt_pos).p.z(),
00482 gripper_l_chain_.getSegment(j).getJoint().getTypeName().c_str());
00483 }
00484
00485 gripper_l_fk_solver_ = new KDL::ChainFkSolverPos_recursive(gripper_l_chain_);
00486
00487 return true;
00488 }
00489
00490 bool VisualizeArm::computeFKwithKDL(const std::vector<double> angles, int frame_num, geometry_msgs::Pose &pose)
00491 {
00492 KDL::Frame frame_out;
00493 for(int i = 0; i < num_joints_; ++i)
00494 jnt_pos_in_(i) = angles[i];
00495
00496 if(frame_num > 0)
00497 {
00498 if(fk_solver_->JntToCart(jnt_pos_in_, frame_out, frame_num) < 0)
00499 {
00500 printf("JntToCart returned < 0. Exiting.\n");
00501 return false;
00502 }
00503 }
00504 else
00505 {
00506 if(gripper_l_fk_solver_->JntToCart(jnt_pos_in_, frame_out, -1*frame_num) < 0)
00507 {
00508 printf("JntToCart returned < 0. Exiting.\n");
00509 return false;
00510 }
00511 }
00512
00513 pose.position.x = frame_out.p[0];
00514 pose.position.y = frame_out.p[1];
00515 pose.position.z = frame_out.p[2];
00516
00517 frame_out.M.GetQuaternion(pose.orientation.x,pose.orientation.y,pose.orientation.z,pose.orientation.w);
00518
00519 return true;
00520 }
00521
00522 bool VisualizeArm::computeFKforVisualizationWithKDL(const std::vector<double> &jnt_pos, std::vector<geometry_msgs::PoseStamped> &poses)
00523 {
00524
00525
00526 geometry_msgs::Pose pose;
00527
00528 poses.resize(pr2_arm_meshes_.size());
00529 for(int i=0; i < (int)pr2_arm_meshes_.size(); i++)
00530 {
00531 if(!computeFKwithKDL(jnt_pos, i, poses[i].pose))
00532 return false;
00533 ROS_DEBUG("pose: %d: %0.2f %0.2f %0.2f",i, poses[i].pose.position.x, poses[i].pose.position.y,poses[i].pose.position.z);
00534 }
00535 return true;
00536 }
00537
00538 void VisualizeArm::visualizeObstacles(const std::vector<std::vector<double> > &obstacles)
00539 {
00540 marker_array_.markers.clear();
00541 marker_array_.markers.resize(obstacles.size());
00542
00543 ROS_INFO("Displaying %d obstaclesin the %s frame", (int)obstacles.size(), reference_frame_.c_str());
00544
00545 std::string ns = "obstacles"+boost::lexical_cast<std::string>(rand());
00546
00547 for(int i = 0; i < int(obstacles.size()); i++)
00548 {
00549 if(obstacles[i].size() < 6)
00550 {
00551 ROS_INFO("Obstacle description doesn't have length = 6");
00552 continue;
00553 }
00554
00555
00556 marker_array_.markers[i].header.stamp = ros::Time::now();
00557 marker_array_.markers[i].header.frame_id = reference_frame_;
00558 marker_array_.markers[i].ns = ns;
00559 marker_array_.markers[i].id = rand();
00560 marker_array_.markers[i].type = visualization_msgs::Marker::CUBE;
00561 marker_array_.markers[i].action = visualization_msgs::Marker::ADD;
00562 marker_array_.markers[i].pose.position.x = obstacles[i][0];
00563 marker_array_.markers[i].pose.position.y = obstacles[i][1];
00564 marker_array_.markers[i].pose.position.z = obstacles[i][2];
00565 marker_array_.markers[i].scale.x = obstacles[i][3];
00566 marker_array_.markers[i].scale.y = obstacles[i][4];
00567 marker_array_.markers[i].scale.z = obstacles[i][5];
00568 marker_array_.markers[i].color.r = 0.0;
00569 marker_array_.markers[i].color.g = 0.0;
00570 marker_array_.markers[i].color.b = 0.5;
00571 marker_array_.markers[i].color.a = 0.9;
00572 marker_array_.markers[i].lifetime = ros::Duration(180.0);
00573 }
00574
00575 marker_array_publisher_.publish(marker_array_);
00576 }
00577
00578 void VisualizeArm::visualizeEnvironment(std::string filename)
00579 {
00580 parseEnvironmentFile(filename);
00581 visualizePose(goal_pose_, filename);
00582 visualizeArmConfiguration(10, start_config_);
00583 visualizeObstacles(cubes_);
00584 }
00585
00586 void VisualizeArm::visualizeTrajectoryFile(std::string filename, int throttle)
00587 {
00588 std::vector<std::vector<double> > traj;
00589 if(!parseCSVFile(filename, num_joints_, traj))
00590 printf("[visualizeTrajectoryFile] Parsing %s failed.\n",filename.c_str());
00591
00592 visualizeArmConfigurations(traj,throttle);
00593 }
00594
00595 void VisualizeArm::visualizeJointTrajectoryMsg(trajectory_msgs::JointTrajectory traj_msg, int throttle)
00596 {
00597 std::vector<std::vector<double> > traj;
00598
00599 if(traj_msg.points.empty())
00600 {
00601 ROS_WARN("Trajectory message is empty. Not visualizing anything.");
00602 return;
00603 }
00604
00605 traj.resize(traj_msg.points.size());
00606 for(size_t i = 0; i < traj_msg.points.size(); i++)
00607 {
00608 traj[i].resize(traj_msg.points[i].positions.size());
00609 for(size_t j = 0; j < traj_msg.points[i].positions.size(); j++)
00610 traj[i][j] = traj_msg.points[i].positions[j];
00611 }
00612
00613 ROS_INFO("[visualizeJointTrajectoryMsg] Visualizing trajectory of length %d with the throttle set to %d.",int(traj.size()),throttle);
00614
00615 visualizeArmConfigurations(traj,throttle);
00616 }
00617
00618 void VisualizeArm::visualizeArmConfigurations(const std::vector<std::vector<double> > &traj, int throttle)
00619 {
00620 double color_inc = 260/traj.size();
00621 std::vector<double> zero_config(num_joints_,0);
00622
00623
00624 visualizeArmConfiguration(color_inc*(1), traj[0]);
00625 visualizeArmConfiguration(color_inc*((traj.size()-1)+1), traj[traj.size()-1]);
00626
00627 for(int i = 1; i < (int)traj.size(); i++)
00628 {
00629
00630 if(traj[i] == zero_config)
00631 {
00632 ROS_WARN("[visualizeArmConfigurations] Not displaying arm configurations of all zeroes.");
00633 continue;
00634 }
00635
00636 if(i % throttle != 0)
00637 continue;
00638
00639 visualizeArmConfiguration(color_inc*(i+1), traj[i]);
00640 }
00641 }
00642
00643 void VisualizeArm::visualizePoses(const std::vector<std::vector<double> > &poses)
00644 {
00645 marker_array_.markers.clear();
00646 marker_array_.markers.resize(poses.size()*3);
00647 btQuaternion pose_quaternion;
00648 geometry_msgs::Quaternion quaternion_msg;
00649
00650 int mind = -1;
00651
00652 ros::Time time = ros::Time::now();
00653
00654 for(int i = 0; i < (int)poses.size(); ++i)
00655 {
00656 pose_quaternion.setRPY(poses[i][3],poses[i][4],poses[i][5]);
00657 tf::quaternionTFToMsg(pose_quaternion, quaternion_msg);
00658
00659 mind++;
00660 marker_array_.markers[mind].header.stamp = time;
00661 marker_array_.markers[mind].header.frame_id = reference_frame_;
00662 marker_array_.markers[mind].ns = "pose_arrows";
00663 marker_array_.markers[mind].type = visualization_msgs::Marker::ARROW;
00664 marker_array_.markers[mind].id = i;
00665 marker_array_.markers[mind].action = visualization_msgs::Marker::ADD;
00666 marker_array_.markers[mind].pose.position.x = poses[i][0];
00667 marker_array_.markers[mind].pose.position.y = poses[i][1];
00668 marker_array_.markers[mind].pose.position.z = poses[i][2];
00669 marker_array_.markers[mind].pose.orientation = quaternion_msg;
00670 marker_array_.markers[mind].scale.x = 0.1;
00671 marker_array_.markers[mind].scale.y = 0.1;
00672 marker_array_.markers[mind].scale.z = 0.1;
00673 marker_array_.markers[mind].color.r = 0.0;
00674 marker_array_.markers[mind].color.g = 0.7;
00675 marker_array_.markers[mind].color.b = 0.6;
00676 marker_array_.markers[mind].color.a = 0.7;
00677 marker_array_.markers[mind].lifetime = ros::Duration(180.0);
00678
00679 mind++;
00680 marker_array_.markers[mind].header.stamp = time;
00681 marker_array_.markers[mind].header.frame_id = reference_frame_;
00682 marker_array_.markers[mind].ns = "pose_spheres";
00683 marker_array_.markers[mind].id = i;
00684 marker_array_.markers[mind].type = visualization_msgs::Marker::SPHERE;
00685 marker_array_.markers[mind].action = visualization_msgs::Marker::ADD;
00686 marker_array_.markers[mind].pose.position.x = poses[i][0];
00687 marker_array_.markers[mind].pose.position.y = poses[i][1];
00688 marker_array_.markers[mind].pose.position.z = poses[i][2];
00689 marker_array_.markers[mind].pose.orientation = quaternion_msg;
00690 marker_array_.markers[mind].scale.x = 0.07;
00691 marker_array_.markers[mind].scale.y = 0.07;
00692 marker_array_.markers[mind].scale.z = 0.07;
00693 marker_array_.markers[mind].color.r = 1.0;
00694 marker_array_.markers[mind].color.g = 0.0;
00695 marker_array_.markers[mind].color.b = 0.6;
00696 marker_array_.markers[mind].color.a = 0.6;
00697 marker_array_.markers[mind].lifetime = ros::Duration(180.0);
00698
00699 mind++;
00700 marker_array_.markers[mind].header.stamp = time;
00701 marker_array_.markers[mind].header.frame_id = reference_frame_;
00702 marker_array_.markers[mind].ns = "pose_text_blocks";
00703 marker_array_.markers[mind].id = i;
00704 marker_array_.markers[mind].type = visualization_msgs::Marker::TEXT_VIEW_FACING;
00705 marker_array_.markers[mind].action = visualization_msgs::Marker::ADD;
00706 marker_array_.markers[mind].pose.position.x = poses[i][0];
00707 marker_array_.markers[mind].pose.position.y = poses[i][1];
00708 marker_array_.markers[mind].pose.position.z = poses[i][2];
00709 marker_array_.markers[mind].scale.x = 0.03;
00710 marker_array_.markers[mind].scale.y = 0.03;
00711 marker_array_.markers[mind].scale.z = 0.03;
00712 marker_array_.markers[mind].color.r = 1.0;
00713 marker_array_.markers[mind].color.g = 1.0;
00714 marker_array_.markers[mind].color.b = 1.0;
00715 marker_array_.markers[mind].color.a = 0.9;
00716 marker_array_.markers[mind].text = boost::lexical_cast<std::string>(i+1);
00717 marker_array_.markers[mind].lifetime = ros::Duration(180.0);
00718 }
00719
00720 ROS_INFO("%d markers in the array",(int)marker_array_.markers.size());
00721 marker_array_publisher_.publish(marker_array_);
00722 }
00723
00724 void VisualizeArm::visualizePose(const std::vector<double> &pose, std::string text)
00725 {
00726 btQuaternion pose_quaternion;
00727 geometry_msgs::Pose pose_msg;
00728
00729 pose_msg.position.x = pose[0];
00730 pose_msg.position.y = pose[1];
00731 pose_msg.position.z = pose[2];
00732
00733 pose_quaternion.setRPY(pose[3],pose[4],pose[5]);
00734 tf::quaternionTFToMsg(pose_quaternion, pose_msg.orientation);
00735
00736 ROS_DEBUG("[visualizing: %s] position: %0.3f %0.3f %0.3f quaternion: %0.3f %0.3f %0.3f %0.3f (frame: %s)", text.c_str(), pose[0], pose[1], pose[2], pose_msg.orientation.x, pose_msg.orientation.y, pose_msg.orientation.z, pose_msg.orientation.w, reference_frame_.c_str());
00737
00738 visualizePose(pose_msg, text);
00739 }
00740
00741 void VisualizeArm::visualizePose(const geometry_msgs::Pose &pose, std::string text)
00742 {
00743 int mind = -1;
00744 marker_array_.markers.clear();
00745 marker_array_.markers.resize(3);
00746 ros::Time time = ros::Time::now();
00747
00748 ROS_DEBUG("[visualizing: %s] position: %0.3f %0.3f %0.3f quaternion: %0.3f %0.3f %0.3f %0.3f (frame: %s)", text.c_str(), pose.position.x, pose.position.y, pose.position.z, pose.orientation.x, pose.orientation.y, pose.orientation.z, pose.orientation.w, reference_frame_.c_str());
00749
00750 mind++;
00751 marker_array_.markers[mind].header.stamp = time;
00752 marker_array_.markers[mind].header.frame_id = reference_frame_;
00753 marker_array_.markers[mind].ns = text + "_arrow";
00754 marker_array_.markers[mind].type = visualization_msgs::Marker::ARROW;
00755 marker_array_.markers[mind].id = 0;
00756 marker_array_.markers[mind].action = visualization_msgs::Marker::ADD;
00757 marker_array_.markers[mind].pose = pose;
00758 marker_array_.markers[mind].scale.x = 0.125;
00759 marker_array_.markers[mind].scale.y = 0.125;
00760 marker_array_.markers[mind].scale.z = 0.125;
00761 marker_array_.markers[mind].color.r = 0.0;
00762 marker_array_.markers[mind].color.g = 0.7;
00763 marker_array_.markers[mind].color.b = 0.6;
00764 marker_array_.markers[mind].color.a = 0.7;
00765 marker_array_.markers[mind].lifetime = ros::Duration(180.0);
00766
00767 mind++;
00768 marker_array_.markers[mind].header.stamp = time;
00769 marker_array_.markers[mind].header.frame_id = reference_frame_;
00770 marker_array_.markers[mind].ns = text + "_sphere";
00771 marker_array_.markers[mind].id = 1;
00772 marker_array_.markers[mind].type = visualization_msgs::Marker::SPHERE;
00773 marker_array_.markers[mind].action = visualization_msgs::Marker::ADD;
00774 marker_array_.markers[mind].pose = pose;
00775 marker_array_.markers[mind].scale.x = 0.10;
00776 marker_array_.markers[mind].scale.y = 0.10;
00777 marker_array_.markers[mind].scale.z = 0.10;
00778 marker_array_.markers[mind].color.r = 1.0;
00779 marker_array_.markers[mind].color.g = 0.0;
00780 marker_array_.markers[mind].color.b = 0.6;
00781 marker_array_.markers[mind].color.a = 0.6;
00782 marker_array_.markers[mind].lifetime = ros::Duration(180.0);
00783
00784 mind++;
00785 marker_array_.markers[mind].header.stamp = time;
00786 marker_array_.markers[mind].header.frame_id = reference_frame_;
00787 marker_array_.markers[mind].ns = text;
00788 marker_array_.markers[mind].id = 2;
00789 marker_array_.markers[mind].type = visualization_msgs::Marker::TEXT_VIEW_FACING;
00790 marker_array_.markers[mind].action = visualization_msgs::Marker::ADD;
00791 marker_array_.markers[mind].pose = pose;
00792 marker_array_.markers[mind].scale.x = 0.03;
00793 marker_array_.markers[mind].scale.y = 0.03;
00794 marker_array_.markers[mind].scale.z = 0.03;
00795 marker_array_.markers[mind].color.r = 1.0;
00796 marker_array_.markers[mind].color.g = 1.0;
00797 marker_array_.markers[mind].color.b = 1.0;
00798 marker_array_.markers[mind].color.a = 0.9;
00799 marker_array_.markers[mind].text = text;
00800 marker_array_.markers[mind].lifetime = ros::Duration(180.0);
00801
00802 marker_array_publisher_.publish(marker_array_);
00803 }
00804
00805 void VisualizeArm::visualizeSphere(std::vector<double> pose, int color, std::string text, double radius)
00806 {
00807 double r=0,g=0,b=0;
00808 visualization_msgs::Marker marker;
00809
00810 HSVtoRGB(&r, &g, &b, color, 1.0, 1.0);
00811
00812 marker.header.stamp = ros::Time::now();
00813 marker.header.frame_id = reference_frame_;
00814 marker.ns = text + "-sphere";
00815 marker.id = 1;
00816 marker.type = visualization_msgs::Marker::SPHERE;
00817 marker.action = visualization_msgs::Marker::ADD;
00818 marker.pose.position.x = pose[0];
00819 marker.pose.position.y = pose[1];
00820 marker.pose.position.z = pose[2];
00821 marker.scale.x = radius*2;
00822 marker.scale.y = radius*2;
00823 marker.scale.z = radius*2;
00824 marker.color.r = r;
00825 marker.color.g = g;
00826 marker.color.b = b;
00827 marker.color.a = 0.6;
00828 marker.lifetime = ros::Duration(120.0);
00829
00830 marker_publisher_.publish(marker);
00831 }
00832
00833 void VisualizeArm::visualizeSpheres(const std::vector<std::vector<double> > &pose, int color, std::string text, double radius)
00834 {
00835 double r=0,g=0,b=0;
00836 visualization_msgs::Marker marker;
00837
00838 HSVtoRGB(&r, &g, &b, color, 1.0, 1.0);
00839
00840 marker.header.stamp = ros::Time::now();
00841 marker.header.frame_id = reference_frame_;
00842 marker.ns = "spheres-" + text;
00843 marker.type = visualization_msgs::Marker::SPHERE_LIST;
00844 marker.action = visualization_msgs::Marker::ADD;
00845 marker.scale.x = radius*2.0;
00846 marker.scale.y = radius*2.0;
00847 marker.scale.z = radius*2.0;
00848 marker.color.r = r;
00849 marker.color.g = g;
00850 marker.color.b = b;
00851 marker.color.a = 0.6;
00852 marker.lifetime = ros::Duration(120.0);
00853 marker.id = 1;
00854
00855 marker.points.resize(pose.size());
00856 for(size_t i = 0; i < pose.size(); i++)
00857 {
00858 marker.points[i].x = pose[i][0];
00859 marker.points[i].y = pose[i][1];
00860 marker.points[i].z = pose[i][2];
00861 }
00862
00863 marker_publisher_.publish(marker);
00864 }
00865
00866 void VisualizeArm::visualizeArmMeshes(double color_num, std::vector<geometry_msgs::PoseStamped> &poses)
00867 {
00868 double r,g,b;
00869 marker_array_.markers.clear();
00870 marker_array_.markers.resize(pr2_arm_meshes_.size());
00871 ros::Time time = ros::Time::now();
00872
00873 HSVtoRGB(&r, &g, &b, color_num, 1.0, 1.0);
00874
00875 for(int i = 0; i < (int)marker_array_.markers.size(); ++i)
00876 {
00877 marker_array_.markers[i].header.stamp = time;
00878 marker_array_.markers[i].header.frame_id = reference_frame_;
00879 marker_array_.markers[i].ns = "arm_mesh_" + boost::lexical_cast<std::string>(color_num);
00880 marker_array_.markers[i].type = visualization_msgs::Marker::MESH_RESOURCE;
00881 marker_array_.markers[i].id = i;
00882 marker_array_.markers[i].action = visualization_msgs::Marker::ADD;
00883 marker_array_.markers[i].pose = poses.at(i).pose;
00884 marker_array_.markers[i].scale.x = 1.0;
00885 marker_array_.markers[i].scale.y = 1.0;
00886 marker_array_.markers[i].scale.z = 1.0;
00887
00888 marker_array_.markers[i].color.r = r;
00889 marker_array_.markers[i].color.g = g;
00890 marker_array_.markers[i].color.b = b;
00891 marker_array_.markers[i].color.a = 0.4;
00892 marker_array_.markers[i].lifetime = ros::Duration(120.0);
00893 marker_array_.markers[i].mesh_resource = pr2_arm_meshes_[i];
00894 }
00895
00896 marker_array_publisher_.publish(marker_array_);
00897 }
00898
00899 void VisualizeArm::visualizeGripperConfiguration(double color_num, const std::vector<double> &jnt_pos)
00900 {
00901 std::vector<geometry_msgs::PoseStamped> poses;
00902
00903 poses.resize(4);
00904
00905
00906 computeFKwithKDL(jnt_pos,11,poses[0].pose);
00907
00908
00909 computeFKwithKDL(jnt_pos,12,poses[1].pose);
00910
00911
00912 computeFKwithKDL(jnt_pos,-11,poses[2].pose);
00913
00914
00915 computeFKwithKDL(jnt_pos,-12,poses[3].pose);
00916
00917 visualizeGripperMeshes(color_num, poses);
00918 }
00919
00920 void VisualizeArm::visualizeGripperMeshes(double color_num, std::vector<geometry_msgs::PoseStamped> &poses)
00921 {
00922 double r,g,b;
00923 marker_array_.markers.clear();
00924 marker_array_.markers.resize(pr2_gripper_meshes_.size());
00925
00926 HSVtoRGB(&r, &g, &b, color_num, 1.0, 1.0);
00927
00928 for(int i = 0; i < (int)marker_array_.markers.size(); ++i)
00929 {
00930 marker_array_.markers[i].header.stamp = ros::Time::now();
00931 marker_array_.markers[i].header.frame_id = chain_root_name_;
00932 marker_array_.markers[i].ns = "gripper_mesh_" + boost::lexical_cast<std::string>(color_num);
00933 marker_array_.markers[i].type = visualization_msgs::Marker::MESH_RESOURCE;
00934 marker_array_.markers[i].id = i;
00935 marker_array_.markers[i].action = visualization_msgs::Marker::ADD;
00936 marker_array_.markers[i].pose = poses.at(i).pose;
00937 marker_array_.markers[i].scale.x = 1.0;
00938 marker_array_.markers[i].scale.y = 1.0;
00939 marker_array_.markers[i].scale.z = 1.0;
00940
00941 marker_array_.markers[i].color.r = r;
00942 marker_array_.markers[i].color.g = g;
00943 marker_array_.markers[i].color.b = b;
00944 marker_array_.markers[i].color.a = 0.4;
00945 marker_array_.markers[i].lifetime = ros::Duration(120.0);
00946 marker_array_.markers[i].mesh_resource = pr2_gripper_meshes_[i];
00947 }
00948
00949 marker_array_publisher_.publish(marker_array_);
00950 }
00951
00952 void VisualizeArm::visualizeArmConfiguration(double color_num, const std::vector<double> &jnt_pos)
00953 {
00954 std::vector<geometry_msgs::PoseStamped> poses;
00955 if(!computeFKforVisualization(jnt_pos, poses))
00956 ROS_INFO("[visualizeArmConfiguration] Unable to compute forward kinematics.");
00957 else
00958 visualizeArmMeshes(color_num, poses);
00959
00960 visualizeGripperConfiguration(color_num,jnt_pos);
00961 }
00962
00963 void VisualizeArm::visualizeCollisionModel(const std::vector<std::vector<double> > &path, sbpl_arm_planner::SBPLCollisionSpace &cspace, int throttle)
00964 {
00965 std::vector<std::vector<double> > cylinders;
00966 visualization_msgs::MarkerArray marker_array;
00967
00968 for(int i = 0; i < int(path.size()); ++i)
00969 {
00970 if(i % throttle != 0)
00971 {
00972 if(i != 0 && i != int(path.size())-1)
00973 continue;
00974 }
00975
00976 cylinders.resize(0);
00977 if(!cspace.getCollisionCylinders(path[i], cylinders))
00978 ROS_WARN("[visualizeCollisionModel] Cannot display arm collision model.");
00979
00980 ROS_DEBUG("[visualizeCollisionModel] waypoint #%d contains %d cylinders.", i, (int)cylinders.size());
00981 marker_array.markers.resize(cylinders.size());
00982
00983 for(int j = 0; j < int(cylinders.size()); ++j)
00984 {
00985 marker_array.markers[j].header.frame_id = reference_frame_;
00986 marker_array.markers[j].header.stamp = ros::Time::now();
00987 marker_array.markers[j].ns = "arm_collision_model_" + boost::lexical_cast<std::string>(i);
00988 marker_array.markers[j].id = j;
00989 marker_array.markers[j].type = visualization_msgs::Marker::SPHERE;
00990 marker_array.markers[j].action = visualization_msgs::Marker::ADD;
00991 marker_array.markers[j].scale.x = cylinders[j][3] * 2;
00992 marker_array.markers[j].scale.y = cylinders[j][3] * 2;
00993 marker_array.markers[j].scale.z = cylinders[j][3] * 2;
00994
00995
00996 marker_array.markers[j].color.r = 0.6;
00997 marker_array.markers[j].color.g = 0.6;
00998 marker_array.markers[j].color.b = 0.0;
00999 marker_array.markers[j].color.a = 0.3;
01000 marker_array.markers[j].lifetime = ros::Duration(120.0);
01001
01002 marker_array.markers[j].pose.position.x = cylinders[j][0];
01003 marker_array.markers[j].pose.position.y = cylinders[j][1];
01004 marker_array.markers[j].pose.position.z = cylinders[j][2];
01005
01006 ROS_DEBUG("[visualizeCollisionModel] center: %0.3f %0.3f %0.3f radius: %0.3fm", cylinders[j][0], cylinders[j][1], cylinders[j][2],cylinders[j][3]);
01007 }
01008
01009 if(cylinders.size() > 0)
01010 marker_array_publisher_.publish(marker_array);
01011 }
01012 }
01013
01014 void VisualizeArm::visualizeCollisionModelFromJointTrajectoryMsg(trajectory_msgs::JointTrajectory &traj_msg, sbpl_arm_planner::SBPLCollisionSpace &cspace, int throttle)
01015 {
01016 std::vector<std::vector<double> > traj;
01017
01018 if(traj_msg.points.empty())
01019 {
01020 ROS_WARN("Trajectory message is empty. Not visualizing anything.");
01021 return;
01022 }
01023
01024 traj.resize(traj_msg.points.size());
01025 for(size_t i = 0; i < traj_msg.points.size(); i++)
01026 {
01027 traj[i].resize(traj_msg.points[i].positions.size());
01028 for(size_t j = 0; j < traj_msg.points[i].positions.size(); j++)
01029 traj[i][j] = traj_msg.points[i].positions[j];
01030 }
01031
01032 ROS_DEBUG("[visualizeCollisionModelFromJointTrajectoryMsg] Visualizing collision model of trajectory with length %d ",int(traj.size()));
01033
01034 visualizeCollisionModel(traj, cspace, throttle);
01035 }
01036
01037 void VisualizeArm::visualize3DPath(std::vector<std::vector<double> > &dpath)
01038 {
01039 if(dpath.empty())
01040 {
01041 ROS_INFO("[visualizeShortestPath] The shortest path is empty.");
01042 return;
01043 }
01044 else
01045 ROS_INFO("[visualizeShortestPath] There are %i waypoints in the shortest path.",int(dpath.size()));
01046
01047 visualization_msgs::Marker obs_marker;
01048 obs_marker.header.frame_id = reference_frame_;
01049 obs_marker.header.stamp = ros::Time();
01050 obs_marker.header.seq = 0;
01051 obs_marker.ns = "path";
01052 obs_marker.id = 0;
01053 obs_marker.type = visualization_msgs::Marker::SPHERE_LIST;
01054 obs_marker.action = 0;
01055 obs_marker.scale.x = 3*0.02;
01056 obs_marker.scale.y = 3*0.02;
01057 obs_marker.scale.z = 3*0.02;
01058 obs_marker.color.r = 0.45;
01059 obs_marker.color.g = 0.3;
01060 obs_marker.color.b = 0.4;
01061 obs_marker.color.a = 0.8;
01062 obs_marker.lifetime = ros::Duration(120.0);
01063
01064 obs_marker.points.resize(dpath.size());
01065
01066 for (int k = 0; k < int(dpath.size()); k++)
01067 {
01068 if(int(dpath[k].size()) < 3)
01069 continue;
01070
01071 obs_marker.points[k].x = dpath[k][0];
01072 obs_marker.points[k].y = dpath[k][1];
01073 obs_marker.points[k].z = dpath[k][2];
01074 }
01075
01076 marker_publisher_.publish(obs_marker);
01077 }
01078
01079 void VisualizeArm::visualizeBasicStates(const std::vector<std::vector<double> > &states, const std::vector<double> &color, std::string name, double size)
01080 {
01081 unsigned int inc = 1;
01082 visualization_msgs::Marker marker;
01083
01084
01085 if(states.empty())
01086 {
01087 ROS_DEBUG("[visualizeBasicStates] There are no states in the %s states list.", name.c_str());
01088 return;
01089 }
01090
01091
01092 if(states.size() > 50000)
01093 inc = 4;
01094 else if(states.size() > 10000)
01095 inc = 2;
01096 else
01097 inc = 1;
01098
01099 marker.points.resize(states.size()/inc + 1);
01100
01101 marker.header.seq = 0;
01102 marker.header.stamp = ros::Time::now();
01103 marker.header.frame_id = reference_frame_;
01104
01105 marker.ns = name;
01106 marker.id = 1;
01107 marker.type = visualization_msgs::Marker::POINTS;
01108 marker.action = visualization_msgs::Marker::ADD;
01109 marker.scale.x = size;
01110 marker.scale.y = size;
01111 marker.scale.z = size;
01112 marker.color.r = color[0];
01113 marker.color.g = color[1];
01114 marker.color.b = color[2];
01115 marker.color.a = color[3];
01116 marker.lifetime = ros::Duration(120.0);
01117
01118 unsigned int m_ind = 0;
01119 for(unsigned int i = 0; i < states.size(); i=i+inc)
01120 {
01121 if(states[i].size() >= 3)
01122 {
01123 marker.points[m_ind].x = states[i][0];
01124 marker.points[m_ind].y = states[i][1];
01125 marker.points[m_ind].z = states[i][2];
01126 ++m_ind;
01127 }
01128 }
01129
01130 marker_publisher_.publish(marker);
01131 ROS_DEBUG("[visualizeBasicStates] published %d markers for %s states", int(marker.points.size()), name.c_str());
01132 }
01133
01134 void VisualizeArm::visualizeDetailedStates(const std::vector<std::vector<double> > &states, const std::vector<std::vector<double> >&color, std::string name, double size)
01135 {
01136 unsigned int inc = 1;
01137 std::vector<double> scaled_color(4,0);
01138 visualization_msgs::MarkerArray marker_array;
01139
01140
01141 if(states.empty())
01142 {
01143 ROS_INFO("[visualizeDetailedStates] There are no states in the %s states list", name.c_str());
01144 return;
01145 }
01146 else
01147 ROS_INFO("[visualizeDetailedStates] There are %i states in the %s states list.",int(states.size()),name.c_str());
01148
01149 if(color.size()<2)
01150 {
01151 ROS_INFO("[visualizeDetailedStates] Not enough colors specified.");
01152 return;
01153 }
01154
01155 if(color[0].size() < 4 || color[1].size() < 4)
01156 {
01157 ROS_INFO("[visualizeDetailedStates] RGBA must be specified for each color.");
01158 return;
01159 }
01160
01161
01162 if(states.size() > 50000)
01163 inc = 20;
01164 else if(states.size() > 5000)
01165 inc = 10;
01166 else if(states.size() > 500)
01167 inc = 2;
01168 else
01169 inc = 1;
01170
01171 unsigned int mind = 0;
01172 for(unsigned int i = 0; i < states.size(); i=i+inc)
01173 {
01174 marker_array.markers.resize(marker_array.markers.size()+1);
01175 marker_array.markers[mind].header.frame_id = reference_frame_;
01176 marker_array.markers[mind].header.stamp = ros::Time::now();
01177 marker_array.markers[mind].ns = "expanded_states";
01178 marker_array.markers[mind].id = mind;
01179 marker_array.markers[mind].type = visualization_msgs::Marker::CUBE;
01180 marker_array.markers[mind].action = visualization_msgs::Marker::ADD;
01181 marker_array.markers[mind].scale.x = size;
01182 marker_array.markers[mind].scale.y = size;
01183 marker_array.markers[mind].scale.z = size;
01184
01185 for(unsigned int j = 0; j < 4; ++j)
01186 scaled_color[j] = color[0][j] - ((color[0][j] - color[1][j]) * (double(i)/double(states.size()/inc)));
01187
01188 marker_array.markers[mind].color.r = scaled_color[0];
01189 marker_array.markers[mind].color.g = scaled_color[1];
01190 marker_array.markers[mind].color.b = scaled_color[2];
01191 marker_array.markers[mind].color.a = 1;
01192 marker_array.markers[mind].lifetime = ros::Duration(90.0);
01193
01194 marker_array.markers[mind].pose.position.x = states[i][0];
01195 marker_array.markers[mind].pose.position.y = states[i][1];
01196 marker_array.markers[mind].pose.position.z = states[i][2];
01197
01198 ++mind;
01199 }
01200
01201 ROS_DEBUG("[visualizeDetailedStates] published %d markers for %s states", (int)marker_array.markers.size(), name.c_str());
01202 marker_array_publisher_.publish(marker_array);
01203 }
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239