basegeom.cc
来自「机器人人3D仿真工具,可以加入到Simbad仿真环境下应用。」· CC 代码 · 共 416 行
CC
416 行
/* * Gazebo - Outdoor Multi-Robot Simulator * Copyright (C) 2003 * Nate Koenig & Andrew Howard * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * *//* Desc: Base class for all geometries * Author: Nate Keonig, Andrew Howard * Date: 8 May 2003 * CVS: $Id: BaseGeom.cc,v 1.15 2004/12/13 22:58:26 inspectorg Exp $ */#include <assert.h>#include "Body.hh"#include "BaseGeom.hh"#include "ContactParams.hh"// Forward declaration for ugly BaseGeom/Geom interdependencyclass Geom;//////////////////////////////////////////////////////////////////////////////// ConstructorBaseGeom::BaseGeom( dSpaceID spaceId ){ this->body = NULL; this->spaceId = spaceId; this->transId = NULL; this->geomId = NULL; // Most geoms are placable this->placeableGeom = true; this->dummyPose = GzPoseSet(GzVectorZero(), GzQuaternIdent()); // Most geoms dont need extra rotations this->extraRotation = GzQuaternIdent(); // Out default mass is zero dMassSetZero( &this->geomMass ); dMassSetZero( &this->bodyMass ); // Create the contact parameters this->contact = new ContactParams(); return;}//////////////////////////////////////////////////////////////////////////////// DestructorBaseGeom::~BaseGeom(){ if (this->geomId) dGeomDestroy(this->geomId); if (this->transId) dGeomDestroy(this->transId); return;}//////////////////////////////////////////////////////////////////////////////// Set the encapsulated geometry objectvoid BaseGeom::SetGeom( Body *body, dGeomID geomId, dMass *mass, bool placeable ){ assert(!this->geomId); this->geomId = geomId; this->transId = NULL; this->placeableGeom = placeable; if (this->placeableGeom) { this->transId = dCreateGeomTransform( this->spaceId ); dGeomTransformSetGeom( this->transId, this->geomId ); dGeomTransformSetInfo( this->transId, 1 ); } if (mass) this->geomMass = *mass; if (this->placeableGeom) { // Placeable; the encapsulated geom must not belong to any space assert(dGeomGetSpace(this->geomId) == 0); dGeomSetData(this->geomId, this); } else if (this->geomId) { // Non-placeable; the encapsulated geom must belong to some space assert(dGeomGetSpace(this->geomId) != 0); dGeomSetData(this->geomId, this); } this->body = body; this->body->AttachGeom( (Geom*) this ); return;}//////////////////////////////////////////////////////////////////////////////// Set the extra rotation of the encapsulated object (called in constructor)void BaseGeom::SetExtraRotation( GzQuatern rot ){ this->extraRotation = rot; return;}//////////////////////////////////////////////////////////////////////////////// Get the transform geometrydGeomID BaseGeom::GetTransId() const{ return this->transId;}//////////////////////////////////////////////////////////////////////////////// Get the geometrydGeomID BaseGeom::GetGeomId() const{ return this->geomId;}//////////////////////////////////////////////////////////////////////////////// Set the geometry category bitfieldvoid BaseGeom::SetCategoryBits( uint bits ){ if (this->transId) dGeomSetCategoryBits( this->transId, bits ); dGeomSetCategoryBits( this->geomId, bits ); return;}//////////////////////////////////////////////////////////////////////////////// Set the geometry collision bitfieldvoid BaseGeom::SetCollideBits( uint bits ){ if (this->transId) dGeomSetCollideBits( this->transId, bits ); dGeomSetCollideBits( this->geomId, bits ); return;}///////////////////////////////////////////////////////////////////////////////// @brief Set spring-damper parameters for contact jointsvoid BaseGeom::SetHardness( double kp, double kd ){ this->contact->kp = kp; this->contact->kd = kd; return;}//////////////////////////////////////////////////////////////////////////////// Set friction coefficientsvoid BaseGeom::SetFriction( double mu1, double mu2 ){ this->contact->mu1 = mu1; this->contact->mu2 = mu2; return;}//////////////////////////////////////////////////////////////////////////////// Set bouncinessvoid BaseGeom::SetBounce( double bounce ){ this->contact->bounce = bounce;}//////////////////////////////////////////////////////////////////////////////// Set direction 1 slipvoid BaseGeom::SetSlip1( double slip ){ this->contact->slip1 = slip;}//////////////////////////////////////////////////////////////////////////////// Set direction 2 slipvoid BaseGeom::SetSlip2( double slip ){ this->contact->slip2 = slip;}//////////////////////////////////////////////////////////////////////////////// Get bounce parameterdouble BaseGeom::GetBounce() const{ return this->contact->bounce;}//////////////////////////////////////////////////////////////////////////////// Get direction 1 slipdouble BaseGeom::GetSlip1() const{ return this->contact->slip1;}//////////////////////////////////////////////////////////////////////////////// Get direction 2 slipdouble BaseGeom::GetSlip2() const{ return this->contact->slip2;}//////////////////////////////////////////////////////////////////////////////// Set the pose of the geom, relative to the bodyvoid BaseGeom::SetRelativePose(GzPose pose, bool updateCoM){ dQuaternion q; // Must be attached before we can set the pose assert(this->body); if (!this->placeableGeom) { this->dummyPose = pose; return; } // Transform into CoM relative pose pose = GzCoordPoseSub(pose, this->body->comPose); // Hack: we want cylinders aligned along the z-axis pose.rot = GzQuaternMul(pose.rot, this->extraRotation); q[0] = pose.rot.u; q[1] = pose.rot.x; q[2] = pose.rot.y; q[3] = pose.rot.z; // Set the pose of the encapsulated geom; this is always relative // to the CoM dGeomSetPosition( this->geomId, pose.pos.x, pose.pos.y, pose.pos.z ); dGeomSetQuaternion( this->geomId, q); // Update the bodies CoM if (updateCoM) this->body->UpdateCoM(); return;}//////////////////////////////////////////////////////////////////////////////// Get the pose relative to the bodyGzPose BaseGeom::GetRelativePose() const{ const dReal *p; dQuaternion q; GzPose pose; // Must be attached before we can get the pose assert(this->body); if (!this->placeableGeom) return this->dummyPose; // Get the pose of the encapsulated geom; this is always relative to // the CoM p = dGeomGetPosition(this->geomId); dGeomGetQuaternion(this->geomId, q); pose = GzPoseSet(GzVectorSet(p[0], p[1], p[2]), GzQuaternSet(q[0], q[1], q[2], q[3])); // Hack: we want cylinders aligned along the z-axis pose.rot = GzQuaternMul(pose.rot, GzQuaternInverse(this->extraRotation)); // Transform into body relative pose pose = GzCoordPoseAdd(pose, this->body->comPose); return pose;}//////////////////////////////////////////////////////////////////////////////// Get the pose (global cs)GzPose BaseGeom::GetPose() const{ const dReal *p; dQuaternion q; GzPose a, b, pose; // For non-placeable geoms, just offset from parent body if (!this->placeableGeom) { a = this->GetRelativePose(); assert(this->body); return GzCoordPoseAdd(a, this->body->GetPose()); } // Get the relative pose and subtract out the body com offset. Note // that we use GetRelativePose(), rather than calling ODE directly, // since the former may be overloaded in subclasses (e.g. RayGeom). a = this->GetRelativePose(); // Offset with CoM a = GzCoordPoseSub(a, this->body->comPose); // Get the pose of the transform geom (global cs) assert(this->transId); p = dGeomGetPosition(this->transId); dGeomGetQuaternion(this->transId, q); b.pos = GzVectorSet(p[0], p[1], p[2]); b.rot = GzQuaternSet(q[0], q[1], q[2], q[3]); // Compute global pose pose = GzCoordPoseAdd(a, b); return pose;}//////////////////////////////////////////////////////////////////////////////// Set the position (body-centered cs)void BaseGeom::SetRelativePosition( GzVector pos ){ GzPose pose; pose = this->GetRelativePose(); pose.pos = pos; this->SetRelativePose(pose); return;}//////////////////////////////////////////////////////////////////////////////// Set the rotation (body-centered cs)void BaseGeom::SetRelativeRotation( GzQuatern rot ){ GzPose pose; pose = this->GetRelativePose(); pose.rot = rot; this->SetRelativePose(pose); return;}//////////////////////////////////////////////////////////////////////////////// Set the mass of the object. void BaseGeom::SetMass( double m ){ if (m < 1e-16) return; // Update the ODE mass dMassAdjust( &this->geomMass, m ); // Update the bodies CoM this->body->UpdateCoM(); return;}//////////////////////////////////////////////////////////////////////////////// Get the mass matrix (body-centered coords)const dMass *BaseGeom::GetBodyMassMatrix(){ GzPose pose; dQuaternion q; dMatrix3 r; if (!this->placeableGeom) return NULL; // Get the pose relative to the body pose = this->GetRelativePose(); // Construct the rotation matrix q[0] = pose.rot.u; q[1] = pose.rot.x; q[2] = pose.rot.y; q[3] = pose.rot.z; dQtoR(q, r); // Compute the transformed mass matrix this->bodyMass = this->geomMass; dMassRotate( &this->bodyMass, r ); dMassTranslate( &this->bodyMass, pose.pos.x, pose.pos.y, pose.pos.z ); return &this->bodyMass;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?