228 lines
6.8 KiB
C++
228 lines
6.8 KiB
C++
/*
|
|
* Copyright (C) 2014 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/Assert.hh"
|
|
|
|
#include "gazebo/physics/World.hh"
|
|
|
|
#include "gazebo/physics/dart/DARTPhysics.hh"
|
|
#include "gazebo/physics/dart/DARTLink.hh"
|
|
#include "gazebo/physics/dart/DARTModel.hh"
|
|
|
|
#include "gazebo/physics/dart/DARTModelPrivate.hh"
|
|
|
|
using namespace gazebo;
|
|
using namespace physics;
|
|
|
|
//////////////////////////////////////////////////
|
|
DARTModel::DARTModel(BasePtr _parent)
|
|
: Model(_parent), dataPtr(new DARTModelPrivate())
|
|
{
|
|
}
|
|
|
|
//////////////////////////////////////////////////
|
|
DARTModel::~DARTModel()
|
|
{
|
|
delete this->dataPtr;
|
|
this->dataPtr = nullptr;
|
|
}
|
|
|
|
//////////////////////////////////////////////////
|
|
void DARTModel::Load(sdf::ElementPtr _sdf)
|
|
{
|
|
if (_sdf->HasElement("model"))
|
|
{
|
|
gzerr << "Nested models are not currently supported in DART. ["
|
|
<< _sdf->Get<std::string>("name") << "] will not be loaded. "
|
|
<< std::endl;
|
|
this->sdf = _sdf;
|
|
return;
|
|
}
|
|
|
|
// create skeleton of DART
|
|
this->dataPtr->dtSkeleton = new dart::dynamics::Skeleton();
|
|
|
|
Model::Load(_sdf);
|
|
}
|
|
|
|
//////////////////////////////////////////////////
|
|
void DARTModel::Init()
|
|
{
|
|
// nested models are not supported for now, issue #1833
|
|
if (this->sdf->HasElement("model"))
|
|
return;
|
|
|
|
Model::Init();
|
|
|
|
//----------------------------------------------
|
|
// Name
|
|
std::string modelName = this->GetName();
|
|
this->dataPtr->dtSkeleton->setName(modelName.c_str());
|
|
|
|
//----------------------------------------------
|
|
// Static
|
|
this->dataPtr->dtSkeleton->setMobile(!this->IsStatic());
|
|
|
|
//----------------------------------------------
|
|
// Check if this link is free floating body
|
|
// If a link of this model has no parent joint, then we add 6-dof free joint
|
|
// to the link.
|
|
Link_V linkList = this->GetLinks();
|
|
for (unsigned int i = 0; i < linkList.size(); ++i)
|
|
{
|
|
dart::dynamics::BodyNode *dtBodyNode
|
|
= boost::static_pointer_cast<DARTLink>(linkList[i])->GetDARTBodyNode();
|
|
|
|
if (dtBodyNode->getParentJoint() == NULL)
|
|
{
|
|
dart::dynamics::FreeJoint *newFreeJoint = new dart::dynamics::FreeJoint;
|
|
|
|
newFreeJoint->setTransformFromParentBodyNode(
|
|
DARTTypes::ConvPose(linkList[i]->GetWorldPose()));
|
|
newFreeJoint->setTransformFromChildBodyNode(
|
|
Eigen::Isometry3d::Identity());
|
|
|
|
dtBodyNode->setParentJoint(newFreeJoint);
|
|
}
|
|
|
|
this->dataPtr->dtSkeleton->addBodyNode(dtBodyNode);
|
|
}
|
|
|
|
// Add the skeleton to the world
|
|
this->GetDARTWorld()->addSkeleton(this->dataPtr->dtSkeleton);
|
|
|
|
// Self collision
|
|
// Note: This process should be done after this skeleton is added to the
|
|
// world.
|
|
|
|
// Check whether there exist at least one pair of self collidable links.
|
|
int numSelfCollidableLinks = 0;
|
|
bool hasPairOfSelfCollidableLinks = false;
|
|
for (size_t i = 0; i < linkList.size(); ++i)
|
|
{
|
|
if (linkList[i]->GetSelfCollide())
|
|
{
|
|
++numSelfCollidableLinks;
|
|
if (numSelfCollidableLinks >= 2)
|
|
{
|
|
hasPairOfSelfCollidableLinks = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// If the skeleton has at least two self collidable links, then we set the
|
|
// skeleton as self collidable. If the skeleton is self collidable, then
|
|
// DART regards that all the links in the skeleton is self collidable. So, we
|
|
// disable all the pairs of which both of the links in the pair is not self
|
|
// collidable.
|
|
if (hasPairOfSelfCollidableLinks)
|
|
{
|
|
this->dataPtr->dtSkeleton->enableSelfCollision();
|
|
|
|
dart::simulation::World *dtWorld = this->GetDARTPhysics()->GetDARTWorld();
|
|
dart::collision::CollisionDetector *dtCollDet =
|
|
dtWorld->getConstraintSolver()->getCollisionDetector();
|
|
|
|
for (size_t i = 0; i < linkList.size() - 1; ++i)
|
|
{
|
|
for (size_t j = i + 1; j < linkList.size(); ++j)
|
|
{
|
|
dart::dynamics::BodyNode *itdtBodyNode1 =
|
|
boost::dynamic_pointer_cast<DARTLink>(linkList[i])->GetDARTBodyNode();
|
|
dart::dynamics::BodyNode *itdtBodyNode2 =
|
|
boost::dynamic_pointer_cast<DARTLink>(linkList[j])->GetDARTBodyNode();
|
|
|
|
// If this->dtBodyNode and itdtBodyNode are connected then don't enable
|
|
// the pair.
|
|
// Please see: https://bitbucket.org/osrf/gazebo/issue/899
|
|
if ((itdtBodyNode1->getParentBodyNode() == itdtBodyNode2) ||
|
|
itdtBodyNode2->getParentBodyNode() == itdtBodyNode1)
|
|
{
|
|
dtCollDet->disablePair(itdtBodyNode1, itdtBodyNode2);
|
|
}
|
|
|
|
if (!linkList[i]->GetSelfCollide() || !linkList[j]->GetSelfCollide())
|
|
{
|
|
dtCollDet->disablePair(itdtBodyNode1, itdtBodyNode2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Note: This function should be called after the skeleton is added to the
|
|
// world.
|
|
this->BackupState();
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
void DARTModel::Update()
|
|
{
|
|
Model::Update();
|
|
}
|
|
|
|
//////////////////////////////////////////////////
|
|
void DARTModel::Fini()
|
|
{
|
|
Model::Fini();
|
|
}
|
|
|
|
//////////////////////////////////////////////////
|
|
void DARTModel::BackupState()
|
|
{
|
|
this->dataPtr->dtConfig = this->dataPtr->dtSkeleton->getPositions();
|
|
this->dataPtr->dtVelocity = this->dataPtr->dtSkeleton->getVelocities();
|
|
}
|
|
|
|
//////////////////////////////////////////////////
|
|
void DARTModel::RestoreState()
|
|
{
|
|
if (!this->dataPtr->dtSkeleton)
|
|
return;
|
|
|
|
GZ_ASSERT(static_cast<size_t>(this->dataPtr->dtConfig.size()) ==
|
|
this->dataPtr->dtSkeleton->getNumDofs(),
|
|
"Cannot RestoreState, invalid size");
|
|
GZ_ASSERT(static_cast<size_t>(this->dataPtr->dtVelocity.size()) ==
|
|
this->dataPtr->dtSkeleton->getNumDofs(),
|
|
"Cannot RestoreState, invalid size");
|
|
|
|
this->dataPtr->dtSkeleton->setPositions(this->dataPtr->dtConfig);
|
|
this->dataPtr->dtSkeleton->setVelocities(this->dataPtr->dtVelocity);
|
|
this->dataPtr->dtSkeleton->computeForwardKinematics(true, true, false);
|
|
}
|
|
|
|
//////////////////////////////////////////////////
|
|
dart::dynamics::Skeleton *DARTModel::GetDARTSkeleton()
|
|
{
|
|
return this->dataPtr->dtSkeleton;
|
|
}
|
|
|
|
//////////////////////////////////////////////////
|
|
DARTPhysicsPtr DARTModel::GetDARTPhysics(void) const
|
|
{
|
|
return boost::dynamic_pointer_cast<DARTPhysics>(
|
|
this->GetWorld()->GetPhysicsEngine());
|
|
}
|
|
|
|
//////////////////////////////////////////////////
|
|
dart::simulation::World *DARTModel::GetDARTWorld(void) const
|
|
{
|
|
return GetDARTPhysics()->GetDARTWorld();
|
|
}
|