pxmlw6n2f/Gazebo_Distributed_TCP/gazebo/physics/ode/ODECollision.cc

259 lines
6.6 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.
*
*/
/* Desc: ODECollision class
* Author: Nate Koenig
* Date: 13 Feb 2006
*/
#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 <sstream>
#include "gazebo/common/Assert.hh"
#include "gazebo/common/Console.hh"
#include "gazebo/math/Box.hh"
#include "gazebo/physics/ode/ODESurfaceParams.hh"
#include "gazebo/physics/ode/ODEPhysics.hh"
#include "gazebo/physics/ode/ODELink.hh"
#include "gazebo/physics/ode/ODECollision.hh"
using namespace gazebo;
using namespace physics;
//////////////////////////////////////////////////
ODECollision::ODECollision(LinkPtr _link)
: Collision(_link)
{
this->SetName("ODE_Collision");
this->collisionId = NULL;
this->onPoseChangeFunc = &ODECollision::OnPoseChangeNull;
this->SetSpaceId(
boost::static_pointer_cast<ODELink>(this->link)->GetSpaceId());
this->surface.reset(new ODESurfaceParams());
}
//////////////////////////////////////////////////
ODECollision::~ODECollision()
{
if (this->collisionId)
dGeomDestroy(this->collisionId);
this->collisionId = NULL;
}
//////////////////////////////////////////////////
void ODECollision::Load(sdf::ElementPtr _sdf)
{
Collision::Load(_sdf);
if (this->IsStatic())
{
this->SetCategoryBits(GZ_FIXED_COLLIDE);
this->SetCollideBits(~GZ_FIXED_COLLIDE);
}
// Force max correcting velocity to zero for certain collision entities
if (this->IsStatic() || this->shape->HasType(Base::HEIGHTMAP_SHAPE) ||
this->shape->HasType(Base::MAP_SHAPE))
{
this->GetODESurface()->maxVel = 0.0;
}
}
//////////////////////////////////////////////////
void ODECollision::Fini()
{
/*
if (this->collisionId)
dGeomDestroy(this->collisionId);
this->collisionId = NULL;
if (this->spaceId)
dSpaceDestroy(this->spaceId);
this->spaceId = NULL;
*/
Collision::Fini();
}
//////////////////////////////////////////////////
void ODECollision::OnPoseChange()
{
// Update all the models
// (*this.*onPoseChangeFunc)();
if (this->IsStatic() && this->collisionId && this->placeable)
this->OnPoseChangeGlobal();
else if (this->collisionId && this->placeable)
this->OnPoseChangeRelative();
}
//////////////////////////////////////////////////
void ODECollision::SetCollision(dGeomID _collisionId, bool _placeable)
{
// Must go first in this function
this->collisionId = _collisionId;
Collision::SetCollision(_placeable);
if (dGeomGetSpace(this->collisionId) == 0)
{
dSpaceAdd(this->spaceId, this->collisionId);
GZ_ASSERT(dGeomGetSpace(this->collisionId) != 0, "Collision ID is NULL");
}
if (this->collisionId && this->placeable)
{
if (this->IsStatic())
this->onPoseChangeFunc = &ODECollision::OnPoseChangeGlobal;
else
this->onPoseChangeFunc = &ODECollision::OnPoseChangeRelative;
}
else
{
this->onPoseChangeFunc = &ODECollision::OnPoseChangeNull;
}
dGeomSetData(this->collisionId, this);
}
//////////////////////////////////////////////////
dGeomID ODECollision::GetCollisionId() const
{
return this->collisionId;
}
//////////////////////////////////////////////////
int ODECollision::GetCollisionClass() const
{
int result = 0;
if (this->collisionId)
{
result = dGeomGetClass(this->collisionId);
}
return result;
}
//////////////////////////////////////////////////
void ODECollision::SetCategoryBits(unsigned int _bits)
{
if (this->collisionId)
dGeomSetCategoryBits(this->collisionId, _bits);
if (this->spaceId)
dGeomSetCategoryBits((dGeomID)this->spaceId, _bits);
}
//////////////////////////////////////////////////
void ODECollision::SetCollideBits(unsigned int _bits)
{
if (this->collisionId)
dGeomSetCollideBits(this->collisionId, _bits);
if (this->spaceId)
dGeomSetCollideBits((dGeomID)this->spaceId, _bits);
}
//////////////////////////////////////////////////
math::Box ODECollision::GetBoundingBox() const
{
dReal aabb[6];
memset(aabb, 0, 6 * sizeof(dReal));
// if (this->collisionId && this->type != Shape::PLANE)
dGeomGetAABB(this->collisionId, aabb);
math::Box box(math::Vector3(aabb[0], aabb[2], aabb[4]),
math::Vector3(aabb[1], aabb[3], aabb[5]));
return box;
}
//////////////////////////////////////////////////
dSpaceID ODECollision::GetSpaceId() const
{
return this->spaceId;
}
//////////////////////////////////////////////////
void ODECollision::SetSpaceId(dSpaceID _spaceid)
{
this->spaceId = _spaceid;
}
/////////////////////////////////////////////////
ODESurfaceParamsPtr ODECollision::GetODESurface() const
{
return boost::dynamic_pointer_cast<ODESurfaceParams>(this->surface);
}
/////////////////////////////////////////////////
void ODECollision::OnPoseChangeGlobal()
{
dQuaternion q;
// Transform into global pose since a static collision does not have a link
math::Pose localPose = this->GetWorldPose();
// un-offset cog location
math::Vector3 cog_vec = this->link->GetInertial()->GetCoG();
localPose.pos = localPose.pos - cog_vec;
q[0] = localPose.rot.w;
q[1] = localPose.rot.x;
q[2] = localPose.rot.y;
q[3] = localPose.rot.z;
dGeomSetPosition(this->collisionId, localPose.pos.x, localPose.pos.y,
localPose.pos.z);
dGeomSetQuaternion(this->collisionId, q);
}
/////////////////////////////////////////////////
void ODECollision::OnPoseChangeRelative()
{
dQuaternion q;
// Transform into CoM relative Pose
math::Pose localPose = this->GetRelativePose();
// un-offset cog location
math::Vector3 cog_vec = this->link->GetInertial()->GetCoG();
localPose.pos = localPose.pos - cog_vec;
q[0] = localPose.rot.w;
q[1] = localPose.rot.x;
q[2] = localPose.rot.y;
q[3] = localPose.rot.z;
// Set the pose of the encapsulated collision; this is always relative
// to the CoM
dGeomSetOffsetPosition(this->collisionId, localPose.pos.x, localPose.pos.y,
localPose.pos.z);
dGeomSetOffsetQuaternion(this->collisionId, q);
}
/////////////////////////////////////////////////
void ODECollision::OnPoseChangeNull()
{
}