pxmlw6n2f/Gazebo_Distributed_TCP/gazebo/physics/ModelState.cc

698 lines
19 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.
*
*/
#include "gazebo/common/Exception.hh"
#include "gazebo/physics/Model.hh"
#include "gazebo/physics/Link.hh"
#include "gazebo/physics/World.hh"
#include "gazebo/physics/ModelState.hh"
using namespace gazebo;
using namespace physics;
/////////////////////////////////////////////////
ModelState::ModelState()
: State()
{
}
/////////////////////////////////////////////////
ModelState::ModelState(const ModelPtr _model, const common::Time &_realTime,
const common::Time &_simTime, const uint64_t _iterations)
: State(_model->GetName(), _realTime, _simTime, _iterations)
{
this->pose = _model->GetWorldPose();
this->scale = _model->Scale();
// Copy all the links
const Link_V links = _model->GetLinks();
for (Link_V::const_iterator iter = links.begin(); iter != links.end(); ++iter)
{
this->linkStates.insert(std::make_pair((*iter)->GetName(),
LinkState(*iter, _realTime, _simTime, _iterations)));
}
// Copy all the models
for (const auto &m : _model->NestedModels())
{
this->modelStates.insert(std::make_pair(m->GetName(),
ModelState(m, _realTime, _simTime, _iterations)));
}
// Copy all the joints
/*const Joint_V joints = _model->GetJoints();
for (Joint_V::const_iterator iter = joints.begin();
iter != joints.end(); ++iter)
{
this->jointStates.insert(std::make_pair((*iter)->GetName(),
JointState(*iter, _realTime, _simTime, _iterations)));
}*/
}
/////////////////////////////////////////////////
ModelState::ModelState(const ModelPtr _model)
: State(_model->GetName(), _model->GetWorld()->GetRealTime(),
_model->GetWorld()->GetSimTime(), _model->GetWorld()->GetIterations())
{
this->pose = _model->GetWorldPose();
this->scale = _model->Scale();
// Copy all the links
const Link_V links = _model->GetLinks();
for (Link_V::const_iterator iter = links.begin(); iter != links.end(); ++iter)
{
this->linkStates.insert(std::make_pair((*iter)->GetName(),
LinkState((*iter))));
}
// Copy all the models
for (const auto &m : _model->NestedModels())
{
this->modelStates.insert(std::make_pair(m->GetName(),
ModelState(m)));
}
// Copy all the joints
/*const Joint_V joints = _model->GetJoints();
for (Joint_V::const_iterator iter = joints.begin();
iter != joints.end(); ++iter)
{
this->jointStates.insert(std::make_pair((*iter)->GetName(),
JointState(*iter)));
}*/
}
/////////////////////////////////////////////////
ModelState::ModelState(const sdf::ElementPtr _sdf)
: State()
{
this->Load(_sdf);
}
/////////////////////////////////////////////////
ModelState::~ModelState()
{
}
/////////////////////////////////////////////////
void ModelState::Load(const ModelPtr _model, const common::Time &_realTime,
const common::Time &_simTime, const uint64_t _iterations)
{
this->name = _model->GetName();
this->wallTime = common::Time::GetWallTime();
this->realTime = _realTime;
this->simTime = _simTime;
this->iterations = _iterations;
this->pose = _model->GetWorldPose();
this->scale = _model->Scale();
// Load all the links
this->linkStates.clear();
const Link_V links = _model->GetLinks();
for (Link_V::const_iterator iter = links.begin(); iter != links.end(); ++iter)
{
this->linkStates[(*iter)->GetName()].Load(*iter, _realTime, _simTime,
_iterations);
}
// Load all the models
this->modelStates.clear();
for (const auto &m : _model->NestedModels())
{
this->modelStates[m->GetName()].Load(m, _realTime, _simTime, _iterations);
}
// Copy all the joints
/*const Joint_V joints = _model->GetJoints();
for (Joint_V::const_iterator iter = joints.begin();
iter != joints.end(); ++iter)
{
this->jointStates[(*iter)->GetName()].Load(*iter, _realTime, _simTime,
_iterations);
}
// Remove joints that no longer exist. We determine this by check the time
// stamp on each joint.
for (JointState_M::iterator iter = this->jointStates.begin();
iter != this->jointStates.end();)
{
if (iter->second.GetRealTime() != this->realTime)
this->jointStates.erase(iter++);
else
++iter;
}*/
}
/////////////////////////////////////////////////
void ModelState::Load(const sdf::ElementPtr _elem)
{
// Set the name
this->name = _elem->Get<std::string>("name");
// Set the model pose
if (_elem->HasElement("pose"))
this->pose = _elem->Get<math::Pose>("pose");
else
this->pose.Set(0, 0, 0, 0, 0, 0);
// Set the model scale
if (_elem->HasElement("scale"))
this->scale = _elem->Get<ignition::math::Vector3d>("scale");
else
this->scale.Set(1, 1, 1);
// Set all the links
this->linkStates.clear();
if (_elem->HasElement("link"))
{
sdf::ElementPtr childElem = _elem->GetElement("link");
while (childElem)
{
this->linkStates.insert(std::make_pair(
childElem->Get<std::string>("name"), LinkState(childElem)));
childElem = childElem->GetNextElement("link");
}
}
// Set all the models
this->modelStates.clear();
if (_elem->HasElement("model"))
{
sdf::ElementPtr childElem = _elem->GetElement("model");
while (childElem)
{
this->modelStates.insert(std::make_pair(
childElem->Get<std::string>("name"), ModelState(childElem)));
childElem = childElem->GetNextElement("model");
}
}
// Set all the joints
/*this->jointStates.clear();
if (_elem->HasElement("joint"))
{
sdf::ElementPtr childElem = _elem->GetElement("joint");
while (childElem)
{
this->jointStates.insert(std::make_pair(childElem->Get<std::string>("name"),
JointState(childElem)));
childElem = childElem->GetNextElement("joint");
}
}*/
}
/////////////////////////////////////////////////
const math::Pose &ModelState::GetPose() const
{
return this->pose;
}
/////////////////////////////////////////////////
const ignition::math::Vector3d &ModelState::Scale() const
{
return this->scale;
}
/////////////////////////////////////////////////
bool ModelState::IsZero() const
{
bool result = true;
for (LinkState_M::const_iterator iter = this->linkStates.begin();
iter != this->linkStates.end() && result; ++iter)
{
result = result && iter->second.IsZero();
}
for (const auto &ms : this->modelStates)
{
result = result && ms.second.IsZero();
}
/*for (JointState_M::const_iterator iter = this->jointStates.begin();
iter != this->jointStates.end() && result; ++iter)
{
result = result && iter->second.IsZero();
}*/
return result && this->pose == math::Pose::Zero &&
this->scale == ignition::math::Vector3d::Zero;
}
/////////////////////////////////////////////////
unsigned int ModelState::GetLinkStateCount() const
{
return this->linkStates.size();
}
/////////////////////////////////////////////////
LinkState_M ModelState::GetLinkStates(const boost::regex &_regex) const
{
LinkState_M result;
// Search for matching link names
for (LinkState_M::const_iterator iter = this->linkStates.begin();
iter != this->linkStates.end(); ++iter)
{
if (boost::regex_match(iter->first, _regex))
result.insert(std::make_pair(iter->first, iter->second));
}
return result;
}
/////////////////////////////////////////////////
JointState_M ModelState::GetJointStates(const boost::regex &_regex) const
{
JointState_M result;
// Search for matching link names
for (JointState_M::const_iterator iter = this->jointStates.begin();
iter != this->jointStates.end(); ++iter)
{
if (boost::regex_match(iter->second.GetName(), _regex))
result.insert(std::make_pair(iter->first, iter->second));
}
return result;
}
/////////////////////////////////////////////////
LinkState ModelState::GetLinkState(const std::string &_linkName) const
{
// Search for the link name
LinkState_M::const_iterator iter = this->linkStates.find(_linkName);
if (iter != this->linkStates.end())
return iter->second;
gzerr << "Invalid link name[" + _linkName + "]" << std::endl;
return LinkState();
}
/////////////////////////////////////////////////
bool ModelState::HasLinkState(const std::string &_linkName) const
{
return this->linkStates.find(_linkName) != this->linkStates.end();
}
/////////////////////////////////////////////////
const LinkState_M &ModelState::GetLinkStates() const
{
return this->linkStates;
}
/////////////////////////////////////////////////
unsigned int ModelState::GetJointStateCount() const
{
return this->jointStates.size();
}
/////////////////////////////////////////////////
JointState ModelState::GetJointState(unsigned int _index) const
{
if (_index < this->jointStates.size())
{
JointState_M::const_iterator iter = this->jointStates.begin();
std::advance(iter, _index);
return iter->second;
}
gzerr << "Index is out of range" << std::endl;
return JointState();
}
/////////////////////////////////////////////////
JointState ModelState::GetJointState(const std::string &_jointName) const
{
JointState_M::const_iterator iter = this->jointStates.find(_jointName);
if (iter != this->jointStates.end())
return iter->second;
gzerr << "Invalid joint name[" + _jointName + "]" << std::endl;
return JointState();
}
/////////////////////////////////////////////////
bool ModelState::HasJointState(const std::string &_jointName) const
{
JointState_M::const_iterator iter = this->jointStates.find(_jointName);
if (iter != this->jointStates.end())
return true;
return false;
}
/////////////////////////////////////////////////
const JointState_M &ModelState::GetJointStates() const
{
return this->jointStates;
}
/////////////////////////////////////////////////
unsigned int ModelState::NestedModelStateCount() const
{
return this->modelStates.size();
}
/////////////////////////////////////////////////
ModelState ModelState::NestedModelState(const std::string &_modelName) const
{
// Search for the model name
auto iter = this->modelStates.find(_modelName);
if (iter != this->modelStates.end())
return iter->second;
gzerr << "Invalid model name[" + _modelName + "]" << std::endl;
return ModelState();
}
/////////////////////////////////////////////////
bool ModelState::HasNestedModelState(const std::string &_modelName) const
{
return this->modelStates.find(_modelName) != this->modelStates.end();
}
/////////////////////////////////////////////////
const ModelState_M &ModelState::NestedModelStates() const
{
return this->modelStates;
}
/////////////////////////////////////////////////
ModelState &ModelState::operator=(const ModelState &_state)
{
State::operator=(_state);
// Copy the pose
this->pose = _state.pose;
this->scale = _state.scale;
// Clear the link, joint, and model states.
this->linkStates.clear();
this->jointStates.clear();
this->modelStates.clear();
// Copy the link states.
for (LinkState_M::const_iterator iter =
_state.linkStates.begin(); iter != _state.linkStates.end(); ++iter)
{
this->linkStates.insert(std::make_pair(iter->first, iter->second));
}
// Copy the model states.
for (const auto &ms : _state.modelStates)
{
this->modelStates.insert(std::make_pair(ms.first, ms.second));
}
// Copy the joint states.
// for (JointState_M::const_iterator iter =
// _state.jointStates.begin(); iter != _state.jointStates.end(); ++iter)
// {
// this->jointStates.insert(std::make_pair(iter->first, iter->second));
// }
return *this;
}
/////////////////////////////////////////////////
ModelState ModelState::operator-(const ModelState &_state) const
{
ModelState result;
result.name = this->name;
result.pose.pos = this->pose.pos - _state.pose.pos;
result.pose.rot = _state.pose.rot.GetInverse() * this->pose.rot;
result.scale = this->scale - _state.scale;
// Insert the link state diffs.
for (LinkState_M::const_iterator iter =
this->linkStates.begin(); iter != this->linkStates.end(); ++iter)
{
try
{
if (_state.HasLinkState(iter->second.GetName()))
{
LinkState state = iter->second - _state.GetLinkState(
iter->second.GetName());
if (!state.IsZero())
result.linkStates.insert(std::make_pair(state.GetName(), state));
}
}
catch(common::Exception &)
{
// Ignore exception, which is just the fact that a link state may not
// have been recorded.
}
}
// Insert the model state diffs.
for (const auto &ms : this->modelStates)
{
try
{
if (_state.HasNestedModelState(ms.second.GetName()))
{
ModelState state = ms.second - _state.NestedModelState(
ms.second.GetName());
if (!state.IsZero())
result.modelStates.insert(std::make_pair(state.GetName(), state));
}
}
catch(common::Exception &)
{
// Ignore exception, which is just the fact that a model state may not
// have been recorded.
}
}
// Insert the joint state diffs.
/*for (JointState_M::const_iterator iter =
this->jointStates.begin(); iter != this->jointStates.end(); ++iter)
{
try
{
if (_state.HasJointState(iter->second.GetName()))
{
JointState state = iter->second -
_state.GetJointState(iter->second.GetName());
if (!state.IsZero())
result.jointStates.insert(std::make_pair(state.GetName(), state));
}
}
catch(common::Exception &)
{
// Ignore exception, which is just the fact that a joint state may not
// have been recorded.
}
}*/
return result;
}
/////////////////////////////////////////////////
ModelState ModelState::operator+(const ModelState &_state) const
{
ModelState result;
result.name = this->name;
result.pose.pos = this->pose.pos + _state.pose.pos;
result.pose.rot = _state.pose.rot * this->pose.rot;
result.scale = this->scale + _state.scale;
// Insert the link state diffs.
for (LinkState_M::const_iterator iter =
this->linkStates.begin(); iter != this->linkStates.end(); ++iter)
{
try
{
if (_state.HasLinkState(iter->second.GetName()))
{
LinkState state = iter->second + _state.GetLinkState(
iter->second.GetName());
result.linkStates.insert(std::make_pair(state.GetName(), state));
}
}
catch(common::Exception &)
{
// Ignore exception, which is just the fact that a link state may not
// have been recorded.
}
}
// Insert the model state diffs.
for (const auto &ms : this->modelStates)
{
try
{
if (_state.HasNestedModelState(ms.second.GetName()))
{
ModelState state = ms.second + _state.NestedModelState(
ms.second.GetName());
result.modelStates.insert(std::make_pair(state.GetName(), state));
}
}
catch(common::Exception &)
{
// Ignore exception, which is just the fact that a model state may not
// have been recorded.
}
}
// Insert the joint state diffs.
for (JointState_M::const_iterator iter =
this->jointStates.begin(); iter != this->jointStates.end(); ++iter)
{
try
{
if (_state.HasJointState(iter->second.GetName()))
{
JointState state = iter->second +
_state.GetJointState(iter->second.GetName());
result.jointStates.insert(std::make_pair(state.GetName(), state));
}
}
catch(common::Exception &)
{
// Ignore exception, which is just the fact that a joint state may not
// have been recorded.
}
}
return result;
}
/////////////////////////////////////////////////
void ModelState::FillSDF(sdf::ElementPtr _sdf)
{
_sdf->ClearElements();
_sdf->GetAttribute("name")->Set(this->name);
_sdf->GetElement("pose")->Set(this->pose);
_sdf->GetElement("scale")->Set(this->scale);
for (LinkState_M::iterator iter = this->linkStates.begin();
iter != this->linkStates.end(); ++iter)
{
sdf::ElementPtr elem = _sdf->AddElement("link");
iter->second.FillSDF(elem);
}
for (auto &ms : this->modelStates)
{
sdf::ElementPtr elem = _sdf->AddElement("model");
ms.second.FillSDF(elem);
}
for (JointState_M::iterator iter = this->jointStates.begin();
iter != this->jointStates.end(); ++iter)
{
sdf::ElementPtr elem = _sdf->AddElement("joint");
iter->second.FillSDF(elem);
}
}
/////////////////////////////////////////////////
void ModelState::SetWallTime(const common::Time &_time)
{
State::SetWallTime(_time);
for (LinkState_M::iterator iter = this->linkStates.begin();
iter != this->linkStates.end(); ++iter)
{
iter->second.SetWallTime(_time);
}
for (auto &ms : this->modelStates)
{
ms.second.SetWallTime(_time);
}
for (JointState_M::iterator iter = this->jointStates.begin();
iter != this->jointStates.end(); ++iter)
{
iter->second.SetWallTime(_time);
}
}
/////////////////////////////////////////////////
void ModelState::SetRealTime(const common::Time &_time)
{
State::SetRealTime(_time);
for (LinkState_M::iterator iter = this->linkStates.begin();
iter != this->linkStates.end(); ++iter)
{
iter->second.SetRealTime(_time);
}
for (auto &ms : this->modelStates)
{
ms.second.SetRealTime(_time);
}
for (JointState_M::iterator iter = this->jointStates.begin();
iter != this->jointStates.end(); ++iter)
{
iter->second.SetRealTime(_time);
}
}
/////////////////////////////////////////////////
void ModelState::SetSimTime(const common::Time &_time)
{
State::SetSimTime(_time);
for (LinkState_M::iterator iter = this->linkStates.begin();
iter != this->linkStates.end(); ++iter)
{
iter->second.SetSimTime(_time);
}
for (auto &ms : this->modelStates)
{
ms.second.SetSimTime(_time);
}
for (JointState_M::iterator iter = this->jointStates.begin();
iter != this->jointStates.end(); ++iter)
{
iter->second.SetSimTime(_time);
}
}
/////////////////////////////////////////////////
void ModelState::SetIterations(const uint64_t _iterations)
{
State::SetIterations(_iterations);
for (auto &linkState : this->linkStates)
linkState.second.SetIterations(_iterations);
for (auto &ms : this->modelStates)
{
ms.second.SetIterations(_iterations);
}
for (auto &jointState : this->jointStates)
jointState.second.SetIterations(_iterations);
}