pxmlw6n2f/Gazebo_Distributed_TCP/gazebo/physics/Actor.cc

751 lines
25 KiB
C++

/*
* 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.
*
*/
#ifdef _WIN32
// Ensure that Winsock2.h is included before Windows.h, which can get
// pulled in by anybody (e.g., Boost).
#include <Winsock2.h>
#endif
#include <boost/thread/recursive_mutex.hpp>
#include <sstream>
#include <limits>
#include <algorithm>
#include "gazebo/msgs/msgs.hh"
#include "gazebo/common/KeyFrame.hh"
#include "gazebo/common/Animation.hh"
#include "gazebo/common/Plugin.hh"
#include "gazebo/common/Events.hh"
#include "gazebo/common/Exception.hh"
#include "gazebo/common/Console.hh"
#include "gazebo/common/CommonTypes.hh"
#include "gazebo/common/MeshManager.hh"
#include "gazebo/common/Mesh.hh"
#include "gazebo/common/Skeleton.hh"
#include "gazebo/common/SkeletonAnimation.hh"
#include "gazebo/common/BVHLoader.hh"
#include "gazebo/physics/World.hh"
#include "gazebo/physics/Joint.hh"
#include "gazebo/physics/Link.hh"
#include "gazebo/physics/Model.hh"
#include "gazebo/physics/PhysicsEngine.hh"
#include "gazebo/physics/Actor.hh"
#include "gazebo/physics/PhysicsIface.hh"
#include "gazebo/transport/Node.hh"
using namespace gazebo;
using namespace physics;
using namespace common;
//////////////////////////////////////////////////
Actor::Actor(BasePtr _parent)
: Model(_parent)
{
this->AddType(ACTOR);
this->mesh = NULL;
this->skeleton = NULL;
this->pathLength = 0.0;
this->lastTraj = 1e+5;
}
//////////////////////////////////////////////////
Actor::~Actor()
{
this->skelAnimation.clear();
this->bonePosePub.reset();
}
//////////////////////////////////////////////////
void Actor::Load(sdf::ElementPtr _sdf)
{
sdf::ElementPtr skinSdf = _sdf->GetElement("skin");
this->skinFile = skinSdf->Get<std::string>("filename");
this->skinScale = skinSdf->Get<double>("scale");
MeshManager::Instance()->Load(this->skinFile);
std::string actorName = _sdf->Get<std::string>("name");
/* double radius = 1.0;
unsigned int pointNum = 32;
for (unsigned int i = 0; i < pointNum; i++)
{
double angle = (2 * i * M_PI) / pointNum;
double x = radius * sin(angle);
double y = radius * cos(angle);
if (ignition::math::equal(x, 0.0))
x = 0;
if (ignition::math::equal(y, 0.0))
y = 0;
std::cerr << x << " " << y << " 0 0 0 " << angle << "\n";
} */
if (MeshManager::Instance()->HasMesh(this->skinFile))
{
this->mesh = MeshManager::Instance()->GetMesh(this->skinFile);
if (!this->mesh->HasSkeleton())
gzthrow("Collada file does not contain skeletal animation.");
this->skeleton = mesh->GetSkeleton();
this->skeleton->Scale(this->skinScale);
/// create the link sdfs for the model
NodeMap nodes = this->skeleton->GetNodes();
/// self_collide should be added to prevent error messages
// _sdf->GetElement("self_collide")->Set(false);
sdf::ElementPtr linkSdf;
linkSdf = _sdf->GetElement("link");
linkSdf->GetAttribute("name")->Set(actorName + "_pose");
linkSdf->GetElement("gravity")->Set(false);
linkSdf->GetElement("self_collide")->Set(false);
sdf::ElementPtr linkPose = linkSdf->GetElement("pose");
// this->AddSphereInertia(linkSdf, ignition::math::Pose3d(), 1.0, 0.01);
// this->AddSphereCollision(linkSdf, actorName + "_pose_col",
// ignition::math::Pose3d(), 0.02);
// this->AddBoxVisual(linkSdf, actorName + "_pose_vis",
// ignition::math::Pose3d(),
// ignition::math::Vector3d(0.05, 0.05, 0.05), "Gazebo/White",
// Color::White);
this->AddActorVisual(linkSdf, actorName + "_visual",
ignition::math::Pose3d::Zero);
std::string actorLinkName = actorName + "::" + actorName + "_pose";
this->visualName = actorLinkName + "::"
+ actorName + "_visual";
for (NodeMapIter iter = nodes.begin(); iter != nodes.end(); ++iter)
{
SkeletonNode* bone = iter->second;
linkSdf = _sdf->AddElement("link");
linkSdf->GetAttribute("name")->Set(bone->GetName());
linkSdf->GetElement("gravity")->Set(false);
linkSdf->GetElement("self_collide")->Set(false);
linkPose = linkSdf->GetElement("pose");
ignition::math::Pose3d pose(bone->ModelTransform().Translation(),
bone->ModelTransform().Rotation());
if (bone->IsRootNode())
pose = ignition::math::Pose3d::Zero;
linkPose->Set(pose);
/// FIXME hardcoded inertia of a sphere with mass 1.0 and radius 0.01
this->AddSphereInertia(linkSdf, ignition::math::Pose3d::Zero, 1.0, 0.01);
/// FIXME hardcoded collision to sphere with radius 0.02
this->AddSphereCollision(linkSdf, bone->GetName() + "_collision",
ignition::math::Pose3d::Zero, 0.02);
/// FIXME hardcoded visual to red sphere with radius 0.02
if (bone->IsRootNode())
{
this->AddSphereVisual(linkSdf, bone->GetName() + "__SKELETON_VISUAL__",
ignition::math::Pose3d::Zero, 0.02, "Gazebo/Blue", Color::Blue);
}
else
if (bone->GetChildCount() == 0)
{
this->AddSphereVisual(linkSdf, bone->GetName() +
"__SKELETON_VISUAL__", ignition::math::Pose3d::Zero, 0.02,
"Gazebo/Yellow", Color::Yellow);
}
else
{
this->AddSphereVisual(linkSdf, bone->GetName() +
"__SKELETON_VISUAL__", ignition::math::Pose3d::Zero, 0.02,
"Gazebo/Red", Color::Red);
}
for (unsigned int i = 0; i < bone->GetChildCount(); ++i)
{
SkeletonNode *curChild = bone->GetChild(i);
ignition::math::Vector3d dir =
curChild->ModelTransform().Translation() -
bone->ModelTransform().Translation();
double length = dir.Length();
if (!ignition::math::equal(length, 0.0))
{
ignition::math::Vector3d r =
curChild->Transform().Translation();
ignition::math::Vector3d linkPos =
ignition::math::Vector3d(r.X() / 2.0, r.Y() / 2.0, r.Z() / 2.0);
double theta = atan2(dir.Y(), dir.X());
double phi = acos(dir.Z() / length);
ignition::math::Pose3d bonePose(linkPos,
ignition::math::Quaterniond(0.0, phi, theta));
bonePose.Rot() = pose.Rot().Inverse() * bonePose.Rot();
this->AddBoxVisual(linkSdf, bone->GetName() + "_" +
curChild->GetName() + "__SKELETON_VISUAL__", bonePose,
ignition::math::Vector3d(0.02, 0.02, length),
"Gazebo/Green", Color::Green);
}
}
}
sdf::ElementPtr animSdf = _sdf->GetElement("animation");
while (animSdf)
{
this->LoadAnimation(animSdf);
animSdf = animSdf->GetNextElement("animation");
}
this->LoadScript(_sdf->GetElement("script"));
/// we are ready to load the links
Model::Load(_sdf);
LinkPtr actorLinkPtr = Model::GetLink(actorLinkName);
if (actorLinkPtr)
{
msgs::Visual actorVisualMsg = actorLinkPtr->GetVisualMessage(
this->visualName);
if (actorVisualMsg.has_id())
this->visualId = actorVisualMsg.id();
else
gzerr << "No actor visual message found.";
}
else
{
gzerr << "No actor link found.";
}
this->bonePosePub = this->node->Advertise<msgs::PoseAnimation>(
"~/skeleton_pose/info", 10);
}
}
//////////////////////////////////////////////////
void Actor::LoadScript(sdf::ElementPtr _sdf)
{
this->loop = _sdf->Get<bool>("loop");
this->startDelay = _sdf->Get<double>("delay_start");
this->autoStart = _sdf->Get<bool>("auto_start");
this->active = this->autoStart;
if (_sdf->HasElement("trajectory"))
{
sdf::ElementPtr trajSdf = _sdf->GetElement("trajectory");
while (trajSdf)
{
if (this->skelAnimation.find(trajSdf->Get<std::string>("type")) ==
this->skelAnimation.end())
{
gzwarn << "Resource not found for trajectory of type " <<
trajSdf->Get<std::string>("type") << "\n";
continue;
}
TrajectoryInfo tinfo;
tinfo.id = trajSdf->Get<int>("id");
tinfo.type = trajSdf->Get<std::string>("type");
std::vector<TrajectoryInfo>::iterator iter = this->trajInfo.begin();
while (iter != this->trajInfo.end())
{
if (iter->id > tinfo.id)
break;
++iter;
}
unsigned int idx = iter - this->trajInfo.begin();
this->trajInfo.insert(iter, tinfo);
std::map<double, ignition::math::Pose3d> points;
if (trajSdf->HasElement("waypoint"))
{
sdf::ElementPtr wayptSdf = trajSdf->GetElement("waypoint");
while (wayptSdf)
{
points[wayptSdf->Get<double>("time")] =
wayptSdf->Get<ignition::math::Pose3d>("pose");
wayptSdf = wayptSdf->GetNextElement("waypoint");
}
std::map<double, ignition::math::Pose3d>::reverse_iterator last =
points.rbegin();
std::stringstream animName;
animName << tinfo.type << "_" << tinfo.id;
common::PoseAnimation *anim = new common::PoseAnimation(animName.str(),
last->first, false);
this->trajInfo[idx].duration = last->first;
this->trajInfo[idx].translated = true;
for (std::map<double, ignition::math::Pose3d>::iterator pIter =
points.begin(); pIter != points.end(); ++pIter)
{
common::PoseKeyFrame *key;
if (pIter == points.begin() &&
!ignition::math::equal(pIter->first, 0.0))
{
key = anim->CreateKeyFrame(0.0);
key->Translation(pIter->second.Pos());
key->Rotation(pIter->second.Rot());
}
key = anim->CreateKeyFrame(pIter->first);
key->Translation(pIter->second.Pos());
key->Rotation(pIter->second.Rot());
}
this->trajectories[this->trajInfo[idx].id] = anim;
}
else
{
this->trajInfo[idx].duration =
this->skelAnimation[this->trajInfo[idx].type]->GetLength();
this->trajInfo[idx].translated = false;
}
trajSdf = trajSdf->GetNextElement("trajectory");
}
}
double scriptTime = 0.0;
if (!this->skelAnimation.empty())
{
if (this->trajInfo.empty())
{
TrajectoryInfo tinfo;
tinfo.id = 0;
tinfo.type = this->skinFile;
tinfo.startTime = 0.0;
tinfo.duration = this->skelAnimation.begin()->second->GetLength();
tinfo.endTime = tinfo.duration;
tinfo.translated = false;
this->trajInfo.push_back(tinfo);
this->interpolateX[this->skinFile] = false;
}
for (unsigned int i = 0; i < this->trajInfo.size(); i++)
{
this->trajInfo[i].startTime = scriptTime;
scriptTime += this->trajInfo[i].duration;
this->trajInfo[i].endTime = scriptTime;
}
}
this->scriptLength = scriptTime;
}
//////////////////////////////////////////////////
void Actor::LoadAnimation(sdf::ElementPtr _sdf)
{
std::string animName = _sdf->Get<std::string>("name");
if (animName == "__default__")
{
this->skelAnimation[this->skinFile] =
this->skeleton->GetAnimation(0);
std::map<std::string, std::string> skelMap;
for (unsigned int i = 0; i < this->skeleton->GetNumNodes(); ++i)
skelMap[this->skeleton->GetNodeByHandle(i)->GetName()] =
this->skeleton->GetNodeByHandle(i)->GetName();
this->skelNodesMap[this->skinFile] = skelMap;
this->interpolateX[this->skinFile] = false;
}
else
{
std::string animFile = _sdf->Get<std::string>("filename");
std::string extension = animFile.substr(animFile.rfind(".") + 1,
animFile.size());
double animScale = _sdf->Get<double>("scale");
Skeleton *skel = NULL;
if (extension == "bvh")
{
BVHLoader loader;
skel = loader.Load(animFile, animScale);
}
else
if (extension == "dae")
{
MeshManager::Instance()->Load(animFile);
const Mesh *animMesh = NULL;
if (MeshManager::Instance()->HasMesh(animFile))
animMesh = MeshManager::Instance()->GetMesh(animFile);
if (animMesh && animMesh->HasSkeleton())
{
skel = animMesh->GetSkeleton();
skel->Scale(animScale);
}
}
if (!skel || skel->GetNumAnimations() == 0)
gzerr << "Failed to load animation.";
else
{
bool compatible = true;
std::map<std::string, std::string> skelMap;
if (this->skeleton->GetNumNodes() != skel->GetNumNodes())
compatible = false;
else
for (unsigned int i = 0; i < this->skeleton->GetNumNodes(); ++i)
{
SkeletonNode *skinNode = this->skeleton->GetNodeByHandle(i);
SkeletonNode *animNode = skel->GetNodeByHandle(i);
if (animNode->GetChildCount() != skinNode->GetChildCount())
{
compatible = false;
break;
}
else
skelMap[skinNode->GetName()] = animNode->GetName();
}
if (!compatible)
{
gzerr << "Skin and animation " << animName <<
" skeletons are not compatible.\n";
}
else
{
this->skelAnimation[animName] =
skel->GetAnimation(0);
this->interpolateX[animName] = _sdf->Get<bool>("interpolate_x");
this->skelNodesMap[animName] = skelMap;
}
}
}
}
//////////////////////////////////////////////////
void Actor::Init()
{
this->prevFrameTime = this->world->GetSimTime();
if (this->autoStart)
this->Play();
this->mainLink = this->GetChildLink(this->GetName() + "_pose");
}
//////////////////////////////////////////////////
void Actor::Play()
{
this->active = true;
this->playStartTime = this->world->GetSimTime();
this->lastScriptTime = std::numeric_limits<double>::max();
}
//////////////////////////////////////////////////
void Actor::Stop()
{
this->active = false;
}
//////////////////////////////////////////////////
bool Actor::IsActive()
{
return this->active;
}
///////////////////////////////////////////////////
void Actor::Update()
{
if (!this->active)
return;
common::Time currentTime = this->world->GetSimTime();
/// do not refresh animation more faster the 30 Hz sim time
/// TODO: Reducing to 20 Hz. Because there were memory corruption
/// and segmentation faults. Possibly due to some dangling pointers
/// in pose message processing. This will need a proper fix. Just a
/// workaround for now.
if ((currentTime - this->prevFrameTime).Double() < (1.0 / 20.0))
return;
double scriptTime = currentTime.Double() - this->startDelay -
this->playStartTime.Double();
/// waiting for delayed start
if (scriptTime < 0)
return;
if (scriptTime >= this->scriptLength)
{
if (!this->loop)
return;
else
{
scriptTime = scriptTime - this->scriptLength;
this->playStartTime = currentTime - scriptTime;
}
}
/// at this point we are certain that a new frame will be animated
this->prevFrameTime = currentTime;
TrajectoryInfo tinfo;
for (unsigned int i = 0; i < this->trajInfo.size(); ++i)
if (this->trajInfo[i].startTime <= scriptTime &&
this->trajInfo[i].endTime >= scriptTime)
{
tinfo = this->trajInfo[i];
break;
}
scriptTime = scriptTime - tinfo.startTime;
SkeletonAnimation *skelAnim = this->skelAnimation[tinfo.type];
std::map<std::string, std::string> skelMap = this->skelNodesMap[tinfo.type];
ignition::math::Pose3d modelPose;
std::map<std::string, ignition::math::Matrix4d> frame;
if (this->trajectories.find(tinfo.id) != this->trajectories.end())
{
common::PoseKeyFrame posFrame(0.0);
this->trajectories[tinfo.id]->SetTime(scriptTime);
this->trajectories[tinfo.id]->GetInterpolatedKeyFrame(posFrame);
modelPose.Pos() = posFrame.Translation();
modelPose.Rot() = posFrame.Rotation();
if (this->lastTraj == tinfo.id)
this->pathLength += fabs(this->lastPos.Distance(modelPose.Pos()));
else
{
common::PoseKeyFrame *frame0 = dynamic_cast<common::PoseKeyFrame*>
(this->trajectories[tinfo.id]->GetKeyFrame(0));
ignition::math::Vector3d vector3Ign;
vector3Ign = frame0->Translation();
this->pathLength = fabs(modelPose.Pos().Distance(vector3Ign));
}
this->lastPos = modelPose.Pos();
}
if (this->interpolateX[tinfo.type] &&
this->trajectories.find(tinfo.id) != this->trajectories.end())
{
frame = skelAnim->PoseAtX(this->pathLength,
skelMap[this->skeleton->GetRootNode()->GetName()]);
}
else
frame = skelAnim->PoseAt(scriptTime);
this->lastTraj = tinfo.id;
ignition::math::Matrix4d rootTrans =
frame[skelMap[this->skeleton->GetRootNode()->GetName()]];
ignition::math::Vector3d rootPos = rootTrans.Translation();
ignition::math::Quaterniond rootRot = rootTrans.Rotation();
if (tinfo.translated)
rootPos.X() = 0.0;
ignition::math::Pose3d actorPose;
actorPose.Pos() = modelPose.Pos() + modelPose.Rot().RotateVector(rootPos);
actorPose.Rot() = modelPose.Rot() * rootRot;
ignition::math::Matrix4d rootM(actorPose.Rot());
rootM.Translate(actorPose.Pos());
frame[skelMap[this->skeleton->GetRootNode()->GetName()]] = rootM;
this->SetPose(frame, skelMap, currentTime.Double());
this->lastScriptTime = scriptTime;
}
//////////////////////////////////////////////////
void Actor::SetPose(std::map<std::string, ignition::math::Matrix4d> _frame,
std::map<std::string, std::string> _skelMap, double _time)
{
msgs::PoseAnimation msg;
msg.set_model_name(this->visualName);
msg.set_model_id(this->visualId);
ignition::math::Matrix4d modelTrans(ignition::math::Matrix4d::Identity);
ignition::math::Pose3d mainLinkPose;
for (unsigned int i = 0; i < this->skeleton->GetNumNodes(); ++i)
{
SkeletonNode *bone = this->skeleton->GetNodeByHandle(i);
SkeletonNode *parentBone = bone->GetParent();
ignition::math::Matrix4d transform(ignition::math::Matrix4d::Identity);
if (_frame.find(_skelMap[bone->GetName()]) != _frame.end())
transform = _frame[_skelMap[bone->GetName()]];
else
transform = bone->Transform();
LinkPtr currentLink = this->GetChildLink(bone->GetName());
ignition::math::Pose3d bonePose = transform.Pose();
if (!bonePose.IsFinite())
{
std::cerr << "ACTOR: " << _time << " " << bone->GetName()
<< " " << bonePose << "\n";
bonePose.Correct();
}
msgs::Pose *bone_pose = msg.add_pose();
bone_pose->set_name(bone->GetName());
if (!parentBone)
{
bone_pose->mutable_position()->CopyFrom(
msgs::Convert(ignition::math::Vector3d()));
bone_pose->mutable_orientation()->CopyFrom(msgs::Convert(
ignition::math::Quaterniond()));
mainLinkPose = bonePose;
}
else
{
bone_pose->mutable_position()->CopyFrom(msgs::Convert(bonePose.Pos()));
bone_pose->mutable_orientation()->CopyFrom(msgs::Convert(bonePose.Rot()));
LinkPtr parentLink = this->GetChildLink(parentBone->GetName());
math::Pose parentPose = parentLink->GetWorldPose();
math::Matrix4 parentTrans(parentPose.rot.GetAsMatrix4());
parentTrans.SetTranslate(parentPose.pos);
transform = (parentTrans * transform).Ign();
}
msgs::Pose *link_pose = msg.add_pose();
link_pose->set_name(currentLink->GetScopedName());
link_pose->set_id(currentLink->GetId());
ignition::math::Pose3d linkPose = transform.Pose() - mainLinkPose;
link_pose->mutable_position()->CopyFrom(msgs::Convert(linkPose.Pos()));
link_pose->mutable_orientation()->CopyFrom(msgs::Convert(linkPose.Rot()));
currentLink->SetWorldPose(transform.Pose(), true, false);
}
msgs::Time *stamp = msg.add_time();
stamp->CopyFrom(msgs::Convert(_time));
msgs::Pose *model_pose = msg.add_pose();
model_pose->set_name(this->GetScopedName());
model_pose->set_id(this->GetId());
model_pose->mutable_position()->CopyFrom(msgs::Convert(mainLinkPose.Pos()));
model_pose->mutable_orientation()->CopyFrom(
msgs::Convert(mainLinkPose.Rot()));
if (this->bonePosePub && this->bonePosePub->HasConnections())
this->bonePosePub->Publish(msg);
this->SetWorldPose(mainLinkPose, true, false);
}
//////////////////////////////////////////////////
void Actor::Fini()
{
Model::Fini();
}
//////////////////////////////////////////////////
void Actor::UpdateParameters(sdf::ElementPtr /*_sdf*/)
{
// Model::UpdateParameters(_sdf);
}
//////////////////////////////////////////////////
const sdf::ElementPtr Actor::GetSDF()
{
return Model::GetSDF();
}
//////////////////////////////////////////////////
void Actor::AddSphereInertia(const sdf::ElementPtr &_linkSdf,
const ignition::math::Pose3d &_pose,
const double _mass, const double _radius)
{
double ixx = 2.0 * _mass * _radius * _radius / 5.0;
sdf::ElementPtr inertialSdf = _linkSdf->GetElement("inertial");
sdf::ElementPtr inertialPoseSdf = inertialSdf->GetElement("pose");
inertialPoseSdf->Set(_pose);
inertialSdf->GetElement("mass")->Set(_mass);
sdf::ElementPtr tensorSdf = inertialSdf->GetElement("inertia");
tensorSdf->GetElement("ixx")->Set(ixx);
tensorSdf->GetElement("ixy")->Set(0.00);
tensorSdf->GetElement("ixz")->Set(0.00);
tensorSdf->GetElement("iyy")->Set(ixx);
tensorSdf->GetElement("iyz")->Set(0.00);
tensorSdf->GetElement("izz")->Set(ixx);
}
//////////////////////////////////////////////////
void Actor::AddSphereCollision(const sdf::ElementPtr &_linkSdf,
const std::string &_name,
const ignition::math::Pose3d &_pose,
const double _radius)
{
sdf::ElementPtr collisionSdf = _linkSdf->GetElement("collision");
collisionSdf->GetAttribute("name")->Set(_name);
sdf::ElementPtr collPoseSdf = collisionSdf->GetElement("pose");
collPoseSdf->Set(_pose);
sdf::ElementPtr geomColSdf = collisionSdf->GetElement("geometry");
sdf::ElementPtr sphereColSdf = geomColSdf->GetElement("sphere");
sphereColSdf->GetElement("radius")->Set(_radius);
}
//////////////////////////////////////////////////
void Actor::AddSphereVisual(const sdf::ElementPtr &_linkSdf,
const std::string &_name, const ignition::math::Pose3d &_pose,
const double _radius, const std::string &_material,
const common::Color &_ambient)
{
sdf::ElementPtr visualSdf = _linkSdf->GetElement("visual");
visualSdf->GetAttribute("name")->Set(_name);
sdf::ElementPtr visualPoseSdf = visualSdf->GetElement("pose");
visualPoseSdf->Set(_pose);
sdf::ElementPtr geomVisSdf = visualSdf->GetElement("geometry");
sdf::ElementPtr sphereVisSdf = geomVisSdf->GetElement("sphere");
sphereVisSdf->GetElement("radius")->Set(_radius);
sdf::ElementPtr matSdf = visualSdf->GetElement("material");
matSdf->GetElement("script")->Set(_material);
sdf::ElementPtr colorSdf = matSdf->GetElement("ambient");
colorSdf->Set(_ambient);
}
//////////////////////////////////////////////////
void Actor::AddBoxVisual(const sdf::ElementPtr &_linkSdf,
const std::string &_name, const ignition::math::Pose3d &_pose,
const ignition::math::Vector3d &_size, const std::string &_material,
const common::Color &_ambient)
{
sdf::ElementPtr visualSdf = _linkSdf->AddElement("visual");
visualSdf->GetAttribute("name")->Set(_name);
sdf::ElementPtr visualPoseSdf = visualSdf->GetElement("pose");
visualPoseSdf->Set(_pose);
sdf::ElementPtr geomVisSdf = visualSdf->GetElement("geometry");
sdf::ElementPtr boxSdf = geomVisSdf->GetElement("box");
boxSdf->GetElement("size")->Set(_size);
sdf::ElementPtr matSdf = visualSdf->GetElement("material");
matSdf->GetElement("script")->Set(_material);
sdf::ElementPtr colorSdf = matSdf->GetElement("ambient");
colorSdf->Set(_ambient);
}
//////////////////////////////////////////////////
void Actor::AddActorVisual(const sdf::ElementPtr &_linkSdf,
const std::string &_name, const ignition::math::Pose3d &_pose)
{
sdf::ElementPtr visualSdf = _linkSdf->AddElement("visual");
visualSdf->GetAttribute("name")->Set(_name);
sdf::ElementPtr visualPoseSdf = visualSdf->GetElement("pose");
visualPoseSdf->Set(_pose);
sdf::ElementPtr geomVisSdf = visualSdf->GetElement("geometry");
sdf::ElementPtr meshSdf = geomVisSdf->GetElement("mesh");
meshSdf->GetElement("uri")->Set(this->skinFile);
meshSdf->GetElement("scale")->Set(math::Vector3(this->skinScale,
this->skinScale, this->skinScale));
}
//////////////////////////////////////////////////
TrajectoryInfo::TrajectoryInfo()
: id(0), type(""), duration(0.0), startTime(0.0), endTime(0.0),
translated(false)
{
}