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/PlatformDescription>
00026
00027 #include <base/Externalizer>
00028 #include <base/Matrix>
00029 #include <base/Matrix4>
00030
00031 #include <cstdio>
00032
00033 using robot::PlatformDescription;
00034
00035 using base::Externalizer;
00036 using base::Expression;
00037 using base::Matrix;
00038 using base::Matrix4;
00039 using base::ExpressionMatrix;
00040 using base::dom::DOMNode;
00041 using base::dom::DOMElement;
00042 using robot::KinematicChain;
00043
00044
00045 KinematicChain PlatformDescription::getKinematicChain(Int platformDOF, const base::Matrix4& platformTransform) const
00046 {
00047 KinematicChain chain;
00048 if ((platformDOF == 0) || (!isMobile())) {
00049 chain += KinematicChain::Link(platformTransform);
00050 }
00051 else if (platformDOF == 3) {
00052
00053
00054
00055
00056 Matrix3 platformRot(platformTransform);
00057
00058 if (!platformRot.equals(Matrix3().setIdentity())) {
00059
00060 Logln("warning: an initial non-zero orientation isn't well tested for the 3-dof platform KinematicChain");
00061 }
00062
00063 chain += KinematicChain::Link(Vector3(1,0,0),platformTransform(1,4));
00064 chain += KinematicChain::Link(Vector3(0,1,0),platformTransform(2,4));
00065 Matrix4 translateZAxis; translateZAxis.setToTranslation(Vector3(0,0,platformTransform(3,4)));
00066 chain += KinematicChain::Link(translateZAxis);
00067 Orient r(platformRot); r.changeRepresentation(Orient::EulerZYXs);
00068 Real rotAboutZAxis = r[0];
00069 chain += KinematicChain::Link(KinematicChain::Link::Revolute, 0,0,0,rotAboutZAxis);
00070 r[0]=0;
00071 chain += KinematicChain::Link(r.getRotationMatrix3());
00072 }
00073 else if (platformDOF == 6) {
00074 Unimplemented;
00075 }
00076 else
00077 throw std::invalid_argument(Exception("unsuported platformDOF"));
00078 return chain;
00079 }
00080
00081
00082
00083 Real PlatformDescription::requiredSteeringAngle(const Vector& q, const Vector& qp) const
00084 {
00085 Assert(q.size() == qp.size());
00086
00087 Real dof=q.size();
00088
00089 if ((dof==0) || (!isMobile())) return 0;
00090
00091 Assert((dof == 3) || (dof == 6));
00092
00093 if (dof == 3) {
00094
00095 if (base::equals(q,qp)) return 0;
00096
00097 Real theta = q[2];
00098 Vector dP(2);
00099 dP = vectorRange(qp,Range(0,2)) - vectorRange(q,Range(0,2));
00100 Real dtheta = qp[2] - q[2];
00101
00102 Vector dN(2);
00103 dN[0] = dP[0] + (L()-W())*dtheta*sin(theta);
00104 dN[1] = dP[1] + (L()-W())*dtheta*cos(theta);
00105
00106
00107 Real a = theta;
00108 Matrix T(2,2);
00109 T(0,0) = cos(a); T(0,1) = -sin(a);
00110 T(1,0) = sin(a); T(1,1) = cos(a);
00111 Vector pdN( T*dN );
00112
00113 Real sa = (base::equals(pdN[1],0))?consts::Pi : atan(pdN[0]/pdN[1]);
00114
00115
00116 return sa;
00117 }
00118 else if (dof == 6) {
00119 Unimplemented;
00120 }
00121
00122 return 0;
00123 }
00124
00125
00126
00127
00128 void PlatformDescription::externalize(base::Externalizer& e, String format, Real version)
00129 {
00130 if (format == "") format = "xml";
00131
00132 if (!formatSupported(format,version,e.ioType()))
00133 throw std::invalid_argument(Exception(String("format ")+format+" v"+base::realToString(version)+" unsupported"));
00134
00135 if (e.isOutput()) {
00136
00137 DOMElement* platfElem = e.createElement("platform");
00138 e.setElementAttribute(platfElem,"name", getName() );
00139 e.setElementAttribute(platfElem,"mobile", isMobile()?"true":"false" );
00140 e.setElementAttribute(platfElem,"holonomic", isHolonomic()?"true":"false" );
00141
00142 DOMElement* dimElem = e.createElement("dimensions",false);
00143 e.appendText(dimElem, e.toString(dimensions()) );
00144 e.appendNode(platfElem, dimElem);
00145 e.appendBreak(platfElem);
00146
00147 DOMElement* offsetElem = e.createElement("originoffset",false);
00148 e.appendText(offsetElem, e.toString(originOffset()) );
00149 e.appendNode(platfElem, offsetElem);
00150 e.appendBreak(platfElem);
00151
00152 if (!isHolonomic()) {
00153 DOMElement* paramsElem = e.createElement("params",false);
00154 e.setElementAttribute(paramsElem, "L", base::realToString(L()));
00155 e.setElementAttribute(paramsElem, "W", base::realToString(W()));
00156 e.appendNode(platfElem, paramsElem);
00157 e.appendBreak(platfElem);
00158 }
00159
00160
00161 e.appendElement(platfElem);
00162
00163 } else {
00164
00165 DOMNode* context = e.context();
00166
00167 DOMElement* platfElem = e.getFirstElement(context, "platform");
00168
00169 setName( e.getDefaultedElementAttribute(platfElem, "name", "platform") );
00170 setMobile( e.getDefaultedElementAttribute(platfElem, "mobile", "false") == "true" );
00171 setHolonomic( e.getDefaultedElementAttribute(platfElem, "holonomic", "false") == "true" );
00172
00173 DOMElement* dimElem = e.getFirstChildElement(platfElem, "dimensions");
00174 String dimText = e.getContainedText(dimElem);
00175 setDimensions( e.toVector3(dimText) );
00176
00177 DOMElement* offsetElem = e.getFirstChildElement(platfElem, "originoffset",false);
00178 if (offsetElem) {
00179 String offsetText = e.getContainedText(offsetElem);
00180 setOriginOffset( e.toVector3(offsetText) );
00181 }
00182 else
00183 setOriginOffset( Vector3() );
00184
00185 DOMElement* paramsElem = e.getFirstChildElement(platfElem, "params",false);
00186 if (paramsElem) {
00187 setL( base::stringToReal(e.getDefaultedElementAttribute(paramsElem, "L", "0.0")) );
00188 setW( base::stringToReal(e.getDefaultedElementAttribute(paramsElem, "W", "0.0")) );
00189 }
00190
00191
00192 e.removeElement(platfElem);
00193
00194 }
00195 }