pxmlw6n2f/Gazebo_Distributed_TCP/gazebo/msgs/msgs.cc

2838 lines
86 KiB
C++
Raw Permalink Normal View History

2019-03-28 10:57:49 +08:00
/*
* Copyright (C) 2012 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <google/protobuf/descriptor.h>
#include <algorithm>
#include <ignition/math/MassMatrix3.hh>
#include <ignition/math/Rand.hh>
#include "gazebo/common/CommonIface.hh"
#include "gazebo/common/Image.hh"
#include "gazebo/common/Exception.hh"
#include "gazebo/common/Console.hh"
#include "gazebo/msgs/msgs.hh"
namespace gazebo
{
namespace msgs
{
/// \internal
/// \brief Internal function to create an SDF element from msgs::Axis.
/// It is only intended to be used by JointToSDF.
/// \param[in] _msg The msgs::Axis object.
/// \param[in] _sdf sdf::ElementPtr to fill with data.
void AxisToSDF(const msgs::Axis &_msg, sdf::ElementPtr _sdf);
/////////////////////////////////////////////
/// Create a request message
msgs::Request *CreateRequest(const std::string &_request,
const std::string &_data)
{
msgs::Request *request = new msgs::Request;
request->set_request(_request);
request->set_data(_data);
request->set_id(ignition::math::Rand::IntUniform(1, 10000));
return request;
}
/////////////////////////////////////////////
const google::protobuf::FieldDescriptor *GetFD(
google::protobuf::Message &message, const std::string &name)
{
return message.GetDescriptor()->FindFieldByName(name);
}
/////////////////////////////////////////////
msgs::Header *GetHeader(google::protobuf::Message &message)
{
google::protobuf::Message *msg = NULL;
if (GetFD(message, "str_id"))
msg = &message;
else
{
const google::protobuf::FieldDescriptor *fd;
fd = GetFD(message, "header");
if (fd)
msg = message.GetReflection()->MutableMessage(&message, fd);
}
return (msgs::Header*)msg;
}
/////////////////////////////////////////////
void Init(google::protobuf::Message &_message, const std::string &_id)
{
msgs::Header *header = GetHeader(_message);
if (header)
{
if (!_id.empty())
header->set_str_id(_id);
Stamp(header->mutable_stamp());
}
}
/////////////////////////////////////////////
void Stamp(msgs::Header *_hdr)
{
Stamp(_hdr->mutable_stamp());
}
/////////////////////////////////////////////
void Stamp(msgs::Time *_time)
{
common::Time tm = common::Time::GetWallTime();
_time->set_sec(tm.sec);
_time->set_nsec(tm.nsec);
}
/////////////////////////////////////////////
std::string Package(const std::string &type,
const google::protobuf::Message &message)
{
std::string data;
msgs::Packet pkg;
Stamp(pkg.mutable_stamp());
pkg.set_type(type);
std::string *serialized_data = pkg.mutable_serialized_data();
if (!message.IsInitialized())
gzthrow("Can't serialize message of type[" + message.GetTypeName() +
"] because it is missing required fields");
if (!message.SerializeToString(serialized_data))
gzthrow("Failed to serialized message");
if (!pkg.SerializeToString(&data))
gzthrow("Failed to serialized message");
return data;
}
/////////////////////////////////////////////
void Set(msgs::Vector3d *_pt, const ignition::math::Vector3d &_v)
{
_pt->set_x(_v.X());
_pt->set_y(_v.Y());
_pt->set_z(_v.Z());
}
/////////////////////////////////////////////
void Set(msgs::Vector2d *_pt, const ignition::math::Vector2d &_v)
{
_pt->set_x(_v.X());
_pt->set_y(_v.Y());
}
/////////////////////////////////////////////
void Set(msgs::Quaternion *_q, const ignition::math::Quaterniond &_v)
{
_q->set_x(_v.X());
_q->set_y(_v.Y());
_q->set_z(_v.Z());
_q->set_w(_v.W());
}
/////////////////////////////////////////////
void Set(msgs::Pose *_p, const ignition::math::Pose3d &_v)
{
Set(_p->mutable_position(), _v.Pos());
Set(_p->mutable_orientation(), _v.Rot());
}
/////////////////////////////////////////////
void Set(msgs::Color *_c, const common::Color &_v)
{
_c->set_r(_v.r);
_c->set_g(_v.g);
_c->set_b(_v.b);
_c->set_a(_v.a);
}
/////////////////////////////////////////////
void Set(msgs::Time *_t, const common::Time &_v)
{
_t->set_sec(_v.sec);
_t->set_nsec(_v.nsec);
}
/////////////////////////////////////////////////
void Set(msgs::SphericalCoordinates *_s,
const common::SphericalCoordinates &_v)
{
switch (_v.GetSurfaceType())
{
case common::SphericalCoordinates::EARTH_WGS84:
_s->set_surface_model(msgs::SphericalCoordinates::EARTH_WGS84);
break;
default:
gzerr << "Unable to map surface type[" << _v.GetSurfaceType()
<< "] to a SphericalCoordinates message.\n";
_s->set_surface_model(msgs::SphericalCoordinates::EARTH_WGS84);
break;
};
_s->set_latitude_deg(_v.LatitudeReference().Degree());
_s->set_longitude_deg(_v.LongitudeReference().Degree());
_s->set_heading_deg(_v.HeadingOffset().Degree());
_s->set_elevation(_v.GetElevationReference());
}
/////////////////////////////////////////////////
void Set(msgs::Inertial *_i, const ignition::math::MassMatrix3d &_m)
{
_i->set_mass(_m.Mass());
_i->set_ixx(_m.IXX());
_i->set_iyy(_m.IYY());
_i->set_izz(_m.IZZ());
_i->set_ixy(_m.IXY());
_i->set_ixz(_m.IXZ());
_i->set_iyz(_m.IYZ());
}
/////////////////////////////////////////////////
void Set(msgs::Inertial *_i, const ignition::math::Inertiald &_m)
{
msgs::Set(_i, _m.MassMatrix());
msgs::Set(_i->mutable_pose(), _m.Pose());
}
/////////////////////////////////////////////////
void Set(msgs::PlaneGeom *_p, const ignition::math::Planed &_v)
{
Set(_p->mutable_normal(), _v.Normal());
_p->mutable_size()->set_x(_v.Size().X());
_p->mutable_size()->set_y(_v.Size().Y());
_p->set_d(_v.Offset());
}
/////////////////////////////////////////////////
void Set(common::Image &_img, const msgs::Image &_msg)
{
_img.SetFromData(
(const unsigned char*)_msg.data().data(),
_msg.width(),
_msg.height(),
(common::Image::PixelFormat)(_msg.pixel_format()));
}
/////////////////////////////////////////////////
void Set(msgs::Image *_msg, const common::Image &_i)
{
_msg->set_width(_i.GetWidth());
_msg->set_height(_i.GetHeight());
_msg->set_pixel_format(_i.GetPixelFormat());
_msg->set_step(_i.GetPitch());
unsigned char *data = NULL;
unsigned int size;
_i.GetData(&data, size);
_msg->set_data(data, size);
if (data)
{
delete[] data;
}
}
/////////////////////////////////////////////////
msgs::Any ConvertAny(const double _d)
{
msgs::Any result;
result.set_type(msgs::Any::DOUBLE);
result.set_double_value(_d);
return result;
}
/////////////////////////////////////////////////
msgs::Any ConvertAny(const int _i)
{
msgs::Any result;
result.set_type(msgs::Any::INT32);
result.set_int_value(_i);
return result;
}
/////////////////////////////////////////////////
msgs::Any ConvertAny(const std::string &_s)
{
msgs::Any result;
result.set_type(msgs::Any::STRING);
result.set_string_value(_s);
return result;
}
/////////////////////////////////////////////////
msgs::Any ConvertAny(const char *_s)
{
msgs::Any result;
result.set_type(msgs::Any::STRING);
result.set_string_value(std::string(_s));
return result;
}
/////////////////////////////////////////////////
msgs::Any ConvertAny(const bool _b)
{
msgs::Any result;
result.set_type(msgs::Any::BOOLEAN);
result.set_bool_value(_b);
return result;
}
/////////////////////////////////////////////////
msgs::Any ConvertAny(const ignition::math::Vector3d &_v)
{
msgs::Any result;
result.set_type(msgs::Any::VECTOR3D);
result.mutable_vector3d_value()->CopyFrom(Convert(_v));
return result;
}
/////////////////////////////////////////////////
msgs::Any ConvertAny(const common::Color &_c)
{
msgs::Any result;
result.set_type(msgs::Any::COLOR);
result.mutable_color_value()->CopyFrom(Convert(_c));
return result;
}
/////////////////////////////////////////////////
msgs::Any ConvertAny(const ignition::math::Pose3d &_p)
{
msgs::Any result;
result.set_type(msgs::Any::POSE3D);
result.mutable_pose3d_value()->CopyFrom(Convert(_p));
return result;
}
/////////////////////////////////////////////////
msgs::Any ConvertAny(const ignition::math::Quaterniond &_q)
{
msgs::Any result;
result.set_type(msgs::Any::QUATERNIOND);
result.mutable_quaternion_value()->CopyFrom(Convert(_q));
return result;
}
/////////////////////////////////////////////////
msgs::Any ConvertAny(const common::Time &_t)
{
msgs::Any result;
result.set_type(msgs::Any::TIME);
result.mutable_time_value()->CopyFrom(Convert(_t));
return result;
}
/////////////////////////////////////////////////
msgs::Vector3d Convert(const ignition::math::Vector3d &_v)
{
msgs::Vector3d result;
result.set_x(_v.X());
result.set_y(_v.Y());
result.set_z(_v.Z());
return result;
}
/////////////////////////////////////////////////
msgs::Vector2d Convert(const ignition::math::Vector2d &_v)
{
msgs::Vector2d result;
result.set_x(_v.X());
result.set_y(_v.Y());
return result;
}
/////////////////////////////////////////////
msgs::Quaternion Convert(const ignition::math::Quaterniond &_q)
{
msgs::Quaternion result;
result.set_x(_q.X());
result.set_y(_q.Y());
result.set_z(_q.Z());
result.set_w(_q.W());
return result;
}
/////////////////////////////////////////////
msgs::Pose Convert(const ignition::math::Pose3d &_p)
{
msgs::Pose result;
result.mutable_position()->CopyFrom(Convert(_p.Pos()));
result.mutable_orientation()->CopyFrom(Convert(_p.Rot()));
return result;
}
/////////////////////////////////////////////
msgs::Color Convert(const common::Color &_c)
{
msgs::Color result;
result.set_r(_c.r);
result.set_g(_c.g);
result.set_b(_c.b);
result.set_a(_c.a);
return result;
}
/////////////////////////////////////////////
msgs::Time Convert(const common::Time &_t)
{
msgs::Time result;
result.set_sec(_t.sec);
result.set_nsec(_t.nsec);
return result;
}
/////////////////////////////////////////////
msgs::Inertial Convert(const ignition::math::Inertiald &_i)
{
msgs::Inertial result;
msgs::Set(&result, _i);
return result;
}
/////////////////////////////////////////////
msgs::Inertial Convert(const ignition::math::MassMatrix3d &_m)
{
msgs::Inertial result;
msgs::Set(&result, _m);
return result;
}
/////////////////////////////////////////////
msgs::PlaneGeom Convert(const ignition::math::Planed &_p)
{
msgs::PlaneGeom result;
result.mutable_normal()->CopyFrom(Convert(_p.Normal()));
result.mutable_size()->set_x(_p.Size().X());
result.mutable_size()->set_y(_p.Size().Y());
result.set_d(_p.Offset());
return result;
}
/////////////////////////////////////////////
msgs::Joint::Type ConvertJointType(const std::string &_str)
{
msgs::Joint::Type result = msgs::Joint::REVOLUTE;
if (_str == "revolute")
{
result = msgs::Joint::REVOLUTE;
}
else if (_str == "revolute2")
{
result = msgs::Joint::REVOLUTE2;
}
else if (_str == "prismatic")
{
result = msgs::Joint::PRISMATIC;
}
else if (_str == "universal")
{
result = msgs::Joint::UNIVERSAL;
}
else if (_str == "ball")
{
result = msgs::Joint::BALL;
}
else if (_str == "screw")
{
result = msgs::Joint::SCREW;
}
else if (_str == "gearbox")
{
result = msgs::Joint::GEARBOX;
}
else if (_str == "fixed")
{
result = msgs::Joint::FIXED;
}
else
{
gzerr << "Unrecognized JointType ["
<< _str
<< "], returning REVOLUTE"
<< std::endl;
}
return result;
}
/////////////////////////////////////////////
std::string ConvertJointType(const msgs::Joint::Type &_type)
{
std::string result;
switch (_type)
{
case msgs::Joint::REVOLUTE:
{
result = "revolute";
break;
}
case msgs::Joint::REVOLUTE2:
{
result = "revolute2";
break;
}
case msgs::Joint::PRISMATIC:
{
result = "prismatic";
break;
}
case msgs::Joint::UNIVERSAL:
{
result = "universal";
break;
}
case msgs::Joint::BALL:
{
result = "ball";
break;
}
case msgs::Joint::SCREW:
{
result = "screw";
break;
}
case msgs::Joint::GEARBOX:
{
result = "gearbox";
break;
}
case msgs::Joint::FIXED:
{
result = "fixed";
break;
}
default:
{
result = "unknown";
gzerr << "Unrecognized JointType [" << _type << "]"
<< std::endl;
break;
}
}
return result;
}
/////////////////////////////////////////////////
msgs::Geometry::Type ConvertGeometryType(const std::string &_str)
{
msgs::Geometry::Type result = msgs::Geometry::BOX;
if (_str == "box")
{
result = msgs::Geometry::BOX;
}
else if (_str == "cylinder")
{
result = msgs::Geometry::CYLINDER;
}
else if (_str == "sphere")
{
result = msgs::Geometry::SPHERE;
}
else if (_str == "plane")
{
result = msgs::Geometry::PLANE;
}
else if (_str == "image")
{
result = msgs::Geometry::IMAGE;
}
else if (_str == "heightmap")
{
result = msgs::Geometry::HEIGHTMAP;
}
else if (_str == "mesh")
{
result = msgs::Geometry::MESH;
}
else if (_str == "polyline")
{
result = msgs::Geometry::POLYLINE;
}
else
{
gzwarn << "Geometry: '" << _str << "' is not recognized, "
<< " returning type as msgs::Geometry::BOX." << std::endl;
}
return result;
}
/////////////////////////////////////////////////
std::string ConvertGeometryType(const msgs::Geometry::Type _type)
{
std::string result;
switch (_type)
{
case msgs::Geometry::BOX:
{
result = "box";
break;
}
case msgs::Geometry::CYLINDER:
{
result = "cylinder";
break;
}
case msgs::Geometry::SPHERE:
{
result = "sphere";
break;
}
case msgs::Geometry::PLANE:
{
result = "plane";
break;
}
case msgs::Geometry::IMAGE:
{
result = "image";
break;
}
case msgs::Geometry::HEIGHTMAP:
{
result = "heightmap";
break;
}
case msgs::Geometry::MESH:
{
result = "mesh";
break;
}
case msgs::Geometry::POLYLINE:
{
result = "polyline";
break;
}
default:
{
result = "unknown";
break;
}
}
return result;
}
/////////////////////////////////////////////
ignition::math::Vector3d ConvertIgn(const msgs::Vector3d &_v)
{
return ignition::math::Vector3d(_v.x(), _v.y(), _v.z());
}
/////////////////////////////////////////////
ignition::math::Vector2d ConvertIgn(const msgs::Vector2d &_v)
{
return ignition::math::Vector2d(_v.x(), _v.y());
}
/////////////////////////////////////////////
ignition::math::Quaterniond ConvertIgn(const msgs::Quaternion &_q)
{
return ignition::math::Quaterniond(_q.w(), _q.x(), _q.y(), _q.z());
}
/////////////////////////////////////////////
ignition::math::Pose3d ConvertIgn(const msgs::Pose &_p)
{
return ignition::math::Pose3d(ConvertIgn(_p.position()),
ConvertIgn(_p.orientation()));
}
/////////////////////////////////////////////
ignition::math::Inertiald Convert(const msgs::Inertial &_i)
{
auto pose = msgs::ConvertIgn(_i.pose());
return ignition::math::Inertiald(
ignition::math::MassMatrix3d(
_i.mass(),
ignition::math::Vector3d(_i.ixx(), _i.iyy(), _i.izz()),
ignition::math::Vector3d(_i.ixy(), _i.ixz(), _i.iyz())),
pose);
}
/////////////////////////////////////////////
common::Color Convert(const msgs::Color &_c)
{
return common::Color(_c.r(), _c.g(), _c.b(), _c.a());
}
/////////////////////////////////////////////
common::Time Convert(const msgs::Time &_t)
{
return common::Time(_t.sec(), _t.nsec());
}
/////////////////////////////////////////////
ignition::math::Planed ConvertIgn(const msgs::PlaneGeom &_p)
{
return ignition::math::Planed(ConvertIgn(_p.normal()),
ignition::math::Vector2d(_p.size().x(), _p.size().y()),
_p.d());
}
/////////////////////////////////////////////
msgs::GUI GUIFromSDF(sdf::ElementPtr _sdf)
{
msgs::GUI result;
result.set_fullscreen(_sdf->Get<bool>("fullscreen"));
// Set gui plugins
if (_sdf->HasElement("plugin"))
{
sdf::ElementPtr pluginElem = _sdf->GetElement("plugin");
while (pluginElem)
{
msgs::Plugin *pluginMsg = result.add_plugin();
pluginMsg->CopyFrom(PluginFromSDF(pluginElem));
pluginElem = pluginElem->GetNextElement("plugin");
}
}
if (_sdf->HasElement("camera"))
{
sdf::ElementPtr camSDF = _sdf->GetElement("camera");
msgs::GUICamera *guiCam = result.mutable_camera();
guiCam->set_name(camSDF->Get<std::string>("name"));
if (camSDF->HasElement("pose"))
{
msgs::Set(guiCam->mutable_pose(),
camSDF->Get<ignition::math::Pose3d>("pose"));
}
if (camSDF->HasElement("view_controller"))
{
guiCam->set_view_controller(
camSDF->Get<std::string>("view_controller"));
}
if (camSDF->HasElement("projection_type"))
{
guiCam->set_projection_type(
camSDF->Get<std::string>("projection_type"));
}
if (camSDF->HasElement("track_visual"))
{
guiCam->mutable_track()->CopyFrom(
TrackVisualFromSDF(camSDF->GetElement("track_visual")));
}
}
return result;
}
/////////////////////////////////////////////
msgs::Plugin PluginFromSDF(const sdf::ElementPtr _sdf)
{
msgs::Plugin result;
result.set_name(_sdf->Get<std::string>("name"));
result.set_filename(_sdf->Get<std::string>("filename"));
std::stringstream ss;
for (sdf::ElementPtr innerElem = _sdf->GetFirstElement();
innerElem; innerElem = innerElem->GetNextElement(""))
{
ss << innerElem->ToString("");
}
result.set_innerxml(ss.str());
return result;
}
/////////////////////////////////////////////////
msgs::TrackVisual TrackVisualFromSDF(sdf::ElementPtr _sdf)
{
msgs::TrackVisual result;
result.set_name(_sdf->Get<std::string>("name"));
if (_sdf->HasElement("min_dist"))
result.set_min_dist(_sdf->GetElement("min_dist")->Get<double>());
if (_sdf->HasElement("max_dist"))
result.set_max_dist(_sdf->GetElement("max_dist")->Get<double>());
return result;
}
/////////////////////////////////////////////////
msgs::Light LightFromSDF(sdf::ElementPtr _sdf)
{
msgs::Light result;
std::string type = _sdf->Get<std::string>("type");
std::transform(type.begin(), type.end(), type.begin(), ::tolower);
result.set_name(_sdf->Get<std::string>("name"));
result.set_cast_shadows(_sdf->Get<bool>("cast_shadows"));
if (type == "point")
result.set_type(msgs::Light::POINT);
else if (type == "spot")
result.set_type(msgs::Light::SPOT);
else if (type == "directional")
result.set_type(msgs::Light::DIRECTIONAL);
if (_sdf->HasElement("pose"))
{
result.mutable_pose()->CopyFrom(
Convert(_sdf->Get<ignition::math::Pose3d>("pose")));
}
if (_sdf->HasElement("diffuse"))
{
result.mutable_diffuse()->CopyFrom(
Convert(_sdf->Get<common::Color>("diffuse")));
}
if (_sdf->HasElement("specular"))
{
result.mutable_specular()->CopyFrom(
Convert(_sdf->Get<common::Color>("specular")));
}
if (_sdf->HasElement("attenuation"))
{
sdf::ElementPtr elem = _sdf->GetElement("attenuation");
result.set_attenuation_constant(elem->Get<double>("constant"));
result.set_attenuation_linear(elem->Get<double>("linear"));
result.set_attenuation_quadratic(elem->Get<double>("quadratic"));
result.set_range(elem->Get<double>("range"));
}
if (_sdf->HasElement("direction"))
{
result.mutable_direction()->CopyFrom(
Convert(_sdf->Get<ignition::math::Vector3d>("direction")));
}
if (_sdf->HasElement("spot"))
{
sdf::ElementPtr elem = _sdf->GetElement("spot");
result.set_spot_inner_angle(elem->Get<double>("inner_angle"));
result.set_spot_outer_angle(elem->Get<double>("outer_angle"));
result.set_spot_falloff(elem->Get<double>("falloff"));
}
return result;
}
/////////////////////////////////////////////////
msgs::MeshGeom MeshFromSDF(sdf::ElementPtr _sdf)
{
msgs::MeshGeom result;
if (_sdf->GetName() != "mesh")
{
gzerr << "Cannot create a mesh message from an "
<< _sdf->GetName() << " SDF element.\n";
return result;
}
msgs::Set(result.mutable_scale(),
_sdf->Get<ignition::math::Vector3d>("scale"));
result.set_filename(_sdf->Get<std::string>("uri"));
if (_sdf->HasElement("submesh"))
{
sdf::ElementPtr submeshElem = _sdf->GetElement("submesh");
if (submeshElem->HasElement("name") &&
submeshElem->Get<std::string>("name") != "__default__")
{
result.set_submesh(submeshElem->Get<std::string>("name"));
if (submeshElem->HasElement("center"))
result.set_center_submesh(submeshElem->Get<bool>("center"));
}
}
return result;
}
/////////////////////////////////////////////////
msgs::Geometry GeometryFromSDF(sdf::ElementPtr _sdf)
{
msgs::Geometry result;
if (_sdf->GetName() != "geometry")
{
gzerr << "Cannot create a geometry message from an "
<< _sdf->GetName() << " SDF element.\n";
return result;
}
// Load the geometry
sdf::ElementPtr geomElem = _sdf->GetFirstElement();
if (!geomElem)
gzthrow("Invalid geometry element");
if (geomElem->GetName() == "box")
{
result.set_type(msgs::Geometry::BOX);
msgs::Set(result.mutable_box()->mutable_size(),
geomElem->Get<ignition::math::Vector3d>("size"));
}
else if (geomElem->GetName() == "cylinder")
{
result.set_type(msgs::Geometry::CYLINDER);
result.mutable_cylinder()->set_radius(
geomElem->Get<double>("radius"));
result.mutable_cylinder()->set_length(
geomElem->Get<double>("length"));
}
else if (geomElem->GetName() == "sphere")
{
result.set_type(msgs::Geometry::SPHERE);
result.mutable_sphere()->set_radius(
geomElem->Get<double>("radius"));
}
else if (geomElem->GetName() == "plane")
{
result.set_type(msgs::Geometry::PLANE);
msgs::Set(result.mutable_plane()->mutable_normal(),
geomElem->Get<ignition::math::Vector3d>("normal"));
msgs::Set(result.mutable_plane()->mutable_size(),
geomElem->Get<ignition::math::Vector2d>("size"));
}
else if (geomElem->GetName() == "polyline")
{
sdf::ElementPtr polylineElem = geomElem;
result.set_type(msgs::Geometry::POLYLINE);
while (polylineElem)
{
msgs::Polyline *polylineMsg = result.add_polyline();
polylineMsg->set_height(polylineElem->Get<double>("height"));
sdf::ElementPtr pointElem = polylineElem->GetElement("point");
while (pointElem)
{
ignition::math::Vector2d point =
pointElem->Get<ignition::math::Vector2d>();
pointElem = pointElem->GetNextElement("point");
msgs::Vector2d *ptMsg = polylineMsg->add_point();
msgs::Set(ptMsg, point);
}
polylineElem = polylineElem->GetNextElement("polyline");
}
}
else if (geomElem->GetName() == "image")
{
result.set_type(msgs::Geometry::IMAGE);
result.mutable_image()->set_scale(
geomElem->Get<double>("scale"));
result.mutable_image()->set_height(
geomElem->Get<double>("height"));
result.mutable_image()->set_uri(
geomElem->Get<std::string>("uri"));
}
else if (geomElem->GetName() == "heightmap")
{
result.set_type(msgs::Geometry::HEIGHTMAP);
// We do not want to set the size field to be the default values of
// [1, 1, 1] if not specified (size is optional for DEMs). So mark it as
// zero for now.
// TODO remove the required rule in heightmapgeom.proto's size field
ignition::math::Vector3d size;
if (geomElem->HasElement("size"))
size = geomElem->Get<ignition::math::Vector3d>("size");
msgs::Set(result.mutable_heightmap()->mutable_size(), size);
msgs::Set(result.mutable_heightmap()->mutable_origin(),
geomElem->Get<ignition::math::Vector3d>("pos"));
if (geomElem->HasElement("sampling"))
{
result.mutable_heightmap()->set_sampling(
geomElem->Get<unsigned int>("sampling"));
}
sdf::ElementPtr textureElem = geomElem->GetElement("texture");
while (textureElem)
{
msgs::HeightmapGeom::Texture *tex =
result.mutable_heightmap()->add_texture();
tex->set_diffuse(textureElem->Get<std::string>("diffuse"));
tex->set_normal(textureElem->Get<std::string>("normal"));
tex->set_size(textureElem->Get<double>("size"));
textureElem = textureElem->GetNextElement("texture");
}
sdf::ElementPtr blendElem = geomElem->GetElement("blend");
while (blendElem)
{
msgs::HeightmapGeom::Blend *blend =
result.mutable_heightmap()->add_blend();
blend->set_min_height(blendElem->Get<double>("min_height"));
blend->set_fade_dist(blendElem->Get<double>("fade_dist"));
blendElem = blendElem->GetNextElement("blend");
}
// Set if the rendering engine uses terrain paging
bool useTerrainPaging =
geomElem->Get<bool>("use_terrain_paging");
result.mutable_heightmap()->set_use_terrain_paging(useTerrainPaging);
result.mutable_heightmap()->set_filename(
geomElem->Get<std::string>("uri"));
}
else if (geomElem->GetName() == "mesh")
{
result.set_type(msgs::Geometry::MESH);
result.mutable_mesh()->CopyFrom(MeshFromSDF(geomElem));
}
else if (geomElem->GetName() == "empty")
{
result.set_type(msgs::Geometry::EMPTY);
}
else
gzthrow("Unknown geometry type\n");
return result;
}
/////////////////////////////////////////////////
msgs::Visual VisualFromSDF(sdf::ElementPtr _sdf)
{
msgs::Visual result;
result.set_name(_sdf->Get<std::string>("name"));
if (_sdf->HasElement("cast_shadows"))
result.set_cast_shadows(_sdf->Get<bool>("cast_shadows"));
if (_sdf->HasElement("transparency"))
result.set_transparency(_sdf->Get<double>("transparency"));
if (_sdf->HasElement("laser_retro"))
result.set_laser_retro(_sdf->Get<double>("laser_retro"));
// Set the meta information
if (_sdf->HasElement("meta"))
{
auto metaElem = _sdf->GetElement("meta");
auto meta = result.mutable_meta();
if (metaElem->HasElement("layer"))
meta->set_layer(metaElem->Get<int32_t>("layer"));
}
// Load the geometry
if (_sdf->HasElement("geometry"))
{
auto geomMsg = result.mutable_geometry();
geomMsg->CopyFrom(GeometryFromSDF(_sdf->GetElement("geometry")));
}
/// Load the material
if (_sdf->HasElement("material"))
{
sdf::ElementPtr elem = _sdf->GetElement("material");
auto matMsg = result.mutable_material();
if (elem->HasElement("script"))
{
sdf::ElementPtr scriptElem = elem->GetElement("script");
matMsg->mutable_script()->set_name(
scriptElem->Get<std::string>("name"));
sdf::ElementPtr uriElem = scriptElem->GetElement("uri");
while (uriElem)
{
matMsg->mutable_script()->add_uri(uriElem->Get<std::string>());
uriElem = uriElem->GetNextElement("uri");
}
}
if (elem->HasElement("lighting"))
{
matMsg->set_lighting(elem->Get<bool>("lighting"));
}
if (elem->HasElement("shader"))
{
sdf::ElementPtr shaderElem = elem->GetElement("shader");
if (shaderElem->Get<std::string>("type") == "pixel")
matMsg->set_shader_type(msgs::Material::PIXEL);
else if (shaderElem->Get<std::string>("type") == "vertex")
matMsg->set_shader_type(msgs::Material::VERTEX);
else if (shaderElem->Get<std::string>("type") ==
"normal_map_object_space")
matMsg->set_shader_type(msgs::Material::NORMAL_MAP_OBJECT_SPACE);
else if (shaderElem->Get<std::string>("type") ==
"normal_map_tangent_space")
matMsg->set_shader_type(msgs::Material::NORMAL_MAP_TANGENT_SPACE);
else
gzthrow(std::string("Unknown shader type[") +
shaderElem->Get<std::string>("type") + "]");
if (shaderElem->HasElement("normal_map"))
matMsg->set_normal_map(
shaderElem->GetElement("normal_map")->Get<std::string>());
}
if (elem->HasElement("ambient"))
msgs::Set(matMsg->mutable_ambient(),
elem->Get<common::Color>("ambient"));
if (elem->HasElement("diffuse"))
msgs::Set(matMsg->mutable_diffuse(),
elem->Get<common::Color>("diffuse"));
if (elem->HasElement("specular"))
msgs::Set(matMsg->mutable_specular(),
elem->Get<common::Color>("specular"));
if (elem->HasElement("emissive"))
msgs::Set(matMsg->mutable_emissive(),
elem->Get<common::Color>("emissive"));
}
// Set the origin of the visual
if (_sdf->HasElement("pose"))
{
msgs::Set(result.mutable_pose(),
_sdf->Get<ignition::math::Pose3d>("pose"));
}
// Set plugins of the visual
if (_sdf->HasElement("plugin"))
{
sdf::ElementPtr pluginElem = _sdf->GetElement("plugin");
while (pluginElem)
{
msgs::Plugin *pluginMsg = result.add_plugin();
pluginMsg->CopyFrom(PluginFromSDF(pluginElem));
// DEPRECATED in Gazebo7, remove in Gazebo8
// duplicate innerxml contents into an <sdf> tag to keep backwards
// compatibility
pluginMsg->set_innerxml(pluginMsg->innerxml() +
"\n<sdf>" + pluginMsg->innerxml() + "</sdf>");
pluginElem = pluginElem->GetNextElement("plugin");
}
}
return result;
}
/////////////////////////////////////////////////
msgs::Collision CollisionFromSDF(sdf::ElementPtr _sdf)
{
msgs::Collision result;
if (_sdf->GetName() != "collision")
{
gzerr << "Cannot create a collision message from a ["
<< _sdf->GetName() << "] SDF element." << std::endl;
return result;
}
result.set_name(_sdf->Get<std::string>("name"));
if (_sdf->HasElement("laser_retro"))
result.set_laser_retro(_sdf->Get<double>("laser_retro"));
if (_sdf->HasElement("max_contacts"))
result.set_max_contacts(_sdf->Get<double>("max_contacts"));
if (_sdf->HasElement("pose"))
{
msgs::Set(result.mutable_pose(),
_sdf->Get<ignition::math::Pose3d>("pose"));
}
// Load the geometry
if (_sdf->HasElement("geometry"))
{
auto geomMsg = result.mutable_geometry();
geomMsg->CopyFrom(GeometryFromSDF(_sdf->GetElement("geometry")));
}
// Load the surface
if (_sdf->HasElement("surface"))
{
auto surfaceMsg = result.mutable_surface();
surfaceMsg->CopyFrom(SurfaceFromSDF(_sdf->GetElement("surface")));
}
return result;
}
/////////////////////////////////////////////////
msgs::Surface SurfaceFromSDF(sdf::ElementPtr _sdf)
{
msgs::Surface result;
if (_sdf->GetName() != "surface")
{
gzerr << "Cannot create a surface message from a ["
<< _sdf->GetName() << "] SDF element." << std::endl;
return result;
}
// Load the friction
if (_sdf->HasElement("friction"))
{
auto frictionMsg = result.mutable_friction();
frictionMsg->CopyFrom(FrictionFromSDF(_sdf->GetElement("friction")));
}
// Load bounce elements
if (_sdf->HasElement("bounce"))
{
sdf::ElementPtr bounceElem = _sdf->GetElement("bounce");
if (bounceElem->HasElement("restitution_coefficient"))
{
result.set_restitution_coefficient(
bounceElem->Get<double>("restitution_coefficient"));
}
if (bounceElem->HasElement("threshold"))
result.set_bounce_threshold(bounceElem->Get<double>("threshold"));
}
// Load contact elements. Note the hierarchy differs in SDF and msg
if (_sdf->HasElement("contact"))
{
sdf::ElementPtr contactElem = _sdf->GetElement("contact");
/// \todo Getting only ODE elements, find a way to get others too
if (contactElem->HasElement("ode"))
{
sdf::ElementPtr odeElem = contactElem->GetElement("ode");
if (odeElem->HasElement("soft_cfm"))
result.set_soft_cfm(odeElem->Get<double>("soft_cfm"));
if (odeElem->HasElement("soft_erp"))
result.set_soft_erp(odeElem->Get<double>("soft_erp"));
if (odeElem->HasElement("kp"))
result.set_kp(odeElem->Get<double>("kp"));
if (odeElem->HasElement("kd"))
result.set_kd(odeElem->Get<double>("kd"));
if (odeElem->HasElement("max_vel"))
result.set_max_vel(odeElem->Get<double>("max_vel"));
if (odeElem->HasElement("min_depth"))
result.set_min_depth(odeElem->Get<double>("min_depth"));
}
if (contactElem->HasElement("collide_without_contact"))
{
result.set_collide_without_contact(
contactElem->Get<bool>("collide_without_contact"));
}
if (contactElem->HasElement("collide_without_contact_bitmask"))
{
result.set_collide_without_contact_bitmask(
contactElem->Get<int>("collide_without_contact_bitmask"));
}
if (contactElem->HasElement("collide_bitmask"))
{
result.set_collide_bitmask(contactElem->Get<int>("collide_bitmask"));
}
}
return result;
}
/////////////////////////////////////////////////
msgs::Friction FrictionFromSDF(sdf::ElementPtr _sdf)
{
msgs::Friction result;
if (_sdf->GetName() != "friction")
{
gzerr << "Cannot create a friction message from a ["
<< _sdf->GetName() << "] SDF element." << std::endl;
return result;
}
/// \todo Getting only ODE elements, find a way to get others too
if (_sdf->HasElement("ode"))
{
sdf::ElementPtr odeElem = _sdf->GetElement("ode");
if (odeElem->HasElement("mu"))
result.set_mu(odeElem->Get<double>("mu"));
if (odeElem->HasElement("mu2"))
result.set_mu2(odeElem->Get<double>("mu2"));
if (odeElem->HasElement("fdir1"))
{
msgs::Set(result.mutable_fdir1(),
odeElem->Get<ignition::math::Vector3d>("fdir1"));
}
if (odeElem->HasElement("slip1"))
result.set_slip1(odeElem->Get<double>("slip1"));
if (odeElem->HasElement("slip2"))
result.set_slip2(odeElem->Get<double>("slip2"));
}
// Load torsional friction
if (_sdf->HasElement("torsional"))
{
sdf::ElementPtr torsionalElem = _sdf->GetElement("torsional");
msgs::Friction::Torsional torsionalMsg;
if (torsionalElem->HasElement("coefficient"))
{
torsionalMsg.set_coefficient(
torsionalElem->Get<double>("coefficient"));
}
if (torsionalElem->HasElement("use_patch_radius"))
{
torsionalMsg.set_use_patch_radius(
torsionalElem->Get<bool>("use_patch_radius"));
}
if (torsionalElem->HasElement("patch_radius"))
{
torsionalMsg.set_patch_radius(
torsionalElem->Get<double>("patch_radius"));
}
if (torsionalElem->HasElement("surface_radius"))
{
torsionalMsg.set_surface_radius(
torsionalElem->Get<double>("surface_radius"));
}
if (torsionalElem->HasElement("ode"))
{
sdf::ElementPtr odeElem = torsionalElem->GetElement("ode");
if (odeElem->HasElement("slip"))
{
msgs::Friction::Torsional::ODE torsionalOdeMsg;
torsionalOdeMsg.set_slip(odeElem->Get<double>("slip"));
auto torsionalODE = torsionalMsg.mutable_ode();
torsionalODE->CopyFrom(torsionalOdeMsg);
}
}
auto torsional = result.mutable_torsional();
torsional->CopyFrom(torsionalMsg);
}
return result;
}
/////////////////////////////////////////////////
msgs::Axis AxisFromSDF(sdf::ElementPtr _sdf)
{
msgs::Axis result;
sdf::ElementPtr limitElem = _sdf->GetElement("limit");
result.set_limit_lower(limitElem->Get<double>("lower"));
result.set_limit_upper(limitElem->Get<double>("upper"));
result.set_limit_effort(limitElem->Get<double>("effort"));
result.set_limit_velocity(limitElem->Get<double>("velocity"));
result.set_use_parent_model_frame(
_sdf->Get<bool>("use_parent_model_frame"));
sdf::ElementPtr dynamicsElem = _sdf->GetElement("dynamics");
result.set_damping(dynamicsElem->Get<double>("damping"));
result.set_friction(dynamicsElem->Get<double>("friction"));
msgs::Set(result.mutable_xyz(),
_sdf->Get<ignition::math::Vector3d>("xyz"));
return result;
}
/////////////////////////////////////////////////
msgs::Joint JointFromSDF(sdf::ElementPtr _sdf)
{
msgs::Joint result;
// Name
result.set_name(_sdf->Get<std::string>("name"));
// parent
if (_sdf->HasElement("parent"))
result.set_parent(_sdf->Get<std::string>("parent"));
// child
if (_sdf->HasElement("child"))
result.set_child(_sdf->Get<std::string>("child"));
// Pose
ignition::math::Pose3d jointPose;
if (_sdf->HasElement("pose"))
{
msgs::Set(result.mutable_pose(),
_sdf->Get<ignition::math::Pose3d>("pose"));
}
// Type
std::string type = _sdf->Get<std::string>("type");
result.set_type(msgs::ConvertJointType(type));
// axis1
if (_sdf->HasElement("axis"))
{
msgs::Axis *axis = result.mutable_axis1();
axis->CopyFrom(AxisFromSDF(_sdf->GetElement("axis")));
result.add_angle(0);
}
// axis2
if (_sdf->HasElement("axis2"))
{
msgs::Axis *axis = result.mutable_axis2();
axis->CopyFrom(AxisFromSDF(_sdf->GetElement("axis2")));
result.add_angle(0);
}
// physics
if (_sdf->HasElement("physics"))
{
sdf::ElementPtr physicsElem = _sdf->GetElement("physics");
if (physicsElem->HasElement("ode"))
{
sdf::ElementPtr odeElem = physicsElem->GetElement("ode");
if (odeElem->HasElement("cfm"))
result.set_cfm(odeElem->Get<double>("cfm"));
if (odeElem->HasElement("bounce"))
result.set_bounce(odeElem->Get<double>("bounce"));
if (odeElem->HasElement("velocity"))
result.set_velocity(odeElem->Get<double>("velocity"));
if (odeElem->HasElement("fudge_factor"))
result.set_fudge_factor(odeElem->Get<double>("fudge_factor"));
if (odeElem->HasElement("limit"))
{
sdf::ElementPtr odeLimitElem = odeElem->GetElement("limit");
if (odeLimitElem->HasElement("cfm"))
result.set_limit_cfm(odeLimitElem->Get<double>("cfm"));
if (odeLimitElem->HasElement("erp"))
result.set_limit_erp(odeLimitElem->Get<double>("erp"));
}
if (odeElem->HasElement("suspension"))
{
sdf::ElementPtr odeSuspensionElem =
odeElem->GetElement("suspension");
if (odeSuspensionElem->HasElement("cfm"))
{
result.set_suspension_cfm(
odeSuspensionElem->Get<double>("cfm"));
}
if (odeSuspensionElem->HasElement("erp"))
{
result.set_suspension_erp(
odeSuspensionElem->Get<double>("erp"));
}
}
}
}
// gearbox
if (_sdf->HasElement("gearbox_reference_body"))
{
msgs::Joint::Gearbox *gearboxMsg = result.mutable_gearbox();
gearboxMsg->set_gearbox_reference_body(
_sdf->Get<std::string>("gearbox_reference_body"));
}
if (_sdf->HasElement("gearbox_ratio"))
{
msgs::Joint::Gearbox *gearboxMsg = result.mutable_gearbox();
gearboxMsg->set_gearbox_ratio(_sdf->Get<double>("gearbox_ratio"));
}
// screw
if (_sdf->HasElement("thread_pitch"))
{
msgs::Joint::Screw *screwMsg = result.mutable_screw();
screwMsg->set_thread_pitch(_sdf->Get<double>("thread_pitch"));
}
return result;
}
/////////////////////////////////////////////////
sdf::ElementPtr VisualToSDF(const msgs::Visual &_msg,
sdf::ElementPtr _sdf)
{
sdf::ElementPtr visualSDF;
if (_sdf)
{
visualSDF = _sdf;
}
else
{
visualSDF.reset(new sdf::Element);
sdf::initFile("visual.sdf", visualSDF);
}
// Set the meta information
if (_msg.has_meta())
{
if (_msg.meta().has_layer())
{
visualSDF->GetElement("meta")->GetElement("layer")->Set(
_msg.meta().layer());
}
}
if (_msg.has_name())
visualSDF->GetAttribute("name")->Set(_msg.name());
if (_msg.has_cast_shadows())
visualSDF->GetElement("cast_shadows")->Set(_msg.cast_shadows());
if (_msg.has_transparency())
visualSDF->GetElement("transparency")->Set(_msg.transparency());
if (_msg.has_laser_retro())
visualSDF->GetElement("laser_retro")->Set(_msg.laser_retro());
if (_msg.has_pose())
visualSDF->GetElement("pose")->Set(ConvertIgn(_msg.pose()));
// Load the geometry
if (_msg.has_geometry())
{
sdf::ElementPtr geomElem = visualSDF->GetElement("geometry");
geomElem = GeometryToSDF(_msg.geometry(), geomElem);
}
/// Load the material
if (_msg.has_material())
{
sdf::ElementPtr materialElem = visualSDF->GetElement("material");
materialElem = MaterialToSDF(_msg.material(), materialElem);
}
// Set plugins of the visual
for (int i = 0; i < _msg.plugin_size(); ++i)
{
sdf::ElementPtr pluginElem = visualSDF->AddElement("plugin");
pluginElem = PluginToSDF(_msg.plugin(i), pluginElem);
}
return visualSDF;
}
/////////////////////////////////////////////////
sdf::ElementPtr MaterialToSDF(const msgs::Material &_msg,
sdf::ElementPtr _sdf)
{
sdf::ElementPtr materialSDF;
if (_sdf)
{
materialSDF = _sdf;
}
else
{
materialSDF.reset(new sdf::Element);
sdf::initFile("material.sdf", materialSDF);
}
if (_msg.has_script())
{
sdf::ElementPtr scriptElem = materialSDF->GetElement("script");
msgs::Material::Script script = _msg.script();
if (script.has_name())
scriptElem->GetElement("name")->Set(script.name());
if (script.uri_size() > 0)
while (scriptElem->HasElement("uri"))
scriptElem->GetElement("uri")->RemoveFromParent();
for (int i = 0; i < script.uri_size(); ++i)
{
sdf::ElementPtr uriElem = scriptElem->AddElement("uri");
uriElem->Set(script.uri(i));
}
}
if (_msg.has_shader_type())
{
sdf::ElementPtr shaderElem = materialSDF->GetElement("shader");
shaderElem->GetAttribute("type")->Set(
ConvertShaderType(_msg.shader_type()));
}
if (_msg.has_normal_map())
{
sdf::ElementPtr shaderElem = materialSDF->GetElement("shader");
shaderElem->GetElement("normal_map")->Set(_msg.normal_map());
}
if (_msg.has_lighting())
materialSDF->GetElement("lighting")->Set(_msg.lighting());
if (_msg.has_ambient())
materialSDF->GetElement("ambient")->Set(Convert(_msg.ambient()));
if (_msg.has_diffuse())
materialSDF->GetElement("diffuse")->Set(Convert(_msg.diffuse()));
if (_msg.has_emissive())
materialSDF->GetElement("emissive")->Set(Convert(_msg.emissive()));
if (_msg.has_specular())
materialSDF->GetElement("specular")->Set(Convert(_msg.specular()));
return materialSDF;
}
/////////////////////////////////////////////////
msgs::Material::ShaderType ConvertShaderType(const std::string &_str)
{
auto result = msgs::Material::VERTEX;
if (_str == "vertex")
{
result = msgs::Material::VERTEX;
}
else if (_str == "pixel")
{
result = msgs::Material::PIXEL;
}
else if (_str == "normal_map_object_space")
{
result = msgs::Material::NORMAL_MAP_OBJECT_SPACE;
}
else if (_str == "normal_map_tangent_space")
{
result = msgs::Material::NORMAL_MAP_TANGENT_SPACE;
}
else
{
gzerr << "Unrecognized ShaderType ["
<< _str
<< "], returning VERTEX"
<< std::endl;
}
return result;
}
/////////////////////////////////////////////////
std::string ConvertShaderType(const msgs::Material::ShaderType &_type)
{
std::string result;
switch (_type)
{
case msgs::Material::VERTEX:
{
result = "vertex";
break;
}
case msgs::Material::PIXEL:
{
result = "pixel";
break;
}
case msgs::Material::NORMAL_MAP_OBJECT_SPACE:
{
result = "normal_map_object_space";
break;
}
case msgs::Material::NORMAL_MAP_TANGENT_SPACE:
{
result = "normal_map_tangent_space";
break;
}
default:
{
result = "unknown";
gzerr << "Unrecognized ShaderType [" << _type << "]"
<< std::endl;
break;
}
}
return result;
}
/////////////////////////////////////////////////
msgs::Fog FogFromSDF(sdf::ElementPtr _sdf)
{
msgs::Fog result;
std::string type = _sdf->Get<std::string>("type");
if (type == "linear")
result.set_type(msgs::Fog::LINEAR);
else if (type == "exp")
result.set_type(msgs::Fog::EXPONENTIAL);
else if (type == "exp2")
result.set_type(msgs::Fog::EXPONENTIAL2);
else if (type == "none")
result.set_type(msgs::Fog::NONE);
else
gzthrow(std::string("Unknown fog type[") + type + "]");
result.mutable_color()->CopyFrom(
Convert(_sdf->Get<common::Color>("color")));
result.set_density(_sdf->Get<double>("density"));
result.set_start(_sdf->Get<double>("start"));
result.set_end(_sdf->Get<double>("end"));
return result;
}
/////////////////////////////////////////////////
msgs::Scene SceneFromSDF(sdf::ElementPtr _sdf)
{
msgs::Scene result;
Init(result, "scene");
if (_sdf->HasElement("grid"))
result.set_grid(_sdf->Get<bool>("grid"));
else
result.set_grid(true);
if (_sdf->HasElement("origin_visual"))
result.set_origin_visual(_sdf->Get<bool>("origin_visual"));
else
result.set_origin_visual(true);
if (_sdf->HasElement("ambient"))
result.mutable_ambient()->CopyFrom(
Convert(_sdf->Get<common::Color>("ambient")));
if (_sdf->HasElement("background"))
{
result.mutable_background()->CopyFrom(
Convert(_sdf->Get<common::Color>("background")));
}
if (_sdf->HasElement("sky"))
{
msgs::Sky *skyMsg = result.mutable_sky();
skyMsg->set_time(_sdf->GetElement("sky")->Get<double>("time"));
skyMsg->set_sunrise(_sdf->GetElement("sky")->Get<double>("sunrise"));
skyMsg->set_sunset(_sdf->GetElement("sky")->Get<double>("sunset"));
if (_sdf->GetElement("sky")->HasElement("clouds"))
{
sdf::ElementPtr cloudsElem =
_sdf->GetElement("sky")->GetElement("clouds");
skyMsg->set_wind_speed(cloudsElem->Get<double>("speed"));
skyMsg->set_wind_direction(cloudsElem->Get<double>("direction"));
skyMsg->set_humidity(cloudsElem->Get<double>("humidity"));
skyMsg->set_mean_cloud_size(cloudsElem->Get<double>("mean_size"));
msgs::Set(skyMsg->mutable_cloud_ambient(),
cloudsElem->Get<common::Color>("ambient"));
}
}
if (_sdf->HasElement("fog"))
result.mutable_fog()->CopyFrom(FogFromSDF(_sdf->GetElement("fog")));
if (_sdf->HasElement("shadows"))
result.set_shadows(_sdf->Get<bool>("shadows"));
return result;
}
/////////////////////////////////////////////////
msgs::Sensor SensorFromSDF(sdf::ElementPtr _sdf)
{
msgs::Sensor result;
std::string type = _sdf->Get<std::string>("type");
result.set_name(_sdf->Get<std::string>("name"));
result.set_type(type);
if (_sdf->HasElement("always_on"))
result.set_always_on(_sdf->Get<bool>("always_on"));
if (_sdf->HasElement("update_rate"))
result.set_update_rate(_sdf->Get<double>("update_rate"));
if (_sdf->HasElement("pose"))
{
msgs::Set(result.mutable_pose(),
_sdf->Get<ignition::math::Pose3d>("pose"));
}
if (_sdf->HasElement("visualize"))
result.set_visualize(_sdf->Get<bool>("visualize"));
if (_sdf->HasElement("topic"))
result.set_topic(_sdf->Get<std::string>("topic"));
if (type == "camera")
{
result.mutable_camera()->CopyFrom(
msgs::CameraSensorFromSDF(_sdf->GetElement("camera")));
}
else if (type == "ray")
{
result.mutable_ray()->CopyFrom(msgs::RaySensorFromSDF(
_sdf->GetElement("ray")));
}
else if (type == "contact")
{
result.mutable_contact()->CopyFrom(
msgs::ContactSensorFromSDF(_sdf->GetElement("contact")));
}
else
{
gzwarn << "Conversion of sensor type[" << type << "] not suppported."
<< std::endl;
}
return result;
}
/////////////////////////////////////////////////
msgs::CameraSensor CameraSensorFromSDF(sdf::ElementPtr _sdf)
{
msgs::CameraSensor result;
result.set_horizontal_fov(_sdf->Get<double>("horizontal_fov"));
result.mutable_image_size()->set_x(
_sdf->GetElement("image")->Get<int>("width"));
result.mutable_image_size()->set_y(
_sdf->GetElement("image")->Get<int>("height"));
if (_sdf->GetElement("image")->HasElement("format"))
{
result.set_image_format(
_sdf->GetElement("image")->Get<std::string>("format"));
}
result.set_near_clip(_sdf->GetElement("clip")->Get<double>("near"));
result.set_far_clip(_sdf->GetElement("clip")->Get<double>("far"));
if (_sdf->HasElement("save"))
{
result.set_save_enabled(_sdf->GetElement("save")->Get<bool>("enabled"));
result.set_save_path(
_sdf->GetElement("save")->Get<std::string>("path"));
}
if (_sdf->HasElement("distortion"))
{
sdf::ElementPtr distElem = _sdf->GetElement("distortion");
msgs::Distortion *distortionMsg = result.mutable_distortion();
if (distElem->HasElement("k1"))
distortionMsg->set_k1(distElem->Get<double>("k1"));
if (distElem->HasElement("k2"))
distortionMsg->set_k2(distElem->Get<double>("k2"));
if (distElem->HasElement("k3"))
distortionMsg->set_k3(distElem->Get<double>("k3"));
if (distElem->HasElement("p1"))
distortionMsg->set_p1(distElem->Get<double>("p1"));
if (distElem->HasElement("p2"))
distortionMsg->set_p2(distElem->Get<double>("p2"));
if (distElem->HasElement("center"))
{
distortionMsg->mutable_center()->set_x(
distElem->Get<ignition::math::Vector2d>("center").X());
distortionMsg->mutable_center()->set_y(
distElem->Get<ignition::math::Vector2d>("center").Y());
}
}
return result;
}
/////////////////////////////////////////////////
msgs::RaySensor RaySensorFromSDF(sdf::ElementPtr _sdf)
{
msgs::RaySensor result;
sdf::ElementPtr rangeElem = _sdf->GetElement("range");
sdf::ElementPtr scanElem = _sdf->GetElement("scan");
sdf::ElementPtr hscanElem = scanElem->GetElement("horizontal");
sdf::ElementPtr vscanElem = scanElem->GetElement("vertical");
result.set_horizontal_samples(hscanElem->Get<int>("samples"));
result.set_horizontal_resolution(hscanElem->Get<double>("resolution"));
result.set_horizontal_min_angle(hscanElem->Get<double>("min_angle"));
result.set_horizontal_max_angle(hscanElem->Get<double>("max_angle"));
result.set_vertical_samples(vscanElem->Get<int>("samples"));
result.set_vertical_resolution(vscanElem->Get<double>("resolution"));
result.set_vertical_min_angle(vscanElem->Get<double>("min_angle"));
result.set_vertical_max_angle(vscanElem->Get<double>("max_angle"));
result.set_range_min(rangeElem->Get<double>("min"));
result.set_range_max(rangeElem->Get<double>("max"));
result.set_range_resolution(rangeElem->Get<double>("resolution"));
return result;
}
/////////////////////////////////////////////////
msgs::ContactSensor ContactSensorFromSDF(sdf::ElementPtr _sdf)
{
msgs::ContactSensor result;
result.set_collision_name(_sdf->Get<std::string>("collision"));
return result;
}
/////////////////////////////////////////////////
sdf::ElementPtr LightToSDF(const msgs::Light &_msg, sdf::ElementPtr _sdf)
{
sdf::ElementPtr lightSDF;
if (_sdf)
{
lightSDF = _sdf;
}
else
{
lightSDF.reset(new sdf::Element);
sdf::initFile("light.sdf", lightSDF);
}
lightSDF->GetAttribute("name")->Set(_msg.name());
if (_msg.has_type() && _msg.type() == msgs::Light::POINT)
lightSDF->GetAttribute("type")->Set("point");
else if (_msg.has_type() && _msg.type() == msgs::Light::SPOT)
lightSDF->GetAttribute("type")->Set("spot");
else if (_msg.has_type() && _msg.type() == msgs::Light::DIRECTIONAL)
lightSDF->GetAttribute("type")->Set("directional");
if (_msg.has_pose())
{
lightSDF->GetElement("pose")->Set(ConvertIgn(_msg.pose()));
}
if (_msg.has_diffuse())
{
lightSDF->GetElement("diffuse")->Set(msgs::Convert(_msg.diffuse()));
}
if (_msg.has_specular())
{
lightSDF->GetElement("specular")->Set(msgs::Convert(_msg.specular()));
}
if (_msg.has_direction())
{
lightSDF->GetElement("direction")->Set(ConvertIgn(_msg.direction()));
}
if (_msg.has_attenuation_constant())
{
sdf::ElementPtr elem = lightSDF->GetElement("attenuation");
elem->GetElement("constant")->Set(_msg.attenuation_constant());
}
if (_msg.has_attenuation_linear())
{
sdf::ElementPtr elem = lightSDF->GetElement("attenuation");
elem->GetElement("linear")->Set(_msg.attenuation_linear());
}
if (_msg.has_attenuation_quadratic())
{
sdf::ElementPtr elem = lightSDF->GetElement("attenuation");
elem->GetElement("quadratic")->Set(_msg.attenuation_quadratic());
}
if (_msg.has_range())
{
sdf::ElementPtr elem = lightSDF->GetElement("attenuation");
elem->GetElement("range")->Set(_msg.range());
}
if (_msg.has_cast_shadows())
lightSDF->GetElement("cast_shadows")->Set(_msg.cast_shadows());
if (_msg.has_spot_inner_angle())
{
sdf::ElementPtr elem = lightSDF->GetElement("spot");
elem->GetElement("inner_angle")->Set(_msg.spot_inner_angle());
}
if (_msg.has_spot_outer_angle())
{
sdf::ElementPtr elem = lightSDF->GetElement("spot");
elem->GetElement("outer_angle")->Set(_msg.spot_outer_angle());
}
if (_msg.has_spot_falloff())
{
sdf::ElementPtr elem = lightSDF->GetElement("spot");
elem->GetElement("falloff")->Set(_msg.spot_falloff());
}
return lightSDF;
}
/////////////////////////////////////////////////
sdf::ElementPtr CameraSensorToSDF(const msgs::CameraSensor &_msg,
sdf::ElementPtr _sdf)
{
sdf::ElementPtr cameraSDF;
if (_sdf)
{
cameraSDF = _sdf;
}
else
{
cameraSDF.reset(new sdf::Element);
sdf::initFile("camera.sdf", cameraSDF);
}
if (_msg.has_horizontal_fov())
{
cameraSDF->GetElement("horizontal_fov")->Set(_msg.horizontal_fov());
}
if (_msg.has_image_size())
{
sdf::ElementPtr imageElem = cameraSDF->GetElement("image");
imageElem->GetElement("width")->Set(_msg.image_size().x());
imageElem->GetElement("height")->Set(_msg.image_size().y());
}
if (_msg.has_image_format())
{
sdf::ElementPtr imageElem = cameraSDF->GetElement("image");
imageElem->GetElement("format")->Set(_msg.image_format());
}
if (_msg.has_near_clip() || _msg.has_far_clip())
{
sdf::ElementPtr clipElem = cameraSDF->GetElement("clip");
if (_msg.has_near_clip())
clipElem->GetElement("near")->Set(_msg.near_clip());
if (_msg.has_far_clip())
clipElem->GetElement("far")->Set(_msg.far_clip());
}
if (_msg.has_distortion())
{
msgs::Distortion distortionMsg = _msg.distortion();
sdf::ElementPtr distortionElem =
cameraSDF->GetElement("distortion");
if (distortionMsg.has_center())
{
distortionElem->GetElement("center")->Set(
ConvertIgn(distortionMsg.center()));
}
if (distortionMsg.has_k1())
{
distortionElem->GetElement("k1")->Set(distortionMsg.k1());
}
if (distortionMsg.has_k2())
{
distortionElem->GetElement("k2")->Set(distortionMsg.k2());
}
if (distortionMsg.has_k3())
{
distortionElem->GetElement("k3")->Set(distortionMsg.k3());
}
if (distortionMsg.has_p1())
{
distortionElem->GetElement("p1")->Set(distortionMsg.p1());
}
if (distortionMsg.has_p2())
{
distortionElem->GetElement("p2")->Set(distortionMsg.p2());
}
}
return cameraSDF;
}
/////////////////////////////////////////////////
sdf::ElementPtr CollisionToSDF(const msgs::Collision &_msg,
sdf::ElementPtr _sdf)
{
sdf::ElementPtr collisionSDF;
if (_sdf)
{
collisionSDF = _sdf;
}
else
{
collisionSDF.reset(new sdf::Element);
sdf::initFile("collision.sdf", collisionSDF);
}
if (_msg.has_name())
collisionSDF->GetAttribute("name")->Set(_msg.name());
if (_msg.has_laser_retro())
collisionSDF->GetElement("laser_retro")->Set(_msg.laser_retro());
if (_msg.has_max_contacts())
collisionSDF->GetElement("max_contacts")->Set(_msg.max_contacts());
if (_msg.has_pose())
collisionSDF->GetElement("pose")->Set(ConvertIgn(_msg.pose()));
if (_msg.has_geometry())
{
sdf::ElementPtr geomElem = collisionSDF->GetElement("geometry");
geomElem = GeometryToSDF(_msg.geometry(), geomElem);
}
if (_msg.has_surface())
{
sdf::ElementPtr surfaceElem = collisionSDF->GetElement("surface");
surfaceElem = SurfaceToSDF(_msg.surface(), surfaceElem);
}
return collisionSDF;
}
/////////////////////////////////////////////////
sdf::ElementPtr LinkToSDF(const msgs::Link &_msg,
sdf::ElementPtr _sdf)
{
sdf::ElementPtr linkSDF;
if (_sdf)
{
linkSDF = _sdf;
}
else
{
linkSDF.reset(new sdf::Element);
sdf::initFile("link.sdf", linkSDF);
}
if (_msg.has_name())
linkSDF->GetAttribute("name")->Set(_msg.name());
if (_msg.has_gravity())
linkSDF->GetElement("gravity")->Set(_msg.gravity());
if (_msg.has_self_collide())
linkSDF->GetElement("self_collide")->Set(_msg.self_collide());
if (_msg.has_kinematic())
linkSDF->GetElement("kinematic")->Set(_msg.kinematic());
if (_msg.has_pose())
linkSDF->GetElement("pose")->Set(ConvertIgn(_msg.pose()));
if (_msg.has_inertial())
{
sdf::ElementPtr inertialElem = linkSDF->GetElement("inertial");
inertialElem = InertialToSDF(_msg.inertial(), inertialElem);
}
if (_msg.collision_size() > 0)
while (linkSDF->HasElement("collision"))
linkSDF->GetElement("collision")->RemoveFromParent();
for (int i = 0; i < _msg.collision_size(); ++i)
{
sdf::ElementPtr collisionElem = linkSDF->AddElement("collision");
collisionElem = CollisionToSDF(_msg.collision(i), collisionElem);
}
if (_msg.visual_size() > 0)
while (linkSDF->HasElement("visual"))
linkSDF->GetElement("visual")->RemoveFromParent();
for (int i = 0; i < _msg.visual_size(); ++i)
{
sdf::ElementPtr visualElem = linkSDF->AddElement("visual");
visualElem = VisualToSDF(_msg.visual(i), visualElem);
}
/// \todo LinkToSDF currently does not convert sensor and projector data
return linkSDF;
}
/////////////////////////////////////////////////
sdf::ElementPtr InertialToSDF(const msgs::Inertial &_msg,
sdf::ElementPtr _sdf)
{
sdf::ElementPtr inertialSDF;
if (_sdf)
{
inertialSDF = _sdf;
}
else
{
inertialSDF.reset(new sdf::Element);
sdf::initFile("inertial.sdf", inertialSDF);
}
if (_msg.has_mass())
inertialSDF->GetElement("mass")->Set(_msg.mass());
if (_msg.has_pose())
inertialSDF->GetElement("pose")->Set(ConvertIgn(_msg.pose()));
sdf::ElementPtr inertiaSDF = inertialSDF->GetElement("inertia");
if (_msg.has_ixx())
inertiaSDF->GetElement("ixx")->Set(_msg.ixx());
if (_msg.has_ixy())
inertiaSDF->GetElement("ixy")->Set(_msg.ixy());
if (_msg.has_ixz())
inertiaSDF->GetElement("ixz")->Set(_msg.ixz());
if (_msg.has_iyy())
inertiaSDF->GetElement("iyy")->Set(_msg.iyy());
if (_msg.has_iyz())
inertiaSDF->GetElement("iyz")->Set(_msg.iyz());
if (_msg.has_izz())
inertiaSDF->GetElement("izz")->Set(_msg.izz());
return inertialSDF;
}
/////////////////////////////////////////////////
sdf::ElementPtr SurfaceToSDF(const msgs::Surface &_msg,
sdf::ElementPtr _sdf)
{
sdf::ElementPtr surfaceSDF;
if (_sdf)
{
surfaceSDF = _sdf;
}
else
{
surfaceSDF.reset(new sdf::Element);
sdf::initFile("surface.sdf", surfaceSDF);
}
if (_msg.has_friction())
{
msgs::Friction friction = _msg.friction();
sdf::ElementPtr frictionElem = surfaceSDF->GetElement("friction");
sdf::ElementPtr physicsEngElem = frictionElem->GetElement("ode");
if (friction.has_mu())
physicsEngElem->GetElement("mu")->Set(friction.mu());
if (friction.has_mu2())
physicsEngElem->GetElement("mu2")->Set(friction.mu2());
if (friction.has_fdir1())
{
physicsEngElem->GetElement("fdir1")->Set(
ConvertIgn(friction.fdir1()));
}
if (friction.has_slip1())
physicsEngElem->GetElement("slip1")->Set(friction.slip1());
if (friction.has_slip2())
physicsEngElem->GetElement("slip2")->Set(friction.slip2());
if (friction.has_torsional())
{
msgs::Friction::Torsional torsional = friction.torsional();
sdf::ElementPtr torsionalElem = frictionElem->GetElement("torsional");
if (torsional.has_coefficient())
{
torsionalElem->GetElement("coefficient")->Set(
torsional.coefficient());
}
if (torsional.has_patch_radius())
{
torsionalElem->GetElement("patch_radius")->Set(
torsional.patch_radius());
}
if (torsional.has_surface_radius())
{
torsionalElem->GetElement("surface_radius")->Set(
torsional.surface_radius());
}
if (torsional.has_use_patch_radius())
{
torsionalElem->GetElement("use_patch_radius")->Set(
torsional.use_patch_radius());
}
if (torsional.has_ode())
{
msgs::Friction::Torsional::ODE ode = torsional.ode();
sdf::ElementPtr odeElem = torsionalElem->GetElement("ode");
if (ode.has_slip())
{
odeElem->GetElement("slip")->Set(ode.slip());
}
}
}
}
sdf::ElementPtr bounceElem = surfaceSDF->GetElement("bounce");
if (_msg.has_restitution_coefficient())
{
bounceElem->GetElement("restitution_coefficient")->Set(
_msg.restitution_coefficient());
}
if (_msg.has_bounce_threshold())
{
bounceElem->GetElement("threshold")->Set(
_msg.bounce_threshold());
}
sdf::ElementPtr contactElem = surfaceSDF->GetElement("contact");
if (_msg.has_collide_without_contact())
{
contactElem->GetElement("collide_without_contact")->Set(
_msg.collide_without_contact());
}
if (_msg.has_collide_without_contact_bitmask())
{
contactElem->GetElement("collide_without_contact_bitmask")->Set(
_msg.collide_without_contact_bitmask());
}
if (_msg.has_collide_bitmask())
{
contactElem->GetElement("collide_bitmask")->Set(
_msg.collide_bitmask());
}
sdf::ElementPtr odeElem = contactElem->GetElement("ode");
sdf::ElementPtr bulletElem = contactElem->GetElement("bullet");
if (_msg.has_soft_cfm())
{
odeElem->GetElement("soft_cfm")->Set(_msg.soft_cfm());
bulletElem->GetElement("soft_cfm")->Set(_msg.soft_cfm());
}
if (_msg.has_soft_erp())
{
odeElem->GetElement("soft_erp")->Set(_msg.soft_erp());
bulletElem->GetElement("soft_erp")->Set(_msg.soft_erp());
}
if (_msg.has_kp())
{
odeElem->GetElement("kp")->Set(_msg.kp());
bulletElem->GetElement("kp")->Set(_msg.kp());
}
if (_msg.has_kd())
{
odeElem->GetElement("kd")->Set(_msg.kd());
bulletElem->GetElement("kd")->Set(_msg.kd());
}
if (_msg.has_max_vel())
{
odeElem->GetElement("max_vel")->Set(_msg.max_vel());
}
if (_msg.has_min_depth())
{
odeElem->GetElement("min_depth")->Set(_msg.min_depth());
}
return surfaceSDF;
}
/////////////////////////////////////////////////
sdf::ElementPtr GeometryToSDF(const msgs::Geometry &_msg,
sdf::ElementPtr _sdf)
{
sdf::ElementPtr geometrySDF;
if (_sdf)
{
geometrySDF = _sdf;
}
else
{
geometrySDF.reset(new sdf::Element);
sdf::initFile("geometry.sdf", geometrySDF);
}
if (!_msg.has_type())
return geometrySDF;
if (_msg.type() == msgs::Geometry::BOX &&
_msg.has_box())
{
sdf::ElementPtr geom = geometrySDF->GetElement("box");
msgs::BoxGeom boxGeom = _msg.box();
if (boxGeom.has_size())
geom->GetElement("size")->Set(ConvertIgn(boxGeom.size()));
}
else if (_msg.type() == msgs::Geometry::CYLINDER &&
_msg.has_cylinder())
{
sdf::ElementPtr geom = geometrySDF->GetElement("cylinder");
msgs::CylinderGeom cylinderGeom = _msg.cylinder();
if (cylinderGeom.has_radius())
geom->GetElement("radius")->Set(cylinderGeom.radius());
if (cylinderGeom.has_length())
geom->GetElement("length")->Set(cylinderGeom.length());
}
else if (_msg.type() == msgs::Geometry::SPHERE &&
_msg.has_sphere())
{
sdf::ElementPtr geom = geometrySDF->GetElement("sphere");
msgs::SphereGeom sphereGeom = _msg.sphere();
if (sphereGeom.has_radius())
geom->GetElement("radius")->Set(sphereGeom.radius());
}
else if (_msg.type() == msgs::Geometry::PLANE &&
_msg.has_plane())
{
sdf::ElementPtr geom = geometrySDF->GetElement("plane");
msgs::PlaneGeom planeGeom = _msg.plane();
if (planeGeom.has_normal())
{
geom->GetElement("normal")->Set(ConvertIgn(planeGeom.normal()));
}
if (planeGeom.has_size())
geom->GetElement("size")->Set(ConvertIgn(planeGeom.size()));
if (planeGeom.has_d())
gzerr << "sdformat doesn't have Plane.d variable" << std::endl;
}
else if (_msg.type() == msgs::Geometry::IMAGE &&
_msg.has_image())
{
sdf::ElementPtr geom = geometrySDF->GetElement("image");
msgs::ImageGeom imageGeom = _msg.image();
if (imageGeom.has_scale())
geom->GetElement("scale")->Set(imageGeom.scale());
if (imageGeom.has_height())
geom->GetElement("height")->Set(imageGeom.height());
if (imageGeom.has_uri())
geom->GetElement("uri")->Set(imageGeom.uri());
if (imageGeom.has_threshold())
geom->GetElement("threshold")->Set(imageGeom.threshold());
if (imageGeom.has_granularity())
geom->GetElement("granularity")->Set(imageGeom.granularity());
}
else if (_msg.type() == msgs::Geometry::HEIGHTMAP &&
_msg.has_heightmap())
{
sdf::ElementPtr geom = geometrySDF->GetElement("heightmap");
msgs::HeightmapGeom heightmapGeom = _msg.heightmap();
if (heightmapGeom.has_size())
{
geom->GetElement("size")->Set(ConvertIgn(heightmapGeom.size()));
}
if (heightmapGeom.has_origin())
{
geom->GetElement("pos")->Set(ConvertIgn(heightmapGeom.origin()));
}
if (heightmapGeom.has_sampling())
{
// check if old version of sdformat is in use
if (geom->HasElementDescription("sampling"))
{
geom->GetElement("sampling")->Set(heightmapGeom.sampling());
}
}
if (heightmapGeom.has_use_terrain_paging())
{
geom->GetElement("use_terrain_paging")->Set(
heightmapGeom.use_terrain_paging());
}
if (heightmapGeom.texture_size() > 0)
while (geom->HasElement("texture"))
geom->GetElement("texture")->RemoveFromParent();
for (int i = 0; i < heightmapGeom.texture_size(); ++i)
{
gazebo::msgs::HeightmapGeom_Texture textureMsg =
heightmapGeom.texture(i);
sdf::ElementPtr textureElem = geom->AddElement("texture");
textureElem->GetElement("diffuse")->Set(textureMsg.diffuse());
textureElem->GetElement("normal")->Set(textureMsg.normal());
textureElem->GetElement("size")->Set(textureMsg.size());
}
if (heightmapGeom.blend_size() > 0)
while (geom->HasElement("blend"))
geom->GetElement("blend")->RemoveFromParent();
for (int i = 0; i < heightmapGeom.blend_size(); ++i)
{
gazebo::msgs::HeightmapGeom_Blend blendMsg =
heightmapGeom.blend(i);
sdf::ElementPtr blendElem = geom->AddElement("blend");
blendElem->GetElement("min_height")->Set(blendMsg.min_height());
blendElem->GetElement("fade_dist")->Set(blendMsg.fade_dist());
}
if (heightmapGeom.has_filename())
geom->GetElement("uri")->Set(heightmapGeom.filename());
}
else if (_msg.type() == msgs::Geometry::MESH &&
_msg.has_mesh())
{
sdf::ElementPtr geom = geometrySDF->GetElement("mesh");
msgs::MeshGeom meshGeom = _msg.mesh();
geom = msgs::MeshToSDF(meshGeom, geom);
}
else if (_msg.type() == msgs::Geometry::POLYLINE &&
_msg.polyline_size() > 0)
{
if (_msg.polyline_size() > 0)
while (geometrySDF->HasElement("polyline"))
geometrySDF->GetElement("polyline")->RemoveFromParent();
for (int j = 0; j < _msg.polyline_size(); ++j)
{
sdf::ElementPtr polylineElem = geometrySDF->AddElement("polyline");
if (_msg.polyline(j).has_height())
polylineElem->GetElement("height")->Set(_msg.polyline(j).height());
for (int i = 0; i < _msg.polyline(j).point_size(); ++i)
{
sdf::ElementPtr pointElem = polylineElem->AddElement("point");
pointElem->Set(ConvertIgn(_msg.polyline(j).point(i)));
}
}
}
else
{
gzerr << "Unrecognized geometry type" << std::endl;
}
return geometrySDF;
}
/////////////////////////////////////////////////
sdf::ElementPtr MeshToSDF(const msgs::MeshGeom &_msg, sdf::ElementPtr _sdf)
{
sdf::ElementPtr meshSDF;
if (_sdf)
{
meshSDF = _sdf;
}
else
{
meshSDF.reset(new sdf::Element);
sdf::initFile("mesh_shape.sdf", meshSDF);
}
if (_msg.has_filename())
meshSDF->GetElement("uri")->Set(_msg.filename());
if (_msg.has_submesh())
{
sdf::ElementPtr submeshElem = meshSDF->GetElement("submesh");
submeshElem->GetElement("name")->Set(_msg.submesh());
if (_msg.has_center_submesh())
submeshElem->GetElement("center")->Set(_msg.center_submesh());
}
if (_msg.has_scale())
{
meshSDF->GetElement("scale")->Set(ConvertIgn(_msg.scale()));
}
return meshSDF;
}
/////////////////////////////////////////////////
sdf::ElementPtr PluginToSDF(const msgs::Plugin &_msg, sdf::ElementPtr _sdf)
{
sdf::ElementPtr pluginSDF;
if (_sdf)
{
pluginSDF = _sdf;
}
else
{
pluginSDF.reset(new sdf::Element);
sdf::initFile("plugin.sdf", pluginSDF);
}
// Use the SDF parser to read all the inner xml.
std::string tmp = "<sdf version='" + std::string(SDF_VERSION) + "'>";
tmp += "<plugin name='" + _msg.name() + "' filename='" +
_msg.filename() + "'>";
tmp += _msg.innerxml();
tmp += "</plugin></sdf>";
sdf::readString(tmp, pluginSDF);
return pluginSDF;
}
////////////////////////////////////////////////////////
void AddLinkGeom(Model &_model, const Geometry &_geom)
{
_model.add_link();
int linkCount = _model.link_size();
auto link = _model.mutable_link(linkCount-1);
{
std::ostringstream linkName;
linkName << "link_" << linkCount;
link->set_name(linkName.str());
}
{
link->add_collision();
auto collision = link->mutable_collision(0);
collision->set_name("collision");
*(collision->mutable_geometry()) = _geom;
}
{
link->add_visual();
auto visual = link->mutable_visual(0);
visual->set_name("visual");
*(visual->mutable_geometry()) = _geom;
auto script = visual->mutable_material()->mutable_script();
script->add_uri();
script->set_uri(0, "file://media/materials/scripts/gazebo.material");
script->set_name("Gazebo/Grey");
}
}
////////////////////////////////////////////////////////
void AddBoxLink(Model &_model, const double _mass,
const ignition::math::Vector3d &_size)
{
Geometry geometry;
geometry.set_type(Geometry_Type_BOX);
Set(geometry.mutable_box()->mutable_size(), _size);
AddLinkGeom(_model, geometry);
int linkCount = _model.link_size();
auto link = _model.mutable_link(linkCount-1);
ignition::math::MassMatrix3d m;
if (!m.SetFromBox(_mass, _size))
{
gzerr << "Error computing inertia, not setting" << std::endl;
}
else
{
msgs::Set(link->mutable_inertial(), m);
}
}
////////////////////////////////////////////////////////
void AddCylinderLink(Model &_model,
const double _mass,
const double _radius,
const double _length)
{
Geometry geometry;
geometry.set_type(Geometry_Type_CYLINDER);
geometry.mutable_cylinder()->set_radius(_radius);
geometry.mutable_cylinder()->set_length(_length);
AddLinkGeom(_model, geometry);
int linkCount = _model.link_size();
auto link = _model.mutable_link(linkCount-1);
ignition::math::MassMatrix3d m;
if (!m.SetFromCylinderZ(_mass, _length, _radius))
{
gzerr << "Error computing inertia, not setting" << std::endl;
}
else
{
msgs::Set(link->mutable_inertial(), m);
}
}
////////////////////////////////////////////////////////
void AddSphereLink(Model &_model, const double _mass,
const double _radius)
{
Geometry geometry;
geometry.set_type(Geometry_Type_SPHERE);
geometry.mutable_sphere()->set_radius(_radius);
AddLinkGeom(_model, geometry);
int linkCount = _model.link_size();
auto link = _model.mutable_link(linkCount-1);
ignition::math::MassMatrix3d m;
if (!m.SetFromSphere(_mass, _radius))
{
gzerr << "Error computing inertia, not setting" << std::endl;
}
else
{
msgs::Set(link->mutable_inertial(), m);
}
}
////////////////////////////////////////////////////////
sdf::ElementPtr ModelToSDF(const msgs::Model &_msg, sdf::ElementPtr _sdf)
{
sdf::ElementPtr modelSDF;
if (_sdf)
{
modelSDF = _sdf;
}
else
{
modelSDF.reset(new sdf::Element);
sdf::initFile("model.sdf", modelSDF);
}
if (_msg.has_name())
modelSDF->GetAttribute("name")->Set(_msg.name());
// ignore the id field, since it's not used in sdformat
if (_msg.has_is_static())
modelSDF->GetElement("static")->Set(_msg.is_static());
if (_msg.has_pose())
modelSDF->GetElement("pose")->Set(msgs::ConvertIgn(_msg.pose()));
if (_msg.joint_size() > 0)
while (modelSDF->HasElement("joint"))
modelSDF->GetElement("joint")->RemoveFromParent();
for (int i = 0; i < _msg.joint_size(); ++i)
{
sdf::ElementPtr jointElem = modelSDF->AddElement("joint");
jointElem = JointToSDF(_msg.joint(i), jointElem);
}
if (_msg.link_size())
while (modelSDF->HasElement("link"))
modelSDF->GetElement("link")->RemoveFromParent();
for (int i = 0; i < _msg.link_size(); ++i)
{
sdf::ElementPtr linkElem = modelSDF->AddElement("link");
linkElem = LinkToSDF(_msg.link(i), linkElem);
}
// ignore the deleted field, since it's not used in sdformat
if (_msg.visual_size() > 0)
{
// model element in SDF cannot store visuals,
// so ignore them for now
gzerr << "Model visuals not yet parsed" << std::endl;
}
// ignore the scale field, since it's not used in sdformat
return modelSDF;
}
////////////////////////////////////////////////////////
sdf::ElementPtr JointToSDF(const msgs::Joint &_msg, sdf::ElementPtr _sdf)
{
sdf::ElementPtr jointSDF;
if (_sdf)
{
jointSDF = _sdf;
}
else
{
jointSDF.reset(new sdf::Element);
sdf::initFile("joint.sdf", jointSDF);
}
if (_msg.has_name())
jointSDF->GetAttribute("name")->Set(_msg.name());
if (_msg.has_type())
jointSDF->GetAttribute("type")->Set(ConvertJointType(_msg.type()));
// ignore the id field, since it's not used in sdformat
// ignore the parent_id field, since it's not used in sdformat
// ignore the child_id field, since it's not used in sdformat
// ignore the angle field, since it's not used in sdformat
if (_msg.has_parent())
jointSDF->GetElement("parent")->Set(_msg.parent());
if (_msg.has_child())
jointSDF->GetElement("child")->Set(_msg.child());
if (_msg.has_pose())
jointSDF->GetElement("pose")->Set(ConvertIgn(_msg.pose()));
if (_msg.has_axis1())
AxisToSDF(_msg.axis1(), jointSDF->GetElement("axis"));
if (_msg.has_axis2())
AxisToSDF(_msg.axis2(), jointSDF->GetElement("axis2"));
auto odePhysicsElem = jointSDF->GetElement("physics")->GetElement("ode");
if (_msg.has_cfm())
odePhysicsElem->GetElement("cfm")->Set(_msg.cfm());
if (_msg.has_bounce())
odePhysicsElem->GetElement("bounce")->Set(_msg.bounce());
if (_msg.has_velocity())
odePhysicsElem->GetElement("velocity")->Set(_msg.velocity());
if (_msg.has_fudge_factor())
odePhysicsElem->GetElement("fudge_factor")->Set(_msg.fudge_factor());
{
auto limitElem = odePhysicsElem->GetElement("limit");
if (_msg.has_limit_cfm())
limitElem->GetElement("cfm")->Set(_msg.limit_cfm());
if (_msg.has_limit_erp())
limitElem->GetElement("erp")->Set(_msg.limit_erp());
}
{
auto suspensionElem = odePhysicsElem->GetElement("suspension");
if (_msg.has_suspension_cfm())
suspensionElem->GetElement("cfm")->Set(_msg.suspension_cfm());
if (_msg.has_suspension_erp())
suspensionElem->GetElement("erp")->Set(_msg.suspension_erp());
}
// gearbox joint message fields
if (_msg.has_gearbox())
{
msgs::Joint::Gearbox gearboxMsg = _msg.gearbox();
if (gearboxMsg.has_gearbox_reference_body())
{
jointSDF->GetElement("gearbox_reference_body")->Set(
gearboxMsg.gearbox_reference_body());
}
if (gearboxMsg.has_gearbox_ratio())
{
jointSDF->GetElement("gearbox_ratio")->Set(
gearboxMsg.gearbox_ratio());
}
}
// screw joint message field
if (_msg.has_screw())
{
msgs::Joint::Screw screwMsg = _msg.screw();
if (screwMsg.has_thread_pitch())
jointSDF->GetElement("thread_pitch")->Set(screwMsg.thread_pitch());
}
/// \todo JointToSDF currently does not convert sensor data
return jointSDF;
}
////////////////////////////////////////////////////////
void AxisToSDF(const msgs::Axis &_msg, sdf::ElementPtr _sdf)
{
if (_msg.has_xyz())
_sdf->GetElement("xyz")->Set(ConvertIgn(_msg.xyz()));
if (_msg.has_use_parent_model_frame())
{
_sdf->GetElement("use_parent_model_frame")->Set(
_msg.use_parent_model_frame());
}
{
auto dynamicsElem = _sdf->GetElement("dynamics");
if (_msg.has_damping())
dynamicsElem->GetElement("damping")->Set(_msg.damping());
if (_msg.has_friction())
dynamicsElem->GetElement("friction")->Set(_msg.friction());
}
{
auto limitElem = _sdf->GetElement("limit");
if (_msg.has_limit_lower())
limitElem->GetElement("lower")->Set(_msg.limit_lower());
if (_msg.has_limit_upper())
limitElem->GetElement("upper")->Set(_msg.limit_upper());
if (_msg.has_limit_effort())
limitElem->GetElement("effort")->Set(_msg.limit_effort());
if (_msg.has_limit_velocity())
limitElem->GetElement("velocity")->Set(_msg.limit_velocity());
}
}
}
}