00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <robot/sim/SimulatedRobot>
00026
00027 #include <sstream>
00028
00029 #include <base/SimpleXMLSerializer>
00030 #include <base/Externalizer>
00031 #include <base/Orient>
00032
00033 #include <physics/Box>
00034 #include <physics/Solid>
00035 #include <physics/ConstraintGroup>
00036 #include <physics/FixedConstraint>
00037 #include <physics/CollisionCuller>
00038 #include <physics/CollisionDetector>
00039
00040 #include <robot/sim/SimulatedPlatform>
00041 #include <robot/sim/SimulatedSerialManipulator>
00042
00043 using robot::sim::SimulatedRobot;
00044
00045 using base::array;
00046 using base::Point3;
00047 using base::VFile;
00048 using base::Externalizer;
00049 using base::Orient;
00050 using physics::Box;
00051 using physics::Solid;
00052 using physics::Spatial;
00053 using physics::SpatialGroup;
00054 using physics::ConstraintGroup;
00055 using physics::FixedConstraint;
00056 using physics::Collidable;
00057 using physics::CollidableGroup;
00058 using physics::CollisionCuller;
00059 using physics::CollisionDetector;
00060 using robot::sim::SimulatedPlatform;
00061 using robot::sim::SimulatedSerialManipulator;
00062
00063
00064
00065
00066 SimulatedRobot::SimulatedRobot(ref<base::VFile> robotSpecification,
00067 const base::Point3& initialPosition, const base::Orient& initialOrientation,
00068 ref<physics::SolidSystem> solidSystem, bool dynamic)
00069 : solidSystem(solidSystem), dynamic(dynamic)
00070 {
00071 Assert(solidSystem!=0);
00072
00073
00074 if (robotSpecification->extension() == "xml") {
00075
00076
00077 try {
00078 Externalizer e(Externalizable::Input, robotSpecification);
00079 externalize(e,"xml",1.0);
00080 } catch (std::exception&) {
00081 throw std::invalid_argument(Exception("not a valid robot .xml file."));
00082 }
00083
00084 }
00085 else
00086 throw std::invalid_argument(Exception("file format unsupported."));
00087
00088 construct(initialPosition, initialOrientation);
00089 }
00090
00091
00092 SimulatedRobot::SimulatedRobot(ref<const robot::RobotDescription> robotDescription,
00093 const base::Point3& initialPosition, const base::Orient& initialOrientation,
00094 ref<physics::SolidSystem> solidSystem, bool dynamic)
00095 : solidSystem(solidSystem), dynamic(dynamic)
00096 {
00097 Assert(solidSystem!=0);
00098
00099 setRobotDescription( robotDescription );
00100
00101 platform = ref<SimulatedPlatform>(NewObj SimulatedPlatform(robotDescription->platform(), solidSystem, dynamic));
00102
00103 const array<ref<const ManipulatorDescription> > manips(robotDescription->manipulators());
00104 for (Int i=0; i<manips.size(); i++) {
00105 ref<SimulatedSerialManipulator> m(NewObj SimulatedSerialManipulator(manips[i], solidSystem, dynamic));
00106 manipulators.push_back(m);
00107 }
00108
00109 construct(initialPosition, initialOrientation);
00110 }
00111
00112
00113 void SimulatedRobot::setDynamic(bool enabled)
00114 {
00115 platform->setDynamic(false);
00116
00117 reflist<SimulatedSerialManipulator>::iterator m = manipulators.begin();
00118 reflist<SimulatedSerialManipulator>::iterator end = manipulators.end();
00119 while (m != end) {
00120 (*m)->setDynamic(enabled);
00121 ++m;
00122 }
00123 }
00124
00125
00126
00127 array<std::pair<String,String> > SimulatedRobot::controlInterfaces() const
00128 {
00129 array<std::pair<String,String> > a;
00130 if (dynamic) {
00131 a.push_back(std::make_pair<String,String>("platform","PlatformControl"));
00132 a.push_back(std::make_pair<String,String>("platformVelocity","PlatformVelocityControl"));
00133 }
00134 else
00135 a.push_back(std::make_pair<String,String>("platformPosition","PlatformPositionControl"));
00136
00137 for(Int m=0; m<getRobotDescription()->manipulators().size();m++) {
00138 ref<const ManipulatorDescription> md( getRobotDescription()->manipulators()[m] );
00139 ref<const SimulatedManipulatorDescription> smd;
00140 if (instanceof(*md, const SimulatedManipulatorDescription))
00141 smd = narrow_ref<const SimulatedManipulatorDescription>(md);
00142 else
00143 smd = ref<SimulatedManipulatorDescription>(NewObj SimulatedManipulatorDescription(*md));
00144
00145 String n(base::intToString(m+1));
00146 if (dynamic) {
00147 a.push_back(std::make_pair<String,String>("manipulator"+n,"JointForceControl"));
00148 a.push_back(std::make_pair<String,String>("manipulatorVelocity"+n,"JointVelocityControl"));
00149 a.push_back(std::make_pair<String,String>("tool"+n,"JointForceControl"));
00150 a.push_back(std::make_pair<String,String>("toolVelocity"+n,"JointVelocityControl"));
00151 }
00152 else {
00153 a.push_back(std::make_pair<String,String>("manipulatorPosition"+n,"JointPositionControl"));
00154 a.push_back(std::make_pair<String,String>("toolPosition"+n,"JointPositionControl"));
00155 }
00156 if (smd->hasLinkProximitySensors())
00157 a.push_back(std::make_pair<String,String>("manipulatorProximity"+n,"LinkProximitySensors"));
00158 a.push_back(std::make_pair<String,String>("manipulatorToolGrip"+n,"ToolGripControl"));
00159 }
00160 return a;
00161 }
00162
00163
00164
00165
00166
00167
00168
00169 void SimulatedRobot::setPosition(const Point3& pos)
00170 {
00171 spatialGroup->updateGroupConfiguration( platform->getConfiguration() );
00172 spatialGroup->setPosition(pos);
00173 }
00174
00175 Point3 SimulatedRobot::getPosition() const
00176 {
00177 spatialGroup->updateGroupConfiguration( platform->getConfiguration() );
00178 return spatialGroup->getPosition();
00179 }
00180
00181 void SimulatedRobot::setOrientation(const Orient& orient)
00182 {
00183 spatialGroup->updateGroupConfiguration( platform->getConfiguration() );
00184 spatialGroup->setOrientation(orient);
00185 }
00186
00187 Orient SimulatedRobot::getOrientation() const
00188 {
00189 spatialGroup->updateGroupConfiguration( platform->getConfiguration() );
00190 return spatialGroup->getOrientation();
00191 }
00192
00193 void SimulatedRobot::setConfiguration(const base::Transform& configuration)
00194 {
00195 spatialGroup->updateGroupConfiguration( platform->getConfiguration() );
00196 spatialGroup->setConfiguration(configuration);
00197 }
00198
00199 base::Transform SimulatedRobot::getConfiguration() const
00200 {
00201 spatialGroup->updateGroupConfiguration( platform->getConfiguration() );
00202 return spatialGroup->getConfiguration();
00203 }
00204
00205
00206
00207
00208
00209
00210 bool SimulatedRobot::formatSupported(String format, Real version, ExternalizationType type) const
00211 {
00212 return ( ((format=="dh") || (format=="xml")) && (version==1.0) && (type==Input) );
00213 }
00214
00215
00216 void SimulatedRobot::externalize(base::Externalizer& e, String format, Real version)
00217 {
00218 if (format=="") format = String("xml");
00219
00220 if (!formatSupported(format,version,e.ioType()))
00221 throw std::invalid_argument(Exception(String("format ")+format+" "+base::realToString(version)+" unsupported"));
00222
00223 if (format == "dh") {
00224
00225 if (e.isInput()) {
00226
00227 spatialGroup = ref<SpatialGroup>(NewObj SpatialGroup());
00228
00229
00230 ref<PlatformDescription> pd(NewObj PlatformDescription("platform",base::Dimension3(1,1,0.1), base::Vector3(0,0,0.05), false));
00231 platform = ref<SimulatedPlatform>(NewObj SimulatedPlatform(pd));
00232 spatialGroup->add(platform);
00233
00234
00235
00236 ref<SimulatedSerialManipulator> m(NewObj SimulatedSerialManipulator(solidSystem));
00237 m->externalize(e,format,version);
00238 manipulators.push_back(m);
00239 spatialGroup->add(m);
00240
00241
00242 array<Vector3> offsets(1);
00243 offsets[0] = Vector3();
00244
00245
00246 array<ref<const ManipulatorDescription> > manipulatorDescrs(1);
00247 manipulatorDescrs[0] = m->getManipulatorDescription();
00248
00249 setRobotDescription( ref<RobotDescription>(NewObj RobotDescription("robot",pd,manipulatorDescrs,offsets)) );
00250
00251 }
00252
00253 }
00254 else if (format == "xml") {
00255
00256 if (e.isInput()) {
00257
00258
00259
00260 ref<RobotDescription> rd(NewObj RobotDescription());
00261 rd->externalize(e, format, version);
00262
00263 setRobotDescription( rd );
00264
00265 spatialGroup = ref<SpatialGroup>(NewObj SpatialGroup());
00266
00267 platform = ref<SimulatedPlatform>(NewObj SimulatedPlatform(rd->platform()));
00268 spatialGroup->add(platform);
00269
00270 const array<ref<const ManipulatorDescription> >& manips(rd->manipulators());
00271 for (Int i=0; i<manips.size(); i++) {
00272 ref<SimulatedSerialManipulator> m(NewObj SimulatedSerialManipulator(manips[i], solidSystem));
00273 manipulators.push_back(m);
00274 spatialGroup->add(m);
00275 }
00276
00277 }
00278
00279 }
00280
00281 }
00282
00283
00284
00285
00286 void SimulatedRobot::construct(const base::Point3& initialPosition, const base::Orient& initialOrientation)
00287 {
00288 Assert(solidSystem);
00289 spatialGroup = ref<SpatialGroup>(NewObj SpatialGroup());
00290 spatialGroup->setPositionOrientation(initialPosition, initialOrientation);
00291
00292
00293 Assert(platform);
00294 platform->setSolidSystem(solidSystem);
00295 platform->construct(initialPosition, initialOrientation);
00296 spatialGroup->add(platform);
00297
00298 ref<const RobotDescription> rd(getRobotDescription());
00299 ref<ConstraintGroup> cgroup(solidSystem->createConstraintGroup());
00300
00301 Int manipulatorIndex=0;
00302
00303 reflist<SimulatedSerialManipulator>::iterator m = manipulators.begin();
00304 reflist<SimulatedSerialManipulator>::iterator end = manipulators.end();
00305 while (m != end) {
00306 ref<SimulatedSerialManipulator> sm(*m);
00307
00308
00309 Matrix4 offsetTransform; offsetTransform.setToTranslation(rd->manipulatorOffsets()[manipulatorIndex]);
00310 Matrix4 platformTransform(initialOrientation.getRotationMatrix3()); platformTransform.setTranslationComponent(initialPosition);
00311 Matrix4 manipTransform(platformTransform * offsetTransform);
00312 Vector3 manipPosition = manipTransform.column(4).toVector3();
00313 Orient manipOrient = Matrix3(manipTransform);
00314
00315 sm->setSolidSystem(solidSystem);
00316 sm->construct(manipPosition, manipOrient);
00317 spatialGroup->add(sm);
00318
00319
00320 ref<FixedConstraint> fixed(solidSystem->createFixedConstraint());
00321 cgroup->addConstraint(fixed);
00322 fixed->attach(platform->getPlatformSolid(), sm->getBaseSolid());
00323
00324 ++m; ++manipulatorIndex;
00325 }
00326
00327 if (manipulatorIndex > 0)
00328 solidSystem->addConstraintGroup(cgroup);
00329
00330 }
00331
00332
00333
00334 bool SimulatedRobot::checkProximity(ref<SimulatedTool> tool)
00335 {
00336
00337 bool anyInProximity = false;
00338 reflist<SimulatedSerialManipulator>::iterator m = manipulators.begin();
00339 reflist<SimulatedSerialManipulator>::iterator end = manipulators.end();
00340 while (m != end) {
00341 ref<SimulatedSerialManipulator> sm(*m);
00342 if (sm->checkProximity(tool))
00343 anyInProximity=true;
00344 ++m;
00345 }
00346 return anyInProximity;
00347 }
00348
00349
00350 void SimulatedRobot::placeToolInProximity(ref<SimulatedTool> tool, Int manipIndex)
00351 {
00352 ref<SimulatedSerialManipulator> sm( base::elementAt(manipulators, manipIndex) );
00353
00354
00355 tool->setPositionOrientation( sm->getEEPosition(), sm->getEEOrientation() );
00356 sm->setToolInProximity(tool);
00357 }
00358
00359
00360 bool SimulatedRobot::graspTool(Int manipIndex)
00361 {
00362 ref<SimulatedSerialManipulator> sm( base::elementAt(manipulators, manipIndex) );
00363 return sm->graspTool();
00364 }
00365
00366
00367 void SimulatedRobot::releaseGrasp(Int manipIndex)
00368 {
00369 ref<SimulatedSerialManipulator> sm( base::elementAt(manipulators, manipIndex) );
00370 sm->releaseGrasp();
00371 }
00372
00373
00374 ref<physics::Collidable> SimulatedRobot::createCollidable(CollidableFlags flags)
00375 {
00376 ref<CollisionCuller> cc(solidSystem->getCollisionCuller());
00377
00378 ref<CollidableGroup> collidableGroup = cc->createCollidableGroup();
00379 ref<Collidable> platformCollidable( platform->createCollidable(flags) );
00380 collidableGroup->addCollidable(platformCollidable);
00381 ref<Collidable> platform( platformCollidable->findNamed("platformBody") );
00382
00383
00384 reflist<SimulatedSerialManipulator>::iterator m = manipulators.begin();
00385 reflist<SimulatedSerialManipulator>::iterator end = manipulators.end();
00386 while (m != end) {
00387 ref<SimulatedSerialManipulator> sm(*m);
00388 ref<Collidable> smCollidable( sm->createCollidable(flags) );
00389 collidableGroup->addCollidable( smCollidable );
00390
00391
00392 ref<Collidable> base( smCollidable->findNamed("baseLink") );
00393 if (platform && base)
00394 cc->collisionEnable(false,platform,base);
00395 ref<Collidable> baseSensor( smCollidable->findNamed("baseLink Sensor") );
00396 if (platform && baseSensor)
00397 cc->collisionEnable(false,platform,baseSensor);
00398
00399 ++m;
00400 }
00401
00402 return collidableGroup;
00403 }
00404
00405
00406
00407
00408
00409
00410
00411 ref<robot::ControlInterface> SimulatedRobot::getControlInterface(String interfaceName) throw(std::invalid_argument)
00412 {
00413 if (interfaceName == "") interfaceName = "platform";
00414
00415
00416
00417
00418
00419
00420
00421
00422 ref<SimulatedRobot> self(this);
00423 if (interfaceName == "platformVelocity")
00424 return ref<robot::ControlInterface>(NewObj PlatformControlInterface(interfaceName, "PlatformVelocityControl", self, platform, VelControl));
00425
00426 if (interfaceName == "platformPosition")
00427 return ref<robot::ControlInterface>(NewObj PlatformControlInterface(interfaceName, "PlatformPositionControl", self, platform, PosControl));
00428
00429 if (interfaceName == "platform")
00430 return ref<robot::ControlInterface>(NewObj PlatformControlInterface(interfaceName, "PlatformControl", self, platform, ForceControl));
00431
00432
00433 if (interfaceName.substr(0,19) == "manipulatorVelocity") {
00434 Int n = base::stringToInt(interfaceName.substr(19));
00435 if ((n<1) || (n > manipulators.size()))
00436 throw std::invalid_argument(Exception("manipulator index out of range"));
00437 ref<SimulatedSerialManipulator> manip( base::elementAt(manipulators,n-1) );
00438 return ref<robot::ControlInterface>(NewObj ManipulatorControlInterface(interfaceName,"JointVelocityControl",manip,VelControl));
00439 }
00440
00441 if (interfaceName.substr(0,19) == "manipulatorPosition") {
00442 Int n = base::stringToInt(interfaceName.substr(19));
00443 if ((n<1) || (n > manipulators.size()))
00444 throw std::invalid_argument(Exception("manipulator index out of range"));
00445 ref<SimulatedSerialManipulator> manip( base::elementAt(manipulators,n-1) );
00446 return ref<robot::ControlInterface>(NewObj ManipulatorControlInterface(interfaceName,"JointPositionControl",manip,PosControl));
00447 }
00448
00449
00450 if (interfaceName.substr(0,19) == "manipulatorToolGrip") {
00451 Int n = base::stringToInt(interfaceName.substr(19));
00452 if ((n<1) || (n > manipulators.size()))
00453 throw std::invalid_argument(Exception("manipulator index out of range"));
00454 ref<SimulatedSerialManipulator> manip( base::elementAt(manipulators,n-1) );
00455 return ref<robot::ControlInterface>(NewObj ToolControlInterface(interfaceName,"ToolGripControl", manip, true));
00456 }
00457
00458 if (interfaceName.substr(0,20) == "manipulatorProximity") {
00459 Int n = base::stringToInt(interfaceName.substr(20));
00460 if ((n<1) || (n > manipulators.size()))
00461 throw std::invalid_argument(Exception("manipulator index out of range"));
00462 ref<SimulatedSerialManipulator> manip( base::elementAt(manipulators,n-1) );
00463 if (manip->getManipulatorDescription()->hasLinkProximitySensors()) {
00464 return ref<robot::ControlInterface>(NewObj ProximitySensorInterface(interfaceName, "LinkProximitySensors", manip));
00465 }
00466 else
00467 throw std::invalid_argument(Exception(String("manipulator has no proximity sensors; invalid interface ")+interfaceName));
00468 }
00469
00470 if (interfaceName.substr(0,11) == "manipulator") {
00471 Int n = base::stringToInt(interfaceName.substr(11));
00472 if ((n<1) || (n > manipulators.size()))
00473 throw std::invalid_argument(Exception(String("manipulator index ")+base::intToString(n)+" out of range"));
00474 ref<SimulatedSerialManipulator> manip( base::elementAt(manipulators,n-1) );
00475 return ref<robot::ControlInterface>(NewObj ManipulatorControlInterface(interfaceName,"JointForceControl",manip));
00476 }
00477
00478
00479 if (interfaceName.substr(0,12) == "toolVelocity") {
00480 Int n = base::stringToInt(interfaceName.substr(12));
00481 if ((n<1) || (n > manipulators.size()))
00482 throw std::invalid_argument(Exception("manipulator index out of range"));
00483 ref<SimulatedSerialManipulator> manip( base::elementAt(manipulators,n-1) );
00484 return ref<robot::ControlInterface>(NewObj ToolControlInterface(interfaceName,"JointVelocityControl", manip, false, VelControl));
00485 }
00486
00487 if (interfaceName.substr(0,12) == "toolPosition") {
00488 Int n = base::stringToInt(interfaceName.substr(12));
00489 if ((n<1) || (n > manipulators.size()))
00490 throw std::invalid_argument(Exception("manipulator index out of range"));
00491 ref<SimulatedSerialManipulator> manip( base::elementAt(manipulators,n-1) );
00492 return ref<robot::ControlInterface>(NewObj ToolControlInterface(interfaceName,"JointPositionControl", manip, false, PosControl));
00493 }
00494
00495 if (interfaceName.substr(0,4) == "tool") {
00496 Int n = base::stringToInt(interfaceName.substr(4));
00497 if ((n<1) || (n > manipulators.size()))
00498 throw std::invalid_argument(Exception("manipulator index out of range"));
00499 ref<SimulatedSerialManipulator> manip( base::elementAt(manipulators,n-1) );
00500 return ref<robot::ControlInterface>(NewObj ToolControlInterface(interfaceName,"JointForceControl", manip, false, ForceControl));
00501 }
00502
00503
00504 throw std::invalid_argument(Exception(String("unknown interface ")+interfaceName));
00505 }
00506