Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

robot/PlatformDescription.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002   Copyright (C)2003 David Jung <opensim@pobox.com>
00003 
00004   This program/file is free software; you can redistribute it and/or modify
00005   it under the terms of the GNU General Public License as published by
00006   the Free Software Foundation; either version 2 of the License, or
00007   (at your option) any later version.
00008   
00009   This program is distributed in the hope that it will be useful,
00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012   GNU General Public License for more details. (http://www.gnu.org)
00013   
00014   You should have received a copy of the GNU General Public License
00015   along with this program; if not, write to the Free Software
00016   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017   
00018   $Id: PlatformDescription.cpp 1039 2004-02-11 20:50:52Z jungd $
00019   $Revision: 1.6 $
00020   $Date: 2004-02-11 15:50:52 -0500 (Wed, 11 Feb 2004) $
00021   $Author: jungd $
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     // currently we don't extract the rotation components from platformTransform 
00054     //  to use as static transforms in the chain, so give a warning if these
00055     //  components are not 0 in the initial platformTransform
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));  // first dof translates along x-axis
00064     chain += KinematicChain::Link(Vector3(0,1,0),platformTransform(2,4));  // second dof translates along y-axis
00065     Matrix4 translateZAxis; translateZAxis.setToTranslation(Vector3(0,0,platformTransform(3,4)));
00066     chain += KinematicChain::Link(translateZAxis);  // static translation along z-axis
00067     Orient r(platformRot); r.changeRepresentation(Orient::EulerZYXs);
00068     Real rotAboutZAxis = r[0];
00069     chain += KinematicChain::Link(KinematicChain::Link::Revolute, 0,0,0,rotAboutZAxis); // third dof rotates about z-axis
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) { // 2D x-y positioned platform with theta rot about Z (up)
00094   
00095     if (base::equals(q,qp)) return 0; // special case 
00096   
00097     Real theta = q[2];
00098     Vector dP(2);  // delta change in platform origin between states q and qp
00099     dP = vectorRange(qp,Range(0,2)) - vectorRange(q,Range(0,2)); 
00100     Real dtheta = qp[2] - q[2];
00101     
00102     Vector dN(2); // get delta N (center of steeting rotation) from delta platform center P
00103     dN[0] = dP[0] + (L()-W())*dtheta*sin(theta);
00104     dN[1] = dP[1] + (L()-W())*dtheta*cos(theta);
00105     
00106     // world to platform frame (2D)
00107     Real a = theta;//+consts::Pi;
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 //Debugln(DJ,"sa=" << Math::radToDeg(sa) << " pdN=" << pdN << " dN=" << dN << " theta=" << Math::radToDeg(theta));
00115 //!!! finish    
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()) { // currently, only the non-holonomic platform has any parameters
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 { // input
00164 //!!! link handling??
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 }

Generated on Thu Jul 29 15:56:37 2004 for OpenSim by doxygen 1.3.6