MAMBO logo MAMBO & the MAMBO Toolbox MAMBO logo

Sample project - Bicycle

To illustrate
  • the procedure for finding values for the state variables that satisfy all configuration constraints;
  • the occurrence of singularities in the kinematic differential equations.

This Mambo project contains a non-stationary bicycle and a stationary plane. The non-stationary bicycle may be repositioned and reoriented in four independent steps, namely
  1. Position and orient the rear wheel relative to the world observer.
  2. Orient the bicycle frame relative to the rear wheel.
  3. Orient the steering column relative to the frame.
  4. Orient the front wheel relative to the steering column.
The motion of the bicycle is constrained so as to guarantee rolling contact without slipping on the plane provided that initial conditions result in tangential contact between the plane and the wheels at the points Prear and Pfront.

R: scaling factor corresponding to the radius of the wheels.

markers: radius of two spheres placed on the rim of the two wheels at the points Prear and Pfront.

q1, q2, and q3: coordinates of the center of the rear wheel relative to a coordinate system with origin at the reference point of the world observer and axes parallel to the basis vectors in the reference triad of the world observer.

q4, q5, and q6: 3-1-3 sequence of Euler angles corresponding to the orientation of the rear wheel relative to the reference triad of the world observer.

q7, q8, and q9: angles that describe the orientation of the frame relative to the rear wheel, the steering column relative to the frame, and the front wheel relative to the steering column, respectively.

q10 and q11: angles that describe the location of the points Prear and Pfront on the rim of the rear and front wheel, respectively.

  • Use the default initial conditions and experiment with different assignments in the bicycle.dyn file of the insignals to generate different allowable motions of the bicycle.
  • Attempt to identify the singularities that occur for different allowable motions of the bicycle.
  • Find additional choices of initial conditions that approximately satisfy the condition on tangential contact between the wheels and the plane at the points Prear and Pfront. Study the subsequent motion and comment on its validity.
  • Use the MAMBO toolbox to improve the accuracy in the initial conditions and compare the resulting motion with that obtained in the previous task.

bicycle.zip (zip file, 26 kb, December 30, 2012)
This zip archive contains MAMBO and the MAMBO toolbox source files to visualize the MAMBO project and regenerate visualization files using maple 16, mupad 5.6.0 (matlab R2011a), and mathematica 8.0 versions of the code found below.


Click here to expand/contract!
>Restart():

Click here to expand/contract!
>DeclareObservers(W,Arear,Afront,Aframe,Asteer):
>DeclarePoints(W,Arear,Afront,Aframe,Asteer):
>DeclareTriads(w,arear,afront,aframe,asteer):
>DefineObservers([W,W,w],[Arear,Arear,arear],[Afront,Afront,afront],[Aframe,Aframe,aframe],[Asteer,Asteer,asteer]):
>DefinePoints([W,Aframe,w,q1,q2,q3]):
>DefineTriads([w,aframe,[q4,3],[q5,1],[q6,3]]):
>DefinePoints([Aframe,Arear,NullVector()]):
>DefineTriads([aframe,arear,[q7,3]]):
>v:=MakeTranslations(aframe,p1,p2,0):
>aframe1:=MakeTranslations(aframe,1):
>aframe2:=MakeTranslations(aframe,2):
>aframe3:=MakeTranslations(aframe,3):
>b1:=(1/VectorLength(v)) &** v:
>b2:=(1/VectorLength(aframe3 &xx b1)) &** (aframe3 &xx b1):
>b3:=b1 &xx b2:
>DefineTriads([aframe,asteer,[Matrix(3,3,(i,j)->cat(aframe,i) &oo cat(b,j))],[q8,1]]):
>DefinePoints([Aframe,Asteer,[aframe,p3,p4,0],[asteer,p5,p6,0]]):
>DefinePoints([Asteer,Afront,NullVector()]):
>DefineTriads([asteer,afront,q9,3]):
>DefineNeighbors([W,Arear],[Arear,Aframe],[Aframe,Asteer],[Asteer,Afront]):

Click here to expand/contract!
>DefineObjects([W,'Block',xlength=50,ylength=50,zlength=.01,point=MakeTranslations(w,0,0,.005),color="{.7,.7,.7}"]): #Background
>DefineObjects(
   seq([Arear,'Block',point=MakeTranslations(arear,-.18*sin(1/6*Pi*(i-1))*R,.18*cos(1/6*Pi*(i-1))*R,0),orient=MakeRotations(2*Pi/12*(i-1),3),xlength=1.55*R,ylength=.025*R,zlength=.15*R,color="{.5,.5,0}"],i=1..12),
   [Arear,'Sphere',point=MakeTranslations(arear,R*cos(q10),R*sin(q10),0),radius=marker*R,color=white],
   [Arear,'Cylinder',radius=R,length=.1*R,color=blue],
   [Arear,'Cylinder',radius=.9*R,length=.11*R,color=white],
   [Arear,'Cylinder',radius=.85*R,length=.12*R,color=blue],
   [Arear,'Cylinder',radius=.8*R,length=.13*R,color=black],
   [Arear,'Cylinder',radius=.2*R,length=.2*R,color=cyan],
   seq([Afront,'Block',point=MakeTranslations(afront,-.18*sin(1/6*Pi*(i-1))*R,.18*cos(1/6*Pi*(i-1))*R,0),orient=MakeRotations(2*Pi/12*(i-1),3),xlength=1.55*R,ylength=.025*R,zlength=.15*R,color="{.5,.5,0}"],i=1..12),
   [Afront,'Sphere',point=MakeTranslations(afront,R*cos(q11),R*sin(q11),0),radius=marker*R,color=white],
   [Afront,'Cylinder',radius=R,length=.1*R,color=blue],
   [Afront,'Cylinder',radius=.9*R,length=.11*R,color=white],
   [Afront,'Cylinder',radius=.85*R,length=.12*R,color=blue],
   [Afront,'Cylinder',radius=.8*R,length=.13*R,color=black],
   [Afront,'Cylinder',radius=.2*R,length=.2*R,color=cyan]): #Wheels
>DefineObjects(
   [Asteer,'Block',point=MakeTranslations(asteer,1.645481235*R,.2*R,0),xlength=R,ylength=.08*R,zlength=.08*R,color=cyan],
   [Asteer,'Cylinder',point=MakeTranslations(asteer,2.145481235*R,.2*R,0),radius=.07*R,length=1.5*R,color=cyan],
   [Asteer,'Cylinder',point=MakeTranslations(asteer,2.145481235*R,.2*R,.75*R),radius=.1*R,length=.5*R,color=blue],
   [Asteer,'Cylinder',point=MakeTranslations(asteer,2.145481235*R,.2*R,-.75*R),radius=.1*R,length=.5*R,color=blue],
   [Asteer,'Block',point=MakeTranslations(asteer,1.145481235*R,.2*R,0),xlength=.08*R,ylength=.08*R,zlength=.5*R,color=cyan],
   [Asteer,'Block',xlength=1.164914442*R,ylength=.08*R,zlength=.08*R,color=cyan,point=MakeTranslations(asteer,.572740268*R,.1*R,.165*R),orient=Matrix([[.9833173105,-.1719972364,-.5919475095e-1],[.1716864285,.9850974324,-.1033535693e-1],[.6009024996e-1,0,.9981929490]])],
   [Asteer,'Block',xlength=1.164914442*R,ylength=.08*R,zlength=.08*R,color=cyan,point=MakeTranslations(asteer,.572740268*R,.1*R,-.165*R),orient=Matrix([[.9833173105,-.1719972364,.5919475095e-1],[.1716864285,.9850974324,.1033535693e-1],[-.6009024996e-1,0,.9981929490]])]): #Steering
>DefineObjects(
   [Aframe,'Block',point=MakeTranslations(aframe,7/10*R,0,1/8*R),orient=Matrix([[28/809*sqrt(809),0,5/809*sqrt(809)],[0,1,0],[-5/809*sqrt(809),0,28/809*sqrt(809)]]),xlength=1/20*sqrt(809)*R,ylength=.05*R,zlength=.04*R,color=green],
   [Aframe,'Block',point=MakeTranslations(aframe,7/10*R,0,-1/8*R),orient=Matrix([[28/809*sqrt(809),0,-5/809*sqrt(809)],[0,1,0],[5/809*sqrt(809),0,28/809*sqrt(809)]]),xlength=1/20*sqrt(809)*R,ylength=.05*R,zlength=.04*R,color=green],
   [Aframe,'Block',point=MakeTranslations(aframe,9/8*R,17/40*sqrt(3)*R,0),orient=Matrix([[11/494*sqrt(247),17/494*sqrt(3)*sqrt(247), 0],[-17/494*sqrt(3)*sqrt(247),11/494*sqrt(247),0],[0,0,1]]),xlength=1/10*sqrt(247)*R,ylength=.08*R,zlength=.13*R,color=green],
   [Aframe,'Block',point=MakeTranslations(aframe,17/40*R,17/40*sqrt(3)*R,1/8*R),orient=Matrix([[17/1181*sqrt(1181),-1/2*sqrt(3),5/2362*sqrt(1181)],[17/1181*sqrt(3)*sqrt(1181),1/2,5/2362*sqrt(3)*sqrt(1181)],[-5/1181*sqrt(1181),0,34/1181*sqrt(1181)]]),xlength=1/20*sqrt(1181)*R,ylength=.08*R,zlength=.04*R,color=green],
   [Aframe,'Block',point=MakeTranslations(aframe,17/40*R,17/40*sqrt(3)*R,-1/8*R),orient=Matrix([[17/1181*sqrt(1181),-1/2*sqrt(3),-5/2362*sqrt(1181)],[17/1181*sqrt(3)*sqrt(1181),1/2,-5/2362*sqrt(3)*sqrt(1181)],[5/1181*sqrt(1181),0,34/1181*sqrt(1181)]]),xlength=1/20*sqrt(1181)*R,ylength=.08*R,zlength=.04*R,color=green],
   [Aframe,'Block',point=MakeTranslations(aframe,17/10*R,17/20*sqrt(3)*R,0),xlength=17/10*R,ylength=.08*R,zlength=.13*R,color=green],
   [Aframe,'Block',point=MakeTranslations(aframe,7/5*R+7/16*sqrt(2)*R,7/16*sqrt(2)*R,0),orient=Matrix([[1/2*sqrt(2),-1/2*sqrt(2),0],[1/2*sqrt(2),1/2*sqrt(2),0],[0,0,1]]),xlength=7/4*R,ylength=.08*R,zlength=.13*R,color=green],
   [Aframe,'Block',point=MakeTranslations(aframe,79/40*R+7/16*sqrt(2)*R,17/40*sqrt(3)*R+7/16*sqrt(2)*R,0),orient=Matrix([[-1/2*(-46+35*sqrt(2))/(sqrt(2621-805*sqrt(2)-595*sqrt(3)*sqrt(2))),-1/2*(34*sqrt(3)-35*sqrt(2))/(sqrt(2621-805*sqrt(2)-595*sqrt(3)*sqrt(2))),0],[1/2*(34*sqrt(3)-35*sqrt(2))/(sqrt(2621-805*sqrt(2)-595*sqrt(3)*sqrt(2))),-1/2*(-46+35*sqrt(2))/(sqrt(2621-805*sqrt(2)-595*sqrt(3)*sqrt(2))),0],[0,0,1]]),xlength=1/2*R,ylength=.13*R,zlength=.13*R,color=green],
   [Aframe,'Block',point=MakeTranslations(aframe,.85*R,.85*sqrt(3)*R+.2*R,0),xlength=.8*R,ylength=.2*R,zlength=.25*R,color=magenta]):

Click here to expand/contract!
>DeclarePoints(Prear,Pfront):
>DefinePoints([Arear,Prear,arear,R*cos(q10),R*sin(q10),0],[Afront,Pfront,afront,R*cos(q11),R*sin(q11),0]):
>f1:=simplify(FindTranslation(Arear,Prear) &oo (MakeTranslations(w,3) &xx MakeTranslations(arear,3)))=0:
>f2:=FindTranslation(W,Prear) &oo MakeTranslations(w,3)=0:
>f3:=simplify(FindTranslation(Afront,Pfront) &oo (MakeTranslations(w,3) &xx MakeTranslations(afront,3)))=0:
>f4:=FindTranslation(W,Pfront) &oo MakeTranslations(w,3)=0:
>DeclareStates(seq(cat(q,i),i=1..11)):
>kde:=DiffTime({f1,f3}) union {seq((LinearVelocity(W,Arear) &++ (AngularVelocity(w,arear) &xx FindTranslation(Arear,Prear))) &oo MakeTranslations(w,i)=0,i=1..3), seq((LinearVelocity(W,Afront) &++ (AngularVelocity(w,afront) &xx FindTranslation(Afront,Pfront))) &oo MakeTranslations(w,i)=0,i=1..3)} union {q5t=u1,q7t=u2,q8t=u3}:

Click here to expand/contract!
>GeometryOutput(main=W,states=[q1=0,q2=0,q3=.4207354924,q4=0,q5=1,q6=.1280053714e-1,q7=0,q8=.7,q9=0,q10=-1.583596864,q11=3.288069682],parameters=[p1=-.348968837,p2 =.937134317,p3=1.296859217,p4=.6774200135,p5=-.7601008180,p6=-.10,R=.5,marker=.2],checkargs,checktree,filename="bicycle.geo"):
>MotionOutput(ode=kde,states=[q1=0,q2=0,q3=.4207354924,q4=0,q5=1,q6=.1280053714e-1,q7=0,q8=.7,q9=0,q10=-1.583596864,q11=3.288069682],parameters=[p1=-.348968837,p2 =.937134317,p3=1.296859217,p4=.6774200135,p5 =-.7601008180,p6=-.10,R=.5,marker=.2],insignals=[u1=.5*cos(t),u2=-1.3+1*cos(t),u3=-.5*exp(-t)+.3*cos(t)*(1-exp(-t))],checkargs,checksings,filename="bicycle.dyn");

Sample projects