1 /*
2  *_________________________________________________________________________*
3  *      POEMS: PARALLELIZABLE OPEN SOURCE EFFICIENT MULTIBODY SOFTWARE     *
4  *      DESCRIPTION: SEE READ-ME                                           *
5  *      FILE NAME: joint.cpp                                              *
6  *      AUTHORS: See Author List                                           *
7  *      GRANTS: See Grants List                                            *
8  *      COPYRIGHT: (C) 2005 by Authors as listed in Author's List          *
9  *      LICENSE: Please see License Agreement                              *
10  *      DOWNLOAD: Free at www.rpi.edu/~anderk5                             *
11  *      ADMINISTRATOR: Prof. Kurt Anderson                                 *
12  *                     Computational Dynamics Lab                          *
13  *                     Rensselaer Polytechnic Institute                    *
14  *                     110 8th St. Troy NY 12180                           *
15  *      CONTACT:        anderk5@rpi.edu                                    *
16  *_________________________________________________________________________*/
17 
18 
19 #include "joints.h"
20 #include "body.h"
21 #include "point.h"
22 #include <string>
23 #include "matrixfun.h"
24 #include "fastmatrixops.h"
25 #include <iomanip>
26 
27 using namespace std;
28 
Joint()29 Joint::Joint(){
30   body1 = body2 = 0;
31   point1 = point2 = 0;
32   pk_C_ko.Identity();
33   pk_C_k.Identity();
34 }
35 
~Joint()36 Joint::~Joint(){
37 }
38 
SetBodies(Body * b1,Body * b2)39 void Joint::SetBodies(Body* b1, Body* b2){
40   body1 = b1;
41   body2 = b2;
42 }
43 
SetPoints(Point * p1,Point * p2)44 void Joint::SetPoints(Point* p1, Point* p2){
45   point1 = p1;
46   point2 = p2;
47 }
48 
GetBodyID1()49 int Joint::GetBodyID1(){
50   return body1->GetID();
51 }
52 
GetBodyID2()53 int Joint::GetBodyID2(){
54   return body2->GetID();
55 }
56 
GetPointID1()57 int Joint::GetPointID1(){
58   return point1->GetID();
59 }
60 
GetPointID2()61 int Joint::GetPointID2(){
62   return point2->GetID();
63 }
64 
ReadIn(std::istream & in)65 bool Joint::ReadIn(std::istream& in){
66   in >>setprecision(20)>> qo >> setprecision(20)>>qdoto >> setprecision(20)>>pk_C_ko;
67   q = qo;
68   qdot = qdoto;
69   EP_Normalize(q);
70 
71   return ReadInJointData(in);
72 }
73 
ResetQdot()74 void Joint::ResetQdot(){
75   //EP_Derivatives(q,u,qdot);
76   qdot_to_u(q,u,qdot);
77 }
78 
ResetQ()79 void Joint::ResetQ(){
80   EP_Normalize(q);
81 }
82 
SetInitialState(ColMatrix & a,ColMatrix & adot)83 void Joint::SetInitialState(ColMatrix& a, ColMatrix& adot){
84   if( (qo.GetNumRows() != a.GetNumRows()) || (qdoto.GetNumRows() != adot.GetNumRows()) ){
85     cout<<qo.GetNumRows()<<"  "<<a.GetNumRows()<<" "<<qdoto.GetNumRows()<<" "<<adot.GetNumRows()<<endl;
86     cerr << "ERROR::Illegal matrix size for initial condition" << endl;
87     exit(1);
88   }
89   qo = a;
90   qdoto = adot;
91   EP_Normalize(qo);
92   q=qo;           //////////////////////////Check this ...added May 14 2005
93   qdot=qdoto;     //////////////////////////Check this ...added May 14 2005
94 }
95 
SetZeroOrientation(VirtualMatrix & C)96 void Joint::SetZeroOrientation(VirtualMatrix& C){
97   pk_C_ko = C;
98 }
99 
100 
WriteOut(std::ostream & out)101 void Joint::WriteOut(std::ostream& out){
102   out << GetType() << ' ' << GetName() << ' ';
103   out << GetBodyID1() << ' ' << GetBodyID2() << ' ';
104   out << GetPointID1() << ' ' << GetPointID2() << endl;
105   out <<setprecision(16)<< qo <<setprecision(16)<< qdoto <<setprecision(16)<< pk_C_ko;
106   WriteOutJointData(out);
107   out << endl;
108 }
109 
GetQ()110 ColMatrix* Joint::GetQ(){
111   return &q;
112 }
113 
GetU()114 ColMatrix* Joint::GetU(){
115   return &u;
116 }
117 
GetQdot()118 ColMatrix* Joint::GetQdot(){
119   return &qdot;
120 }
121 
GetUdot()122 ColMatrix* Joint::GetUdot(){
123   return &udot;
124 }
125 
GetQdotdot()126 ColMatrix* Joint::GetQdotdot(){
127   return &qdotdot;
128 }
129 
130 
DimQandU(int i)131 void Joint::DimQandU(int i){
132   DimQandU(i,i);
133 }
134 
DimQandU(int i,int j)135 void Joint::DimQandU(int i, int j){
136   qo.Dim(i);
137   q.Dim(i);
138   qdot.Dim(i);
139   qdoto.Dim(i);
140   uo.Dim(j);
141   u.Dim(j);
142   udot.Dim(j);
143   qdotdot.Dim(i);
144 
145   // zero them
146   qo.Zeros();
147   qdoto.Zeros();
148   q.Zeros();
149   qdot.Zeros();
150   uo.Zeros();
151   u.Zeros();
152   udot.Zeros();
153   qdotdot.Zeros();
154 
155 }
156 
GetBody1()157 Body* Joint::GetBody1(){
158   return body1;
159 }
160 
GetBody2()161 Body* Joint::GetBody2(){
162   return body2;
163 }
164 
OtherBody(Body * body)165 Body* Joint::OtherBody(Body* body){
166   if(body1 == body) return body2;
167   if(body2 == body) return body1;
168   return 0;
169 }
170 
GetR12()171 Vect3* Joint::GetR12(){
172   return &r12;
173 }
174 
GetR21()175 Vect3* Joint::GetR21(){
176   return &r21;
177 }
178 
Get_pkCk()179 Mat3x3* Joint::Get_pkCk(){
180   return &pk_C_k;
181 }
182 
183 
Get_kCpk()184 Mat3x3* Joint::Get_kCpk(){
185   return &k_C_pk;
186 }
187 
GetForward_sP()188 Matrix Joint::GetForward_sP(){
189   cerr << "ERROR: Forward Spatial Partial Velocity is not supported for joint type " << GetType() << endl;
190   exit(0);
191 }
192 
GetBackward_sP()193 Matrix Joint::GetBackward_sP(){
194   cerr << "ERROR: Backward Spatial Partial Velocity is not supported for joint type " << GetType() << endl;
195   exit(0);
196 }
197 
UpdateForward_sP(Matrix & sP)198 void Joint::UpdateForward_sP(Matrix& sP){
199   cerr << "WARNING: Using default Update sP procedure" << endl;
200   sP = GetForward_sP();
201 }
202 
UpdateBackward_sP(Matrix & sP)203 void Joint::UpdateBackward_sP(Matrix& sP){
204   cerr << "WARNING: Using default Update sP procedure" << endl;
205   sP = GetBackward_sP();
206 }
207 
ComputeForwardTransforms()208 void Joint::ComputeForwardTransforms(){
209   ComputeLocalTransform();
210 //  k_C_pk = T(pk_C_k);
211   FastAssignT(pk_C_k, k_C_pk);
212   ComputeForwardGlobalTransform();
213 }
214 
ComputeBackwardTransforms()215 void Joint::ComputeBackwardTransforms(){
216   ComputeLocalTransform();
217   // k_C_pk = pk_C_k^T
218   FastAssignT(pk_C_k, k_C_pk);
219   ComputeBackwardGlobalTransform();
220 }
221 
ComputeForwardGlobalTransform()222 void Joint::ComputeForwardGlobalTransform(){
223   // body2->n_C_k = body1->n_C_k * pk_C_k;
224   FastMult(body1->n_C_k,pk_C_k,body2->n_C_k);
225   }
226 
ComputeBackwardGlobalTransform()227 void Joint::ComputeBackwardGlobalTransform(){
228   // body1->n_C_k = body2->n_C_k * T(pk_C_k);
229   FastMultT(body2->n_C_k,pk_C_k,body1->n_C_k);
230 }
231 
232 
233 //
234 // global joint functions
235 //
236 
NewJoint(int type)237 Joint* NewJoint(int type){
238   switch( JointType(type) )
239   {
240     case FREEBODYJOINT : return new FreeBodyJoint;
241     case REVOLUTEJOINT : return new RevoluteJoint;
242     case PRISMATICJOINT : return new PrismaticJoint;
243     case SPHERICALJOINT : return new SphericalJoint;
244    case BODY23JOINT : return new Body23Joint;
245    case MIXEDJOINT : return new MixedJoint;
246     default : return 0; // error
247   }
248 }
249