00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <uwsim/URDFRobot.h>
00014 #include <uwsim/UWSimUtils.h>
00015 #include <osg/ShapeDrawable>
00016 #include <osg/Material>
00017 #include <math.h>
00018
00019
00020 struct ContactSensorCallback : public btCollisionWorld::ContactResultCallback
00021 {
00022
00024
00026 ContactSensorCallback(btRigidBody& tgtBody) :
00027 btCollisionWorld::ContactResultCallback(), body(tgtBody)
00028 {
00029 collided = 0;
00030 }
00031
00032 btRigidBody& body;
00033 int collided;
00034
00036
00038 virtual bool needsCollision(btBroadphaseProxy* proxy) const
00039 {
00040 if (proxy->m_collisionFilterGroup == 0x00000010)
00041 {
00042 return false;
00043 }
00044 return body.checkCollideWithOverride(static_cast<btCollisionObject*>(proxy->m_clientObject));
00045 }
00046
00047 #if BT_BULLET_VERSION <= 279
00048
00049 virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObject * colObj0, int partId0, int index0,
00050 const btCollisionObject * colObj1, int partId1, int index1)
00051 #else
00052 virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper * colObj0, int partId0, int index0,
00053 const btCollisionObjectWrapper * colObj1, int partId1, int index1)
00054 #endif
00055 {
00056
00057 #if BT_BULLET_VERSION <= 279
00058 if (((colObj0->getCollisionFlags() & btCollisionObject::CF_STATIC_OBJECT) > 0
00059 || (colObj0->getCollisionFlags() & btCollisionObject::CF_KINEMATIC_OBJECT) > 0)
00060 && ((colObj1->getCollisionFlags() & btCollisionObject::CF_STATIC_OBJECT) > 0
00061 || (colObj1->getCollisionFlags() & btCollisionObject::CF_KINEMATIC_OBJECT) > 0))
00062 #else
00063 if (((colObj0->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_STATIC_OBJECT) > 0
00064 || (colObj0->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_KINEMATIC_OBJECT) > 0)
00065 && ((colObj1->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_STATIC_OBJECT) > 0
00066 || (colObj1->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_KINEMATIC_OBJECT) > 0))
00067 #endif
00068 {
00069 collided = 1;
00070
00071 }
00072 return 0;
00073 }
00074 };
00075
00076 URDFRobot::URDFRobot(osgOcean::OceanScene *oscene, Vehicle vehicle) :
00077 KinematicChain(vehicle.nlinks, vehicle.njoints)
00078 {
00079 ScopedTimer buildSceneTimer("Loading URDF robot... \n", osg::notify(osg::ALWAYS));
00080 const std::string SIMULATOR_DATA_PATH = std::string(getenv("HOME")) + "/.uwsim/data";
00081
00082 osgDB::Registry::instance()->getDataFilePathList().push_back(
00083 std::string(SIMULATOR_DATA_PATH) + std::string("/robot"));
00084 osgDB::Registry::instance()->getDataFilePathList().push_back(
00085 std::string(UWSIM_ROOT_PATH) + std::string("/data/shaders"));
00086 osgDB::Registry::instance()->getDataFilePathList().push_back(
00087 std::string(SIMULATOR_DATA_PATH) + std::string("/textures"));
00088
00089 URDFFile=vehicle.URDFFile;
00090
00091 link.resize(vehicle.nlinks);
00092
00093
00094 for (int i = 0; i < vehicle.nlinks; i++)
00095 {
00096 ScopedTimer buildSceneTimer(" · " + vehicle.links[i].geom->file + ": ", osg::notify(osg::ALWAYS));
00097
00098 link[i] = UWSimGeometry::loadGeometry(vehicle.links[i].geom);
00099 if (!link[i])
00100 exit(0);
00101 link[i]->setName(vehicle.links[i].name);
00102
00103 if (!vehicle.links[i].material.empty())
00104 {
00105 osg::ref_ptr < osg::StateSet > stateset = new osg::StateSet();
00106 osg::ref_ptr < osg::Material > material = new osg::Material();
00107 material->setDiffuse(
00108 osg::Material::FRONT_AND_BACK,
00109 osg::Vec4(vehicle.materials[vehicle.links[i].material].r, vehicle.materials[vehicle.links[i].material].g,
00110 vehicle.materials[vehicle.links[i].material].b, vehicle.materials[vehicle.links[i].material].a));
00111 stateset->setAttribute(material);
00112 if (vehicle.materials[vehicle.links[i].material].a < 1)
00113 {
00114 stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
00115 stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
00116 }
00117 link[i]->setStateSet(stateset);
00118 }
00119 }
00120
00121 bool success = true;
00122 for (int i = 0; i < vehicle.nlinks; i++)
00123 {
00124 if (!link[i].valid())
00125 {
00126 osg::notify(osg::WARN) << "Could not find " << vehicle.name << " link" << i << ".osg "
00127 << vehicle.links[i + 1].geom->file << std::endl;
00128 baseTransform = NULL;
00129 success = false;
00130 }
00131 }
00132
00133
00134 if (success)
00135 {
00136 ScopedTimer buildSceneTimer(" · Linking links...", osg::notify(osg::ALWAYS));
00137 osgDB::Registry::instance()->getDataFilePathList().push_back(
00138 std::string(UWSIM_ROOT_PATH) + std::string("/data/shaders"));
00139 static const char model_vertex[] = "default_scene.vert";
00140 static const char model_fragment[] = "default_scene.frag";
00141 std::vector < osg::ref_ptr<osg::MatrixTransform> > linkBaseTransforms(vehicle.nlinks);
00142 std::vector < osg::ref_ptr<osg::MatrixTransform> > linkPostTransforms(vehicle.nlinks);
00143
00144 osg::Matrix linkBase;
00145 osg::Matrix linkPost;
00146 for (int i = 0; i < vehicle.nlinks; i++)
00147 {
00148 link[i]->setNodeMask(
00149 oscene->getNormalSceneMask() | oscene->getReflectedSceneMask() | oscene->getRefractedSceneMask());
00150 linkBase.makeIdentity();
00151
00152
00153
00154
00155 linkBase.makeTranslate(
00156 osg::Vec3d(vehicle.links[i].position[0], vehicle.links[i].position[1], vehicle.links[i].position[2]));
00157 linkBase.preMultRotate(
00158 osg::Quat(vehicle.links[i].quat[0], vehicle.links[i].quat[1], vehicle.links[i].quat[2],
00159 vehicle.links[i].quat[3]));
00160 linkBase.preMultScale(osg::Vec3d(vehicle.links[i].geom->scale[0],vehicle.links[i].geom->scale[1],vehicle.links[i].geom->scale[2]));
00161
00162 linkBaseTransforms[i] = new osg::MatrixTransform;
00163 linkBaseTransforms[i]->setMatrix(linkBase);
00164 linkBaseTransforms[i]->addChild(link[i]);
00165
00166
00167 linkPost.makeIdentity();
00168 linkPost.preMultScale(osg::Vec3d(1.0/vehicle.links[i].geom->scale[0],1.0/vehicle.links[i].geom->scale[1],1.0/vehicle.links[i].geom->scale[2]));
00169 linkPost.preMultRotate(
00170 osg::Quat(vehicle.links[i].quat[0], vehicle.links[i].quat[1], vehicle.links[i].quat[2],
00171 vehicle.links[i].quat[3]).inverse());
00172 linkPost.preMultTranslate(
00173 -osg::Vec3d(vehicle.links[i].position[0], vehicle.links[i].position[1], vehicle.links[i].position[2]));
00174 linkPostTransforms[i] = new osg::MatrixTransform;
00175 linkPostTransforms[i]->setMatrix(linkPost);
00176 link[i]->asGroup()->addChild(linkPostTransforms[i]);
00177 }
00178
00179 joints.resize(vehicle.njoints);
00180 zerojoints.resize(vehicle.njoints);
00181
00182 for (int i = 0; i < vehicle.njoints; i++)
00183 {
00184 joints[i] = new osg::MatrixTransform;
00185 zerojoints[i] = new osg::MatrixTransform;
00186 }
00187
00188 osg::Matrix m;
00189 for (int i = 0; i < vehicle.njoints; i++)
00190 {
00191 m.makeTranslate(0, 0, 0);
00192 m.preMultTranslate(
00193 osg::Vec3d(vehicle.joints[i].position[0], vehicle.joints[i].position[1], vehicle.joints[i].position[2]));
00194 m.preMultRotate(
00195 osg::Quat(vehicle.joints[i].quat[0], vehicle.joints[i].quat[1], vehicle.joints[i].quat[2],
00196 vehicle.joints[i].quat[3]));
00197
00198 joints[i]->setMatrix(m);
00199 zerojoints[i]->setMatrix(m);
00200 }
00201
00202 baseTransform = new osg::MatrixTransform();
00203 baseTransform->addChild(linkBaseTransforms[0]);
00204
00205
00206 osg::ref_ptr < osg::Node > btaxis = UWSimGeometry::createSwitchableFrame();
00207
00208 btaxis->asGroup()->addChild(UWSimGeometry::createLabel(vehicle.name));
00209 baseTransform->addChild(btaxis);
00210
00211 for (int i = 0; i < vehicle.njoints; i++)
00212 {
00213 linkPostTransforms[vehicle.joints[i].parent]->asGroup()->addChild(joints[i]);
00214 joints[i]->addChild(linkBaseTransforms[vehicle.joints[i].child]);
00215
00216
00217 osg::ref_ptr < osg::Node > axis = UWSimGeometry::createSwitchableFrame();
00218
00219 axis->asGroup()->addChild(UWSimGeometry::createLabel(vehicle.joints[i].name));
00220
00221 joints[i]->addChild(axis);
00222 }
00223
00224 joint_axis.resize(vehicle.njoints);
00225 for (int i = 0; i < vehicle.njoints; i++)
00226 {
00227 joint_axis[i] = osg::Vec3d(vehicle.joints[i].axis[0], vehicle.joints[i].axis[1], vehicle.joints[i].axis[2]);
00228 jointType[i] = vehicle.joints[i].type;
00229 limits[i] = std::pair<double, double>(vehicle.joints[i].lowLimit, vehicle.joints[i].upLimit);
00230 names[i] = vehicle.joints[i].name;
00231 }
00232
00233
00234 for (int i = 0; i < vehicle.njoints; i++)
00235 {
00236 if (vehicle.joints[i].mimicp == -1)
00237 {
00238 mimic[i].joint = i;
00239 mimic[i].offset = 0;
00240 mimic[i].multiplier = 1;
00241 mimic[i].sliderCrank = 0;
00242 }
00243 else
00244 {
00245 mimic[i].joint = vehicle.joints[i].mimicp;
00246 mimic[i].offset = vehicle.joints[i].mimic->offset;
00247 mimic[i].multiplier = vehicle.joints[i].mimic->multiplier;
00248 if (vehicle.joints[i].name.find("slidercrank") != string::npos)
00249 mimic[i].sliderCrank = 1;
00250 else
00251 mimic[i].sliderCrank = 0;
00252 }
00253 }
00254
00255 osg::notify(osg::ALWAYS) << "Robot successfully loaded. Total time: ";
00256 }
00257 }
00258
00259 void URDFRobot::addToKinematicChain(osg::Node * newLink, btRigidBody* body)
00260 {
00261 link.push_back(newLink);
00262
00263
00264 if (body)
00265 {
00266 physics->dynamicsWorld->btCollisionWorld::removeCollisionObject(body);
00267 physics->dynamicsWorld->addCollisionObject(body, short(COL_VEHICLE), short(COL_OBJECTS));
00268 }
00269
00270 }
00271
00272 void URDFRobot::moveJoints(std::vector<double> &q)
00273 {
00274 osg::Matrix m;
00275
00276 for (int i = 0; i < getNumberOfJoints(); i++)
00277 {
00278 if (jointType[i] == 1)
00279 {
00280 if (mimic[i].sliderCrank == 0)
00281 m.makeRotate(q[mimic[i].joint] * mimic[i].multiplier + mimic[i].offset, joint_axis[i]);
00282 else
00283 m.makeRotate((q[mimic[i].joint] + asin(mimic[i].offset * sin(q[mimic[i].joint]))) * -1, joint_axis[i]);
00284 }
00285 else if (jointType[i] == 2)
00286 {
00287 m.makeTranslate(joint_axis[i] * (q[mimic[i].joint] * mimic[i].multiplier + mimic[i].offset));
00288 }
00289 else
00290 m.makeIdentity();
00291 osg::Matrix nm = zerojoints[i]->getMatrix();
00292 nm.preMult(m);
00293 joints[i]->setMatrix(nm);
00294 }
00295
00296 }
00297
00298 void URDFRobot::updateJoints(std::vector<double> &q)
00299 {
00300
00301 moveJoints(q);
00302
00303
00304 int collision = 0;
00305 for (int i = 1; i < link.size() && !collision; i++)
00306 {
00307 osg::ref_ptr < NodeDataType > data = dynamic_cast<NodeDataType*>(link[i]->getUserData());
00308 btRigidBody* tgtBody = data->rigidBody;
00309 if (tgtBody)
00310 {
00311 boost::shared_ptr<osg::Matrix> mat = getWorldCoords(link[i]);
00312
00313 mat->preMultScale(osg::Vec3d(1.0/mat->getScale().x(),1.0/mat->getScale().y(),1.0/mat->getScale().z()));
00314 tgtBody->setWorldTransform(osgbCollision::asBtTransform(*mat));
00315 ContactSensorCallback callback(*tgtBody);
00316 physics->dynamicsWorld->contactTest(tgtBody, callback);
00317 collision = callback.collided;
00318 }
00319 }
00320
00321
00322 if (!collision)
00323 {
00324
00325 for (int i = 0; i < getNumberOfJoints(); i++)
00326 qLastSafe[i] = q[i];
00327 }
00328
00329
00330
00331 else
00332 {
00333
00334 for (int i = 0; i < getNumberOfJoints(); i++)
00335 {
00336 this->q[i] = qLastSafe[i];
00337 }
00338 moveJoints (qLastSafe);
00339 }
00340
00341 }
00342
00343 void URDFRobot::updateJoints(std::vector<double> &q, int startJoint, int numJoints)
00344 {
00345 osg::Matrix m;
00346
00347 for (int i = startJoint; i < startJoint + numJoints; i++)
00348 {
00349 m.makeRotate(q[mimic[i].joint] * mimic[i].multiplier + mimic[i].offset, joint_axis[i]);
00350 osg::Matrix nm = zerojoints[i]->getMatrix();
00351 nm.preMult(m);
00352 joints[i]->setMatrix(nm);
00353 }
00354 }
00355
00356 URDFRobot::~URDFRobot()
00357 {
00358 }