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