00001 #include <jsk_interactive_marker/interactive_marker_utils.h>
00002 #include <boost/filesystem/operations.hpp>
00003 #include <iostream>
00004 #include <stdlib.h>
00005 #include <ros/package.h>
00006 #include "urdf_parser/urdf_parser.h"
00007 
00008 #include <kdl/frames_io.hpp>
00009 #include <tf_conversions/tf_kdl.h>
00010 
00011 using namespace urdf;
00012 using namespace std;
00013 using namespace boost;
00014 using namespace boost::filesystem;
00015 
00016 
00017 namespace im_utils {
00018 
00019   
00020   geometry_msgs::Transform Pose2Transform( const geometry_msgs::Pose pose_msg){
00021     geometry_msgs::Transform tf_msg;
00022     tf_msg.translation.x = pose_msg.position.x;
00023     tf_msg.translation.y = pose_msg.position.y;
00024     tf_msg.translation.z = pose_msg.position.z;
00025     tf_msg.rotation = pose_msg.orientation;
00026     return tf_msg;
00027   }
00028 
00029   geometry_msgs::Pose Transform2Pose( const geometry_msgs::Transform tf_msg){
00030     geometry_msgs::Pose pose_msg;
00031     pose_msg.position.x =  tf_msg.translation.x;
00032     pose_msg.position.y = tf_msg.translation.y;
00033     pose_msg.position.z = tf_msg.translation.z;
00034     pose_msg.orientation = tf_msg.rotation;
00035     return pose_msg;
00036   }
00037 
00038   geometry_msgs::Pose UrdfPose2Pose( const urdf::Pose pose){
00039     geometry_msgs::Pose p_msg;
00040     double x, y, z, w;
00041     pose.rotation.getQuaternion(x,y,z,w);
00042     p_msg.orientation.x = x;
00043     p_msg.orientation.y = y;
00044     p_msg.orientation.z = z;
00045     p_msg.orientation.w = w;
00046   
00047     p_msg.position.x = pose.position.x;
00048     p_msg.position.y = pose.position.y;
00049     p_msg.position.z = pose.position.z;
00050 
00051     return p_msg;
00052   }
00053 
00054 
00055   visualization_msgs::InteractiveMarkerControl makeCylinderMarkerControl(const geometry_msgs::PoseStamped &stamped, double length,  double radius, const std_msgs::ColorRGBA &color, bool use_color){
00056     visualization_msgs::Marker cylinderMarker;
00057 
00058     if (use_color) cylinderMarker.color = color;
00059     cylinderMarker.type = visualization_msgs::Marker::CYLINDER;
00060     cylinderMarker.scale.x = radius * 2;
00061     cylinderMarker.scale.y = radius * 2;
00062     cylinderMarker.scale.z = length;
00063     cylinderMarker.pose = stamped.pose;
00064 
00065     visualization_msgs::InteractiveMarkerControl control;
00066     control.markers.push_back( cylinderMarker );
00067     control.interaction_mode = visualization_msgs::InteractiveMarkerControl::BUTTON;
00068     control.always_visible = true;
00069 
00070     return control;
00071   }
00072 
00073   visualization_msgs::InteractiveMarkerControl makeBoxMarkerControl(const geometry_msgs::PoseStamped &stamped, Vector3 dim, const std_msgs::ColorRGBA &color, bool use_color){
00074     visualization_msgs::Marker boxMarker;
00075 
00076     fprintf(stderr, "urdfModelMarker = %f %f %f\n", dim.x, dim.y, dim.z);
00077     if (use_color) boxMarker.color = color;
00078     boxMarker.type = visualization_msgs::Marker::CUBE;
00079     boxMarker.scale.x = dim.x;
00080     boxMarker.scale.y = dim.y;
00081     boxMarker.scale.z = dim.z;
00082     boxMarker.pose = stamped.pose;
00083 
00084     visualization_msgs::InteractiveMarkerControl control;
00085     control.markers.push_back( boxMarker );
00086     control.interaction_mode = visualization_msgs::InteractiveMarkerControl::BUTTON;
00087     control.always_visible = true;
00088 
00089     return control;
00090   }
00091 
00092   visualization_msgs::InteractiveMarkerControl makeSphereMarkerControl(const geometry_msgs::PoseStamped &stamped, double rad, const std_msgs::ColorRGBA &color, bool use_color){
00093     visualization_msgs::Marker sphereMarker;
00094 
00095     if (use_color) sphereMarker.color = color;
00096     sphereMarker.type = visualization_msgs::Marker::SPHERE;
00097     sphereMarker.scale.x = rad * 2;
00098     sphereMarker.scale.y = rad * 2;
00099     sphereMarker.scale.z = rad * 2;
00100     sphereMarker.pose = stamped.pose;
00101 
00102     visualization_msgs::InteractiveMarkerControl control;
00103     control.markers.push_back( sphereMarker );
00104     control.interaction_mode = visualization_msgs::InteractiveMarkerControl::BUTTON;
00105     control.always_visible = true;
00106 
00107     return control;
00108   }
00109 
00110 
00111 
00112   visualization_msgs::InteractiveMarkerControl makeMeshMarkerControl(const std::string &mesh_resource, const geometry_msgs::PoseStamped &stamped, geometry_msgs::Vector3 scale, const std_msgs::ColorRGBA &color, bool use_color){
00113     visualization_msgs::Marker meshMarker;
00114 
00115     if (use_color) meshMarker.color = color;
00116     meshMarker.mesh_resource = mesh_resource;
00117     meshMarker.mesh_use_embedded_materials = !use_color;
00118     meshMarker.type = visualization_msgs::Marker::MESH_RESOURCE;
00119   
00120     meshMarker.scale = scale;
00121     meshMarker.pose = stamped.pose;
00122     visualization_msgs::InteractiveMarkerControl control;
00123     control.markers.push_back( meshMarker );
00124     control.interaction_mode = visualization_msgs::InteractiveMarkerControl::BUTTON;
00125     control.always_visible = true;
00126   
00127     return control;
00128   }
00129 
00130   visualization_msgs::InteractiveMarkerControl makeMeshMarkerControl(const std::string &mesh_resource, const geometry_msgs::PoseStamped &stamped, geometry_msgs::Vector3 scale)
00131   {
00132     std_msgs::ColorRGBA color;
00133     color.r = 0;
00134     color.g = 0;
00135     color.b = 0;
00136     color.a = 0;
00137     return makeMeshMarkerControl(mesh_resource, stamped, scale, color, false);
00138   }
00139 
00140   visualization_msgs::InteractiveMarkerControl makeMeshMarkerControl(const std::string &mesh_resource,
00141                                                                      const geometry_msgs::PoseStamped &stamped, geometry_msgs::Vector3 scale, const std_msgs::ColorRGBA &color)
00142   {
00143     return makeMeshMarkerControl(mesh_resource, stamped, scale, color, true);
00144   }
00145   
00146   void addMeshLinksControl(visualization_msgs::InteractiveMarker &im, LinkConstSharedPtr link, KDL::Frame previous_frame, bool use_color, std_msgs::ColorRGBA color, double scale){
00147     addMeshLinksControl(im, link, previous_frame, use_color, color, scale, true);
00148   }
00149 
00150   void addMeshLinksControl(visualization_msgs::InteractiveMarker &im, LinkConstSharedPtr link, KDL::Frame previous_frame, bool use_color, std_msgs::ColorRGBA color, double scale, bool root){
00151     if(!root && link->parent_joint){
00152       KDL::Frame parent_to_joint_frame;
00153       geometry_msgs::Pose parent_to_joint_pose = UrdfPose2Pose(link->parent_joint->parent_to_joint_origin_transform);
00154       tf::poseMsgToKDL(parent_to_joint_pose, parent_to_joint_frame);
00155       previous_frame =  previous_frame * parent_to_joint_frame;
00156     }
00157 
00158     
00159     
00160     
00161     
00162 
00163     geometry_msgs::PoseStamped ps;
00164     
00165     std::vector<VisualSharedPtr> visual_array;
00166     if(link->visual_array.size() != 0){
00167       visual_array = link->visual_array;
00168     }else if(link->visual.get() != NULL){
00169       visual_array.push_back(link->visual);
00170     }
00171     for(int i=0; i<visual_array.size(); i++){
00172       VisualSharedPtr link_visual = visual_array[i];
00173       if(link_visual.get() != NULL && link_visual->geometry.get() != NULL){
00174         visualization_msgs::InteractiveMarkerControl meshControl;
00175         if(link_visual->geometry->type == Geometry::MESH){
00176 #if ROS_VERSION_MINIMUM(1,14,0) // melodic
00177           MeshConstSharedPtr mesh = std::static_pointer_cast<const Mesh>(link_visual->geometry);
00178 #else
00179         MeshConstSharedPtr mesh = boost::static_pointer_cast<const Mesh>(link_visual->geometry);
00180 #endif
00181           string model_mesh_ = mesh->filename;
00182           model_mesh_ = getRosPathFromModelPath(model_mesh_);
00183           
00184           
00185           KDL::Frame pose_frame, origin_frame;
00186 
00187           tf::poseMsgToKDL(UrdfPose2Pose(link_visual->origin), origin_frame);
00188           pose_frame =  previous_frame * origin_frame;
00189           geometry_msgs::Pose pose;
00190           tf::poseKDLToMsg(pose_frame, pose);
00191           ps.pose = pose;
00192 
00193           cout << "mesh_file:" << model_mesh_ << endl;
00194 
00195           geometry_msgs::Vector3 mesh_scale;
00196           mesh_scale.x = mesh->scale.x * scale;
00197           mesh_scale.y = mesh->scale.y * scale;
00198           mesh_scale.z = mesh->scale.z * scale;
00199           if(use_color){
00200             meshControl = makeMeshMarkerControl(model_mesh_, ps, mesh_scale, color);
00201           }else{
00202             meshControl = makeMeshMarkerControl(model_mesh_, ps, mesh_scale);
00203           }
00204         }else if(link_visual->geometry->type == Geometry::CYLINDER){
00205 #if ROS_VERSION_MINIMUM(1,14,0) // melodic
00206     CylinderConstSharedPtr cylinder = std::static_pointer_cast<const Cylinder>(link_visual->geometry);
00207 #else
00208     CylinderConstSharedPtr cylinder = boost::static_pointer_cast<const Cylinder>(link_visual->geometry);
00209 #endif
00210           std::cout << "cylinder " << link->name;
00211           ps.pose = UrdfPose2Pose(link_visual->origin);
00212           double length = cylinder->length;
00213           double radius = cylinder->radius;
00214           std::cout << ", length =  " << length << ", radius " << radius << std::endl;
00215           if(use_color){
00216             meshControl = makeCylinderMarkerControl(ps, length, radius, color, true);
00217           }else{
00218             meshControl = makeCylinderMarkerControl(ps, length, radius, color, true);
00219           }
00220         }else if(link_visual->geometry->type == Geometry::BOX){
00221 #if ROS_VERSION_MINIMUM(1,14,0) // melodic
00222     BoxConstSharedPtr box = std::static_pointer_cast<const Box>(link_visual->geometry);
00223 #else
00224     BoxConstSharedPtr box = boost::static_pointer_cast<const Box>(link_visual->geometry);
00225 #endif
00226           std::cout << "box " << link->name;
00227           ps.pose = UrdfPose2Pose(link_visual->origin);
00228           Vector3 dim = box->dim;
00229           std::cout << ", dim =  " << dim.x << ", " << dim.y << ", " << dim.z << std::endl;
00230           if(use_color){
00231             meshControl = makeBoxMarkerControl(ps, dim, color, true);
00232           }else{
00233             meshControl = makeBoxMarkerControl(ps, dim, color, true);
00234           }
00235         }else if(link_visual->geometry->type == Geometry::SPHERE){
00236 #if ROS_VERSION_MINIMUM(1,14,0) // melodic
00237     SphereConstSharedPtr sphere = std::static_pointer_cast<const Sphere>(link_visual->geometry);
00238 #else
00239     SphereConstSharedPtr sphere = boost::static_pointer_cast<const Sphere>(link_visual->geometry);
00240 #endif
00241           ps.pose = UrdfPose2Pose(link_visual->origin);
00242           double rad = sphere->radius;
00243           if(use_color){
00244             meshControl = makeSphereMarkerControl(ps, rad, color, true);
00245           }else{
00246             meshControl = makeSphereMarkerControl(ps, rad, color, true);
00247           }
00248         }
00249         im.controls.push_back( meshControl );
00250 
00251       }
00252     }
00253     for (std::vector<LinkSharedPtr>::const_iterator child = link->child_links.begin(); child != link->child_links.end(); child++){
00254       addMeshLinksControl(im, *child, previous_frame, use_color, color, scale, false);
00255     }
00256   }
00257 
00258   ModelInterfaceSharedPtr getModelInterface(std::string model_file){
00259     ModelInterfaceSharedPtr model;
00260     model_file = getFilePathFromRosPath(model_file);
00261     model_file = getFullPathFromModelPath(model_file);
00262     std::string xml_string;
00263     std::fstream xml_file(model_file.c_str(), std::fstream::in);
00264     while ( xml_file.good() )
00265       {
00266         std::string line;
00267         std::getline( xml_file, line);
00268         xml_string += (line + "\n");
00269       }
00270     xml_file.close();
00271 
00272     std::cout << "model_file:" << model_file << std::endl;
00273     model = parseURDF(xml_string);
00274     if (!model){
00275       std::cerr << "ERROR: Model Parsing the xml failed" << std::endl;
00276     }
00277     return model;
00278   }
00279 
00280   
00281   visualization_msgs::InteractiveMarker makeLinksMarker(LinkConstSharedPtr link, bool use_color, std_msgs::ColorRGBA color, geometry_msgs::PoseStamped marker_ps, geometry_msgs::Pose origin_pose)
00282   {
00283     visualization_msgs::InteractiveMarker int_marker;
00284     int_marker.header = marker_ps.header;
00285     int_marker.pose = marker_ps.pose;
00286 
00287     int_marker.name = "sample";
00288     int_marker.scale = 1.0;
00289 
00290     KDL::Frame origin_frame;
00291     tf::poseMsgToKDL(origin_pose, origin_frame);
00292     addMeshLinksControl(int_marker, link, origin_frame, use_color, color, 1.0);
00293     return int_marker;
00294 
00295   }
00296 
00297 
00298 
00299   visualization_msgs::InteractiveMarker makeFingerControlMarker(const char *name, geometry_msgs::PoseStamped ps){
00300     visualization_msgs::InteractiveMarker int_marker;
00301     int_marker.name = name;
00302     int_marker.header = ps.header;
00303     int_marker.pose = ps.pose;
00304     int_marker.scale = 0.5;
00305 
00306     visualization_msgs::InteractiveMarkerControl control;
00307 
00308     
00309     control.interaction_mode = visualization_msgs::InteractiveMarkerControl::ROTATE_AXIS;
00310     control.orientation.w = 1;
00311     control.orientation.x = 0;
00312     control.orientation.y = 0;
00313     control.orientation.z = 1;
00314 
00315     int_marker.controls.push_back(control);
00316 
00317     return int_marker;
00318 
00319   }
00320 
00321   
00322 
00323 
00324 
00325 
00326 
00327 
00328 
00329 
00330 
00331 
00332 
00333 
00334 
00335 
00336 
00337 
00338 
00339 
00340 
00341 
00342 
00343 
00344 
00345 
00346 
00347 
00348 
00349 
00350 
00351 
00352 
00353 
00354 
00355 
00356 
00357 
00358 
00359 
00360 
00361 
00362 
00363 
00364 
00365 
00366 
00367 
00368 
00369 
00370 
00371 
00372 
00373 
00374 
00375 
00376 
00377 
00378 
00379 
00380 
00381 
00382 
00383   visualization_msgs::InteractiveMarker makeSandiaHandInteractiveMarker(geometry_msgs::PoseStamped ps, std::string hand, int finger, int link){
00384     visualization_msgs::InteractiveMarker int_marker;
00385     int_marker.header = ps.header;
00386     int_marker.pose = ps.pose;
00387   
00388 
00389     visualization_msgs::InteractiveMarkerControl control;
00390     std::stringstream ss;
00391     
00392     ss << hand << "_f" << finger << "_" << link;
00393   
00394     int_marker.name = ss.str() + "Marker";
00395     int_marker.header.frame_id = ss.str();
00396     
00397     std::string frame_id = "utorso";
00398     int_marker.header.frame_id = frame_id;
00399     std::cout << ss.str() << std::endl;
00400 
00401     
00402     switch(link){
00403     case 0:
00404       control.markers.push_back(makeSandiaFinger0Marker(frame_id));
00405       break;
00406     case 1:
00407       control.markers.push_back(makeSandiaFinger1Marker(frame_id));
00408       break;
00409     case 2:
00410       control.markers.push_back(makeSandiaFinger2Marker(frame_id));
00411       break;
00412     default:
00413       break;
00414     }
00415     control.interaction_mode = visualization_msgs::InteractiveMarkerControl::BUTTON;
00416     int_marker.controls.push_back(control);
00417 
00418     return int_marker;
00419   }
00420 
00421 
00422 
00423   visualization_msgs::Marker makeSandiaFinger0Marker(std::string frame_id){
00424     visualization_msgs::Marker marker;
00425     marker.header.frame_id = frame_id;
00426     
00427     marker.type = visualization_msgs::Marker::CYLINDER;
00428     marker.action = visualization_msgs::Marker::ADD;
00429     marker.pose.position.x = 0;
00430     marker.pose.position.y = 0;
00431     marker.pose.position.z = 0.003;
00432     marker.pose.orientation.x = 0.0;
00433     marker.pose.orientation.y = 0.0;
00434     marker.pose.orientation.z = 0.0;
00435     marker.pose.orientation.w = 1.0;
00436     marker.scale.x = 0.03;
00437     marker.scale.y = 0.03;
00438     marker.scale.z = 0.023;
00439     marker.color.a = 1.0;
00440     marker.color.r = 0.0;
00441     marker.color.g = 1.0;
00442     marker.color.b = 0.0;
00443 
00444     return marker;
00445   }
00446 
00447   visualization_msgs::Marker makeSandiaFinger1Marker(std::string frame_id){
00448     visualization_msgs::Marker marker;
00449     marker.header.frame_id = frame_id;
00450     marker.type = visualization_msgs::Marker::CYLINDER;
00451     marker.action = visualization_msgs::Marker::ADD;
00452     marker.pose.position.x = 0.024;
00453     marker.pose.position.y = 0;
00454     marker.pose.position.z = 0;
00455     marker.pose.orientation.x = 0.0;
00456     marker.pose.orientation.y = 1.0;
00457     marker.pose.orientation.z = 0.0;
00458     marker.pose.orientation.w = 1.0;
00459     marker.scale.x = 0.02;
00460     marker.scale.y = 0.02;
00461     marker.scale.z = 0.067;
00462     marker.color.a = 1.0;
00463     marker.color.r = 0.0;
00464     marker.color.g = 1.0;
00465     marker.color.b = 0.0;
00466 
00467     return marker;
00468   }
00469 
00470   visualization_msgs::Marker makeSandiaFinger2Marker(std::string frame_id){
00471     visualization_msgs::Marker marker;
00472     marker.header.frame_id = frame_id;
00473     marker.type = visualization_msgs::Marker::CYLINDER;
00474     marker.action = visualization_msgs::Marker::ADD;
00475     marker.pose.position.x = 0.024;
00476     marker.pose.position.y = 0;
00477     marker.pose.position.z = 0;
00478     marker.pose.orientation.x = 0.0;
00479     marker.pose.orientation.y = 1.0;
00480     marker.pose.orientation.z = 0.0;
00481     marker.pose.orientation.w = 1.0;
00482     marker.scale.x = 0.018;
00483     marker.scale.y = 0.018;
00484     marker.scale.z = 0.057;
00485     marker.color.a = 1.0;
00486     marker.color.r = 0.0;
00487     marker.color.g = 1.0;
00488     marker.color.b = 0.0;
00489 
00490     return marker;
00491   }
00492 
00493   std::string getRosPathFromModelPath(std::string path){
00494     return getRosPathFromFullPath(getFullPathFromModelPath(path));
00495   }
00496 
00497   std::string getRosPathFromFullPath(std::string path){
00498     std::string ros_package_path = "";
00499     FILE* fp;
00500     char buf[1000000];
00501 
00502     
00503     if ((fp = popen("echo $ROS_PACKAGE_PATH", "r")) == NULL) {
00504       std::cout << "popen error" << std::endl;
00505     }
00506     while (fgets(buf, sizeof(buf), fp) != NULL) {
00507       ros_package_path += buf;
00508     }
00509     pclose(fp);
00510 
00511     if( path.find("file://", 0) == 0 ){
00512       path.erase(0,7);
00513 
00514       
00515       size_t current = 0, found;
00516       while((found = ros_package_path.find_first_of(":", current)) != std::string::npos){
00517         std::string search_path = std::string(ros_package_path, current, found - current);
00518         current = found + 1;
00519         if(path.find(search_path, 0) == 0){
00520           path.erase(0, strlen(search_path.c_str()));
00521           break;
00522         }
00523       }
00524 
00525       std::string tmp[] = {"", "jsk-ros-pkg", "jsk_model_tools"};
00526       std::set<std::string> package_blackset(tmp, tmp + sizeof(tmp) / sizeof(tmp[0]));
00527 
00528       current = 0;
00529       while((found = path.find_first_of("/", current)) != std::string::npos){
00530         std::string search_path = std::string(path, current, found - current);
00531         current = found + 1;
00532         std::string package_path;
00533 
00534         
00535         if(package_blackset.find(search_path) != package_blackset.end()){
00536           continue;
00537         }
00538 
00539         if( search_path != "" && ros::package::getPath(search_path) != ""){
00540           return "package://" + search_path + path.erase(0, current-1);
00541         }
00542       }
00543       path = "file://" + path;
00544     }
00545 
00546     return path;
00547   }
00548 
00549   std::string getFullPathFromModelPath(std::string path){
00550     std::string gazebo_model_path="";
00551   
00552     FILE* fp;
00553     char buf[1000000];
00554 
00555     
00556     if ((fp = popen("echo $GAZEBO_MODEL_PATH", "r")) == NULL) {
00557       std::cout << "popen error" << std::endl;
00558     }
00559     while (fgets(buf, sizeof(buf), fp) != NULL) {
00560       gazebo_model_path += buf;
00561     }
00562     pclose(fp);
00563     if( path.find("model://", 0) == 0 ){
00564       path.erase(0,8);
00565       
00566       
00567 
00568       size_t current = 0, found;
00569       while((found = gazebo_model_path.find_first_of(":", current)) != std::string::npos){
00570         try{
00571           std::string search_path = std::string(gazebo_model_path, current, found - current);
00572           current = found + 1;
00573           recursive_directory_iterator iter = recursive_directory_iterator(search_path);
00574           recursive_directory_iterator end = recursive_directory_iterator();
00575           for (; iter != end; ++iter) {
00576             if (is_regular_file(*iter)) {
00577               int locate = iter->path().string().find( path, 0 );
00578               if( locate != std::string::npos){
00579                 
00580                 return "file://" + iter->path().string();
00581               }
00582             }
00583           }
00584         }catch(...){
00585         }
00586       }
00587     }
00588     return path;
00589   }
00590 
00591   
00592   std::string getFilePathFromRosPath( std::string rospath){
00593     std::string path = rospath;
00594     if (path.find("package://") == 0){
00595       path.erase(0, strlen("package://"));
00596       size_t pos = path.find("/");
00597       if (pos == std::string::npos){
00598         std::cout << "Could not parse package:// format" <<std::endl;
00599         return "";
00600       }
00601       std::string package = path.substr(0, pos);
00602       path.erase(0, pos);
00603       std::string package_path = ros::package::getPath(package);
00604       if (package_path.empty())
00605         {
00606           std::cout <<  "Package [" + package + "] does not exist" << std::endl;
00607         }
00608  
00609       path = package_path + path;
00610     }
00611     return path;
00612   }
00613 
00614   geometry_msgs::Pose getPose( XmlRpc::XmlRpcValue val){
00615     geometry_msgs::Pose p;
00616     if(val.hasMember("position")){
00617       XmlRpc::XmlRpcValue pos = val["position"];
00618       p.position.x = getXmlValue(pos["x"]);
00619       p.position.y = getXmlValue(pos["y"]);
00620       p.position.z = getXmlValue(pos["z"]);
00621     }else{
00622       p.position.x = p.position.y = p.position.z = 0.0;
00623     }
00624 
00625     if(val.hasMember("orientation")){
00626       XmlRpc::XmlRpcValue ori = val["orientation"];
00627       p.orientation.x = getXmlValue(ori["x"]);
00628       p.orientation.y = getXmlValue(ori["y"]);
00629       p.orientation.z = getXmlValue(ori["z"]);
00630       p.orientation.w = getXmlValue(ori["w"]);
00631     }else{
00632       p.orientation.x = p.orientation.y = p.orientation.z = 0.0;
00633       p.orientation.w = 1.0;
00634     }
00635 
00636     return p;
00637   }
00638 
00639   double getXmlValue( XmlRpc::XmlRpcValue val ){
00640     switch(val.getType()){
00641     case XmlRpc::XmlRpcValue::TypeInt:
00642       return (double)((int)val);
00643     case XmlRpc::XmlRpcValue::TypeDouble:
00644       return (double)val;
00645     default:
00646       return 0;
00647     }
00648   }
00649 
00650 }
00651 
00652