model.cc

来自「机器人人3D仿真工具,可以加入到Simbad仿真环境下应用。」· CC 代码 · 共 460 行

CC
460
字号
/* *  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 models. * Author: Andrew Howard * Date: 8 May 2003 * CVS: $Id: Model.cc,v 1.42 2006/03/12 17:38:56 natepak Exp $ */#include <GL/glu.h>#include <assert.h>#include "World.hh"#include "Body.hh"#include "Geom.hh"#include "HingeJoint.hh"#include "Model.hh"#include "WorldFile.hh"GLuint Model::pickIdMaster = 1;int Model::integerIdCounter = 1;//////////////////////////////////////////////////////////////////////////////// Default constructorModel::Model( World *world ){  this->world = world;  this->parent = NULL;  this->parentBody = NULL;  this->joint = NULL;  this->fixed = true;  this->modelSpaceId = dSimpleSpaceCreate( this->world->spaceId );    this->bodyCount = 0;  this->bodyMaxCount = 0;  this->bodies = NULL;    this->canonicalBody = NULL;  this->jointCount = 0;  this->jointMaxCount = 0;  this->joints = NULL;  this->logPoses = false;  this->poseCount = 0;  this->poseMaxCount = 0;  this->poses = NULL;  this->SetPickId(pickIdMaster++);  this->integerId = integerIdCounter++;  this->id = NULL;  this->name = NULL;  return;}//////////////////////////////////////////////////////////////////////////////// DestructorModel::~Model(){  if (this->joint)    delete this->joint;  if (this->joints)    free(this->joints);  if (this->bodies)    free(this->bodies);  if (this->poses)    free(this->poses);  if (this->id)    delete [] id;  return;}//////////////////////////////////////////////////////////////////////////////// Load some values that are global to this modelint Model::MasterLoad( WorldFile *file, WorldFileNode *node ){  // Read some default values  this->gravityMode = node->GetBool("gravity", true);  this->enable = node->GetBool("enabled", true);  // Load the model specific info  return this->Load(file, node);}//////////////////////////////////////////////////////////////////////////////// Generic Update. Called for all models. This calls Updatevoid Model::MasterUpdate( double step ){  if (this->logPoses)    this->LogPose();  this->Update(step);}//////////////////////////////////////////////////////////////////////////////// Set our parentvoid Model::SetParent(Model *parent, Body *parentBody){  assert(this->parent == NULL);    this->parent = parent;  this->parentBody = parentBody;  this->SetPickId( this->parent->GetPickId() );  return;}//////////////////////////////////////////////////////////////////////////////// Attach this model to another.void Model::Attach(){  GzVector pos;  assert(this->parent != NULL);  assert(this->parentBody != NULL);  assert(this->GetBody());  // If both we and our parent have real ODE bodies, create an ODE  // joint  if (this->GetBody()->GetBodyId() && this->parentBody->GetBodyId())  {    pos = this->GetBody()->GetPosition();        this->joint = new HingeJoint( this->world );    this->joint->Attach( this->GetBody(), this->parentBody );    this->joint->SetAnchor( pos );    this->joint->SetAxis( GzVectorSet(0, 0, 1) );    this->joint->SetParam( dParamHiStop, 0 );    this->joint->SetParam( dParamLoStop, 0 );  }  // If either we or our parent has a dummy body, just store the  // relative pose  else  {    this->joint = NULL;    this->relPose = GzCoordPoseSub(this->GetBody()->GetPose(), this->parentBody->GetPose());  }  return;}//////////////////////////////////////////////////////////////////////////////// Detach this model from another.void Model::Detach(){  this->joint->Detach();  delete this->joint;  this->joint = NULL;    return;}//////////////////////////////////////////////////////////////////////////////// Add a body to this modelvoid Model::AddBody(Body *body, bool canonical){  // Re-size array as needed  if (this->bodyCount >= this->bodyMaxCount)  {    this->bodyMaxCount += 10;    this->bodies = (Body**) realloc(this->bodies, this->bodyMaxCount *                                     sizeof(this->bodies[0]));    assert(this->bodies);  }  body->SetPickId(this->pickId);  // Add body to array  this->bodies[this->bodyCount++] = body;  // Exactly one body should be used as the canonical body  if (canonical)  {    assert(this->canonicalBody == NULL);    this->canonicalBody = body;    // This is a bit naughty: make sure the names are consistent    body->bodyName = "canonical";  }  body->SetGravityMode(this->gravityMode);  body->Enable(this->enable);  return;}//////////////////////////////////////////////////////////////////////////////// Get the canonical body for this modelBody *Model::GetBody(const char *bodyName){  int i;  Body *body;    if (bodyName == NULL)    return this->canonicalBody;  if (strcmp(bodyName, "canonical") == 0)    return this->canonicalBody;  for (i = 0; i < this->bodyCount; i++)  {    body = this->bodies[i];    if (body->bodyName == NULL)      continue;    if (strcmp(bodyName, body->bodyName) == 0)      return body;  }  return NULL;}//////////////////////////////////////////////////////////////////////////////// Set the id of the modelvoid Model::SetId(const char *id){  if (id != NULL)  {    if (this->id != NULL)    {      delete [] this->id;      this->id = NULL;    }    this->id = new char[strlen(id)+1];    strcpy(this->id,id);    // Set the null character, just to be safe.    this->id[strlen(id)] = '\0';  }}//////////////////////////////////////////////////////////////////////////////// Set the name of the modelvoid Model::SetName(const char *name){  if (name != NULL)  {    if (this->name != NULL)    {      delete [] this->name;      this->name = NULL;    }    this->name = new char[strlen(name)+1];    strcpy(this->name,name);    // Set the null character, just to be safe.    this->name[strlen(name)] = '\0';  }}//////////////////////////////////////////////////////////////////////////////// Get the name of the modelconst char* Model::GetName(){  return this->name;}//////////////////////////////////////////////////////////////////////////////// Get the model pose (global frame)GzPose Model::GetPose(){  assert(this->GetBody());  return this->GetBody()->GetPose();}//////////////////////////////////////////////////////////////////////////////// Set the pose of the model (global cs)void Model::SetPose( GzPose pose ){  int i;  Body *body;  GzPose opose, npose, mpose;   // TODO: Only set pose of the new pose is different  // Get the current pose of the model  opose = this->GetPose();  assert(GzPoseFinite(opose));  // Compute the new pose of the model  npose = pose;  for (i = 0; i < this->bodyCount; i++)  {    body = this->bodies[i];    // Get the current pose of this body    mpose = body->GetPose();              // Compute the pose relative to the model    mpose = GzCoordPoseSub( mpose, opose );    // Compute the new pose    mpose = GzCoordPoseAdd( mpose, npose );    assert(GzPoseFinite(mpose));            // Set the new position and rotation    body->SetPose( mpose );       // Reset the object velocity    body->SetLinearVel(GzVectorSet(0, 0, 0));    body->SetAngularVel(GzVectorSet(0, 0, 0));  }  return;}//////////////////////////////////////////////////////////////////////////////// Log the current pose of the canonical bodyvoid Model::LogPose(){  GzPose pose;  double dist = 1.0;  assert(this->canonicalBody);  // Re-size array as needed  if (this->poseCount >= this->poseMaxCount)  {    this->poseMaxCount += 50;    this->poses = (GzPose*) realloc( this->poses, this->poseMaxCount * sizeof(this->poses[0]));    assert( this->poses );  }  if (this->poseCount>0)  {    pose = this->canonicalBody->GetCoMPose();    dist = sqrt( pow(this->poses[this->poseCount-1].pos.x-pose.pos.x,2) +        pow(this->poses[this->poseCount-1].pos.y-pose.pos.y,2) +         pow(this->poses[this->poseCount-1].pos.z-pose.pos.z,2));  }  if (dist >= 1.0)  {    this->poses[this->poseCount] = pose;    this->poseCount++;  }}//////////////////////////////////////////////////////////////////////////////// Set the pick id of the modelvoid Model::SetPickId( GLuint id ){  this->pickId = id;  for (int i=0; i<this->bodyCount; i++)  {    this->bodies[i]->SetPickId(id);  }  return;}//////////////////////////////////////////////////////////////////////////////// Get the Pick id of the modelGLuint Model::GetPickId() const{  return this->pickId;}//////////////////////////////////////////////////////////////////////////////// Return the integer ID of this modelint Model::GetIntId() const{  return this->integerId;}//////////////////////////////////////////////////////////////////////////////// Return the integer ID of this model's parentint Model::GetParentIntId() const{  return this->parent == NULL ? 0: this->parent->GetIntId();}//////////////////////////////////////////////////////////////////////////////// Render the modelvoid Model::Render( int pass, RenderOptions *renderOpt ){  int i;  for (i = 0; i < this->bodyCount; i++)  {   this->bodies[i]->Render(pass, renderOpt);  }  if (this->logPoses && this->poseCount > 0 && pass==GZ_RENDER_MAX_PASSES-1)  {    GLUquadricObj *quad = gluNewQuadric();    gluQuadricOrientation(quad, GLU_OUTSIDE);    gluQuadricDrawStyle(quad, GLU_LINE);    glPushMatrix();    glTranslatef(this->poses[0].pos.x,this->poses[0].pos.y,this->poses[0].pos.z);    gluSphere(quad, 0.05, 3, 3);    for (i=1; i< this->poseCount; i++)    {      glTranslatef(this->poses[i].pos.x-this->poses[i-1].pos.x,           this->poses[i].pos.y-this->poses[i-1].pos.y,           this->poses[i].pos.z-this->poses[i-1].pos.z);      gluSphere(quad, 0.05, 5, 5);    }    glPopMatrix();        glBegin(GL_LINE_STRIP);    for (i=0; i< this->poseCount; i++)    {      glVertex3f(this->poses[i].pos.x, this->poses[i].pos.y, this->poses[i].pos.z);    }    glVertex3f(this->canonicalBody->GetPose().pos.x,this->canonicalBody->GetPose().pos.y,this->canonicalBody->GetPose().pos.z);    glEnd();    gluDeleteQuadric(quad);      }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?