world.cc
来自「机器人人3D仿真工具,可以加入到Simbad仿真环境下应用。」· CC 代码 · 共 902 行 · 第 1/2 页
CC
902 行
PRINT_ERR1("error loading plugin: %s", dlerror()); i=j+1; } } // try to load it from the directory where the config file is if (!handle && worldfilepath) { // Note that dirname() modifies the contents, so // we need to make a copy of the filename. tmp = strdup(worldfilepath); memset(fullpath,0,PATH_MAX); cfgdir = dirname(tmp); if(cfgdir[0] != '/' && cfgdir[0] != '~') { getcwd(fullpath, PATH_MAX); strcat(fullpath,"/"); } strcat(fullpath,cfgdir); strcat(fullpath,"/"); strcat(fullpath,pluginname); free(tmp); PRINT_MSG1(1, "loading %s...", fullpath); if(!(handle = dlopen(fullpath, RTLD_NOW))) PRINT_ERR1("error loading plugin: %s", dlerror()); } // works in more than one version of autotools. Fix this later. // try to load it from prefix/lib/player/plugins if(!handle) { memset(fullpath,0,PATH_MAX); strcpy(fullpath,GAZEBO_PLUGIN_PATH); strcat(fullpath,"/"); strcat(fullpath,pluginname); PRINT_MSG1(1, "loading %s...", fullpath); if(!(handle = dlopen(fullpath, RTLD_NOW))) PRINT_ERR1("error loading plugin: %s", dlerror()); } // Now invoke the initialization function if(handle) { fflush(stdout); initfunc = (gz_plugin_init_fn_t) dlsym(handle, "gazebo_plugin_init"); if((error = dlerror()) != NULL) { PRINT_ERR1("plugin init failed [%s]", error); return -1; } if((*initfunc)() != 0) { PRINT_ERR("plugin init failed"); return -1; } return 0; } else return -1; return 0; #else PRINT_ERR("Sorry, no support for shared libraries, so can't load plugins"); return 0;#endif}//////////////////////////////////////////////////////////////////////////////// Save the world// This save only changes to pose, and only for top-level objectsint World::Save(){ int i; Model *model; for (i = 0; i < this->modelCount; i++) { model = this->models[i]; if (model->parent != NULL) continue; model->initPose = model->GetPose(); model->node->SetPosition("xyz", model->GetPose().pos); model->node->SetRotation("rpy", model->GetPose().rot); } PRINT_MSG1(1, "\nsaving: %s\n", this->worldFile->filename); this->worldFile->Save(NULL); return 0;}//////////////////////////////////////////////////////////////////////////////// Set the model pose and the pose of its attached children. void World::SetModelPose( Model *model, GzPose pose ){ int i; Model *child; GzPose opose, npose, cpose; // Get the current global pose of the model opose = model->GetPose(); // Compute the new global pose of the model if (model->parent) { cpose = model->parentBody->GetPose(); npose = GzCoordPoseAdd( pose, cpose ); } else { npose = pose; } // Recursively move children for (i = 0; i < this->modelCount; i++) { child = this->models[i]; if (child->parent != model) continue; // Compute current relative pose of child cpose = GzCoordPoseSub(child->GetPose(), opose); // Compute the new global pose of the child cpose = GzCoordPoseAdd( cpose, npose ); // Compute the new child pose relative to the current model pose cpose = GzCoordPoseSub( cpose, opose ); // Move child this->SetModelPose( child, cpose ); } // Set the new model pose model->SetPose( npose ); // Set our relative pose if (model->parentBody && model->joint == NULL) model->relPose = GzCoordPoseSub(model->GetPose(), model->parentBody->GetPose()); return;}//////////////////////////////////////////////////////////////////////////////// Reset the worldvoid World::ResetModelPoses(){ int i; Model *model; // Update models for (i = 0; i < this->modelCount; i++) { model = this->models[i]; this->SetModelPose(model, model->initPose); } return;}//////////////////////////////////////////////////////////////////////////////// Single-step the worldvoid World::Step(){ int i; Model *model; GzPose pose; gz_sim_data_t *data; bool reset, save, pause; data = this->gz_sim->data; // Check for commands from the external interface gz_sim_lock(this->gz_sim, 1); pause = data->pause; reset = data->reset; data->reset = 0; save = data->save; data->save = 0; gz_sim_unlock(this->gz_sim); // Reset poses on request if (reset) this->ResetModelPoses(); // Save poses on request if (save) this->Save(); // If we are paused, we do something a bit sneaky: we update the // models, but dont advance the simulator time. This allows models // like the ObserverCam to continue to provide feedback. if (pause) { for (i = 0; i < this->modelCount; i++) { model = this->models[i]; model->MasterUpdate( 0.0 ); } // Increment the pause time this->pauseTime += this->stepTime; } else { // Update models for (i = 0; i < this->modelCount; i++) { model = this->models[i]; model->MasterUpdate( this->stepTime ); } // Increment the time this->simTime += this->stepTime; // Do collision detection; this will add contacts to the contact // group dSpaceCollide( this->spaceId, this, CollisionCallback ); // Update the dynamical model dWorldStep( this->worldId, this->stepTime ); //dWorldStepFast1( this->worldId, step, 10 ); // Very important to clear out the contact group dJointGroupEmpty( this->contactGroup ); // Move models with dummy bodies, since ODE wont do it for (i = 0; i < this->modelCount; i++) { model = this->models[i]; if (model->parentBody != NULL && model->joint == NULL) { pose = GzCoordPoseAdd(model->relPose, model->parentBody->GetPose()); model->SetPose(pose); } } } // Update the external interface gz_sim_lock(this->gz_sim, 1); data->sim_time = this->GetSimTime(); data->pause_time = this->GetPauseTime(); data->real_time = this->GetRealTime(); gz_sim_unlock(this->gz_sim); return;}//////////////////////////////////////////////////////////////////////////////// Do collision detectionvoid World::CollisionCallback( void *data, dGeomID o1, dGeomID o2 ){ int i,n; World *self; Geom *geom1, *geom2; dContactGeom contactGeoms[10]; dContact contactInfo; dJointID joint; int num; self = (World*) data; // Maximum number of contacts num = sizeof(contactGeoms) / sizeof(contactGeoms[0]); // If either geom is a space... if (dGeomIsSpace( o1 ) || dGeomIsSpace( o2 )) { // If the spaces/geoms belong to different spaces, collide them if (dGeomGetSpace(o1) != dGeomGetSpace(o2)) dSpaceCollide2( o1, o2, self, &CollisionCallback ); // If the spaces belong the world space, collide them else if (dGeomGetSpace(o1) == self->spaceId || dGeomGetSpace(o2) == self->spaceId) dSpaceCollide2( o1, o2, self, &CollisionCallback ); } else { // There should be no geoms in the world space assert(dGeomGetSpace(o1) != self->spaceId); assert(dGeomGetSpace(o2) != self->spaceId); // We should never test two geoms in the same space assert(dGeomGetSpace(o1) != dGeomGetSpace(o2)); // Get pointers to the underlying geoms geom1 = NULL; if (dGeomGetClass(o1) == dGeomTransformClass) geom1 = (Geom*) dGeomGetData(dGeomTransformGetGeom(o1)); else geom1 = (Geom*) dGeomGetData(o1); geom2 = NULL; if (dGeomGetClass(o2) == dGeomTransformClass) geom2 = (Geom*) dGeomGetData(dGeomTransformGetGeom(o2)); else geom2 = (Geom*) dGeomGetData(o2); assert(geom1 && geom2); // Detect collisions betweed geoms n = dCollide(o1, o2, num, contactGeoms, sizeof(contactGeoms[0])); for (i=0; i < n; i++) { dBodyID body1 = dGeomGetBody(contactGeoms[i].g1); dBodyID body2 = dGeomGetBody(contactGeoms[i].g2); // Dont add contact joints between already connected bodies. // Sometimes the body is unspecified; should probably figure out // what this means if (body1 && body2 && dAreConnectedExcluding(body1, body2, dJointTypeContact)) continue; contactInfo.geom = contactGeoms[i]; contactInfo.surface.mode = 0; // Compute the CFM and ERP by assuming the two bodies form a // spring-damper system. double h, kp, kd; h = self->stepTime; kp = 1 / (1 / geom1->contact->kp + 1 / geom2->contact->kp); kd = geom1->contact->kd + geom2->contact->kd; contactInfo.surface.mode |= dContactSoftERP | dContactSoftCFM; contactInfo.surface.soft_erp = h * kp / (h * kp + kd); contactInfo.surface.soft_cfm = 1 / (h * kp + kd); /* printf("%f %f %f %f \n", kp, kd, contactInfo.surface.soft_erp, contactInfo.surface.soft_cfm); */ // Compute friction effects; this is standard Coulomb friction contactInfo.surface.mode |= dContactApprox1; contactInfo.surface.mu = Min(geom1->contact->mu1, geom2->contact->mu1); // Compute slipping effects //contactInfo.surface.slip1 = (geom1->contact->slip1 + geom2->contact->slip1)/2.0; //contactInfo.surface.slip2 = (geom1->contact->slip2 + geom2->contact->slip2)/2.0; // Construct a contact joint between the two bodies joint = dJointCreateContact(self->worldId, self->contactGroup, &contactInfo); dJointAttach(joint, body1, body2); } } return;}//////////////////////////////////////////////////////////////////////////////// Get the current sim time (elapsed time)double World::GetSimTime(){ return this->simTime;}//////////////////////////////////////////////////////////////////////////////// Get the current pause time (elapsed time)double World::GetPauseTime(){ return this->pauseTime;}//////////////////////////////////////////////////////////////////////////////// Get the current real time (elapsed time)double World::GetRealTime(){ return this->GetWallTime() - this->startTime;}//////////////////////////////////////////////////////////////////////////////// Get the wall clock timedouble World::GetWallTime(){ struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec + tv.tv_usec * 1e-6;}//////////////////////////////////////////////////////////////////////////////// Get the time relative to 12am (seconds)double World::GetDayTime(){ if (this->dayTime >=0) { return this->dayTime + this->GetRealTime(); } else { double wallTime = this->GetWallTime(); time_t wallTimeWhole = (time_t)(wallTime); wallTime -= wallTimeWhole; tm *dayTm = localtime(&wallTimeWhole); return dayTm->tm_hour*3600 + dayTm->tm_min*60 + dayTm->tm_sec + wallTime; }}//////////////////////////////////////////////////////////////////////////////// Add a modelvoid World::AddModel( Model *model ){ // Re-size array as needed if (this->modelCount >= this->modelMaxCount) { this->modelMaxCount += 10; this->models = (Model**) realloc( this->models, this->modelMaxCount * sizeof(this->models[0])); assert( this->models ); } this->models[this->modelCount] = model; this->modelCount++; return;}//////////////////////////////////////////////////////////////////////////////// Get the number of modelsint World::GetNumModels() const{ return this->modelCount;}//////////////////////////////////////////////////////////////////////////////// Get the list of modelsModel **World::GetModels() const{ return this->models;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?