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 #ifndef _ROBOT_KINEMATICCHAIN_
00026 #define _ROBOT_KINEMATICCHAIN_
00027
00028 #include <robot/robot>
00029
00030 #include <base/array>
00031 #include <base/Vector>
00032 #include <base/Matrix>
00033 #include <base/Serializer>
00034 #include <base/Externalizable>
00035 #include <base/Hashable>
00036 #include <robot/ManipulatorJointTrajectory>
00037 #include <robot/KinematicEvaluator>
00038
00039
00040
00041 namespace robot {
00042
00043
00044
00045
00046
00047 class KinematicChain : public base::Serializable, public base::Externalizable, public base::Hashable
00048 {
00049 public:
00050
00051
00052 enum UnitType { Distance, Angle };
00053
00054
00055 static const Real unboundedMinAngleLimit;
00056 static const Real unboundedMaxAngleLimit;
00057 static const Real unboundedMinDistLimit;
00058 static const Real unboundedMaxDistLimit;
00059
00060
00061
00062 class Link : public base::Serializable, public base::Externalizable, public base::Hashable
00063 {
00064 public:
00065
00066
00067
00068
00069 enum LinkType {
00070 FixedTransform,
00071 Prismatic,
00072 Revolute,
00073 Translating
00074 };
00075
00076 Link()
00077 : alpha(0), a(1), d(0), theta(0),
00078 jminLimit(0), jmaxLimit(0), jminAccel(0), jmaxAccel(0),
00079 linkType(Revolute), active(true), hashDirty(true)
00080 {}
00081 Link(const Link& j)
00082 : alpha(j.alpha), a(j.a), d(j.d), theta(j.theta), direction(j.direction), t(j.t), transform(j.transform),
00083 jminLimit(j.jminLimit), jmaxLimit(j.jmaxLimit), jminAccel(j.jminAccel), jmaxAccel(j.jmaxAccel),
00084 linkType(j.linkType), active(j.active), hashDirty(true)
00085 {}
00086 Link(LinkType type, Real alpha, Real a, Real d, Real theta,
00087 Real minLimit=KinematicChain::unboundedMinAngleLimit, Real maxLimit=KinematicChain::unboundedMaxAngleLimit,
00088 Real minAccel=0, Real maxAccel=0,
00089 bool active=true)
00090 : alpha(alpha), a(a), d(d), theta(theta),
00091 jminLimit(minLimit), jmaxLimit(maxLimit), jminAccel(minAccel), jmaxAccel(maxAccel),
00092 linkType(type), active(active), hashDirty(true)
00093 {
00094 if (dofUnitType(0) == Distance) {
00095 if (Math::equals(minLimit, KinematicChain::unboundedMinAngleLimit))
00096 minLimit = KinematicChain::unboundedMinDistLimit;
00097 if (Math::equals(maxLimit, KinematicChain::unboundedMaxAngleLimit))
00098 maxLimit = KinematicChain::unboundedMaxDistLimit;
00099 }
00100 }
00101
00102 Link(const Vector3& direction, Real t,
00103 Real minLimit=KinematicChain::unboundedMinDistLimit, Real maxLimit=KinematicChain::unboundedMaxDistLimit,
00104 Real minAccel=0, Real maxAccel=0,
00105 bool active=true)
00106 : direction(direction), t(t),
00107 jminLimit(minLimit), jmaxLimit(maxLimit), jminAccel(minAccel), jmaxAccel(maxAccel),
00108 linkType(Translating), active(active), hashDirty(true)
00109 {}
00110
00111 Link(const Matrix4& fixedTransform)
00112 : transform(fixedTransform), linkType(FixedTransform), active(false), hashDirty(true)
00113 {}
00114
00115 ~Link() {}
00116
00117 virtual String className() const { return String("Link"); }
00118
00119 Link& operator=(const Link& l);
00120
00121 LinkType type() const { return linkType; }
00122 bool isActive() const { return active; }
00123 bool isDHType() const { return (linkType==Prismatic)||(linkType==Revolute); }
00124
00125
00126 Int dof() const { return active?(isDHType()?1:(linkType==Translating?1:0)):0; }
00127
00128 UnitType dofUnitType(Int dof=0) const { return (isDHType() && (linkType==Revolute))?Angle:Distance; }
00129
00130
00131 Matrix kinematicTransform(const base::Vector& q) const;
00132
00133
00134
00135 Real getAlpha() const { return alpha; }
00136 Real getA() const { return a; }
00137 Real getD() const { return d; }
00138 Real getTheta() const { return theta; }
00139
00140 void setAlpha(Real alpha) { this->alpha=alpha; dirtyHash(); }
00141 void setA(Real a) { this->a = a; dirtyHash(); }
00142 void setD(Real d) { this->d = d; dirtyHash(); }
00143 void setTheta(Real theta) { this->theta = theta; dirtyHash(); }
00144
00145
00146 Vector3 getDirection() const { return direction; }
00147 Real getT() const { return t; }
00148
00149 void setDirection(const Vector3& dir) { direction = dir; dirtyHash(); }
00150 void setT(Real t) { this->t = t; dirtyHash(); }
00151
00152
00153 Matrix4 getTransform() const { return transform; }
00154 void setTransform(const Matrix4& transform) { this->transform = transform; dirtyHash(); }
00155
00156
00157 Real variable(Int dof=0) const {
00158 Assert(dof < this->dof());
00159 if (isDHType())
00160 return (linkType==Revolute)?theta:d;
00161 else if (linkType==Translating)
00162 return t;
00163 throw std::runtime_error(Exception("unhandled KinematicChain::Link type"));
00164 }
00165
00166 Real minLimit(Int dof=0) const { return jminLimit; }
00167 Real maxLimit(Int dof=0) const { return jmaxLimit; }
00168 Real minAccel(Int dof=0) const { return jminAccel; }
00169 Real maxAccel(Int dof=0) const { return jmaxAccel; }
00170
00171 bool operator==(const Link& l) const;
00172 bool operator!=(const Link& l) const { return !(*this == l); }
00173
00174 virtual void serialize(base::Serializer& s)
00175 {
00176 s(linkType,"type");
00177 if (linkType==Translating)
00178 s(direction,"direction");
00179 else {
00180 s(alpha,"alpha")(a,"a")(d,"d")(theta,"theta");
00181 }
00182 s(jminLimit,"minLimit")(jmaxLimit,"maxLimit");
00183 s(jminAccel,"minAccel")(jmaxAccel,"maxAccel");
00184 s(active,"active");
00185 if (s.isInput()) dirtyHash();
00186 }
00187
00188
00189 virtual bool formatSupported(const String format, Real version = 1.0, ExternalizationType type = IO) const
00190 { return ( (format=="xml") && (version==1.0) ); }
00191 virtual void externalize(base::Externalizer& e, String format = "", Real version = 1.0);
00192 virtual void externalize(base::Externalizer& e, String format = "", Real version = 1.0) const
00193 { Externalizable::externalize(e, format, version); }
00194
00195
00196 virtual base::array<base::Byte> hashCode() const;
00197
00198
00199 protected:
00200
00201 Real alpha;
00202 Real a;
00203 Real d;
00204 Real theta;
00205
00206
00207 Vector3 direction;
00208 Real t;
00209
00210
00211 Matrix4 transform;
00212
00213 Real jminLimit, jmaxLimit;
00214 Real jminAccel, jmaxAccel;
00215
00216 LinkType linkType;
00217 bool active;
00218
00219 String frameName;
00220
00221 mutable bool hashDirty;
00222 mutable array<base::Byte> hash;
00223 void dirtyHash() const { hashDirty=true; }
00224
00225 friend class KinematicChain;
00226 };
00227
00228
00229
00230 KinematicChain()
00231 : hashDirty(true) { initKinematicEvaluator(); }
00232 KinematicChain(const Link& l)
00233 : links(1), hashDirty(true) { initKinematicEvaluator(); links[0] = l; computeVariables(); }
00234
00235 KinematicChain(const KinematicChain& kc)
00236 : links(kc.links), variables(kc.variables), kinematicEvaluator(kc.kinematicEvaluator), hashDirty(true) {}
00237
00238
00239 virtual String className() const { return String("KinematicChain"); }
00240
00241 KinematicChain& operator=(const KinematicChain& kc)
00242 { links=kc.links; variables=kc.variables; dirtyHash(); return *this; }
00243
00244
00245
00246 Int size() const { return links.size(); }
00247 Int dof() const { return variables.size(); }
00248
00249 bool isDHType() const;
00250
00251 const Link& operator[](Int i) const { return links[i]; }
00252 void setLink(Int i, const Link& link) { links[i] = link; dirtyHash(); }
00253
00254 const Link& at(Int i) const { Assert(i < size()); return links[i]; }
00255 void setLinkAt(Int i, const Link& link) { Assert(i < size()); links[i] = link; dirtyHash(); }
00256
00257
00258 const Link& linkOfVariable(Int i) const { Assert(i < dof()); return links[variables[i].first]; }
00259
00260
00261 Int linkIndexOfVariable(Int i) const { Assert(i < dof()); return variables[i].first; }
00262
00263 UnitType variableUnitType(Int i) const
00264 { Assert(i < dof()); return linkOfVariable(i).dofUnitType( variables[i].second ); }
00265
00266 Real variableMinLimit(Int i) const { return linkOfVariable(i).minLimit(variables[i].second); }
00267 Real variableMaxLimit(Int i) const { return linkOfVariable(i).maxLimit(variables[i].second); }
00268 Real variableMinAccel(Int i) const { return linkOfVariable(i).minAccel(variables[i].second); }
00269 Real variableMaxAccel(Int i) const { return linkOfVariable(i).maxAccel(variables[i].second); }
00270
00271
00272 void activateLink(Int i, bool active=true)
00273 { Assert(i < size()); links[i].active=active; computeVariables(); dirtyHash(); }
00274 bool linkIsActive(Int i) const { Assert(i < size()); return links[i].isActive(); }
00275
00276
00277 Link front() const { Assert(size()>0); return links[0]; }
00278 Link back() const { Assert(size()>0); return links[size()-1]; }
00279
00280 void push_back(const Link& l)
00281 { links.at(size())=l; computeVariables(); dirtyHash(); }
00282
00283 void pop_back()
00284 { links.resize( size()-1 ); computeVariables(); dirtyHash(); }
00285
00286 void resize(Int newsize)
00287 { links.resize(newsize); computeVariables(); dirtyHash(); }
00288
00289
00290 KinematicChain subChain(Int first, Int count) const;
00291
00292 bool operator==(const KinematicChain& kc) const { return links==kc.links; }
00293 bool operator!=(const KinematicChain& kc) const { return links!=kc.links; }
00294
00295 KinematicChain& operator+=(const KinematicChain& kc);
00296
00297 KinematicChain& insert(Int pos, const KinematicChain& kc);
00298 KinematicChain& insert(Int pos, const Link& l);
00299 KinematicChain& erase(Int pos);
00300 KinematicChain& erase(Int first, Int last);
00301
00302
00303
00304 void setInitialFrame(const String& name) { initialFrame = name; dirtyHash(); }
00305 const String& getInitialFrame() const { return initialFrame; }
00306
00307 void setLinkFrame(Int i, const String& name) { Assert(i < size()); links[i].frameName = name; dirtyHash(); }
00308 const String& getLinkFrame(Int i) const { Assert(i < size()); return links[i].frameName; }
00309
00310
00311 Vector transform(Int fromLink, Int toLink, const Vector& v, const Vector& q) const;
00312
00313
00314
00315
00316
00317 Vector transform(const String& fromFrame, const String& toFrame, const Vector& v, const Vector& q) const;
00318
00319
00320
00321 Matrix getForwardKinematics(const Vector& q) const;
00322
00323
00324 Matrix getJacobian(const Vector& q, bool includeOrientation = true) const;
00325
00326
00327 array<Vector> getJointOrigins(const Vector& q) const;
00328
00329
00330 array<Vector> getLinkOrigins(const Vector& q) const;
00331
00332
00333 void setKinematicEvaluator(ref<KinematicEvaluator> evaluator)
00334 { kinematicEvaluator = evaluator; }
00335
00336
00337
00338
00339 void convertJointTrajectory(ManipulatorJointTrajectory& jointTrajectory,
00340 ManipulatorJointTrajectory::AngularUnits units = ManipulatorJointTrajectory::Radians) const
00341 {
00342 array<Int> components;
00343 for(Int v=0; v<dof(); v++)
00344 if (variableUnitType(v) == Angle)
00345 components.push_back(v);
00346 jointTrajectory.convertComponentUnits(components, units);
00347 }
00348
00349
00350 virtual void serialize(base::Serializer& s)
00351 { s(links,"links"); computeVariables(); if (s.isInput()) dirtyHash(); }
00352
00353
00354 virtual bool formatSupported(const String format, Real version = 1.0, ExternalizationType type = IO) const
00355 { return ( (format=="xml") && (version==1.0) ); }
00356 virtual void externalize(base::Externalizer& e, String format = "", Real version = 1.0);
00357 virtual void externalize(base::Externalizer& e, String format = "", Real version = 1.0) const
00358 { Externalizable::externalize(e, format, version); }
00359
00360
00361 virtual base::array<base::Byte> hashCode() const;
00362
00363 protected:
00364 typedef base::array<Link> LinkArray;
00365
00366
00367
00368
00369 typedef base::array<std::pair<Int,Int> > VariableIndexArray;
00370
00371 KinematicChain(const LinkArray& la)
00372 : links(la), hashDirty(true) { computeVariables(); }
00373
00374 void computeVariables();
00375
00376 LinkArray links;
00377 VariableIndexArray variables;
00378
00379
00380 static bool KinematicEvaluatorInitialized;
00381 static ref<KinematicEvaluator> defaultKinematicEvaluator;
00382
00383 ref<KinematicEvaluator> kinematicEvaluator;
00384
00385 String initialFrame;
00386
00387 mutable bool hashDirty;
00388 mutable array<base::Byte> hash;
00389 void dirtyHash() const { hashDirty=true; }
00390
00391 void initKinematicEvaluator();
00392
00393 };
00394
00395
00396
00397 std::ostream& operator<<(std::ostream& out, const robot::KinematicChain::Link& l);
00398
00399 inline std::ostream& operator<<(std::ostream& out, const robot::KinematicChain& c)
00400 {
00401 out << "KinematicChain link parameters: ({} marks variable) - " << c.dof() << "-dof" << std::endl;
00402 for(Int i=0; i<c.size(); i++)
00403 out << i << " - " << c[i];
00404 return out;
00405 }
00406
00407
00408
00409
00410 }
00411
00412 #endif