16 def steeringGamma .2
\r
17 def leftSteeringAngle atan2(2 * robotLength * steeringGamma, 2 - robotWidth * steeringGamma)
\r
18 def rightSteeringAngle atan2(2 * robotLength * steeringGamma, 2 + robotWidth * steeringGamma)
\r
20 def wheelRad tireRad - cornerRad
\r
21 def wheelXofs wheelWidth/2 - cornerRad
\r
24 translate([ wheelXofs, wheelRad, 0])
\r
25 } sweep { nArcSegs, rotate(90 / nArcSegs) } (cornerRad,0)
\r
28 translate([-wheelXofs, wheelRad, 0])
\r
29 } sweep { nArcSegs, rotate(90 / nArcSegs) } (0,cornerRad)
\r
31 def tread line(wheelXofs, tireRad)(-wheelXofs, tireRad)
\r
33 def hubPlate sweep[fillcolor=lightgray] { nTireSegs<>, rotate(-360 / nTireSegs, (O), [I]) } (0,wheelRad)
\r
35 def tire sweep[fillcolor=lightgray]{ nTireSegs, rotate(360 / nTireSegs, (O), -[I]) } {
\r
42 def leftHubPlate put { translate( [-wheelWidth/2, 0, 0] ) } {hubPlate}
\r
43 def rightHubPlate put { rotate(180, (O), [K]) } {leftHubPlate}
\r
49 def axle sweep[fillcolor=darkgray]{ nAxleSegs, rotate(360 / nAxleSegs, (O), -[I]) }
\r
50 line (robotWidth/2, axleRad)(-robotWidth/2, axleRad)
\r
52 def leftSteerableWheel put {
\r
53 rotate(leftSteeringAngle, (O), [J]) then
\r
54 translate( [-robotWidth/2, 0, 0] )
\r
57 def rightSteerableWheel put {
\r
58 rotate(rightSteeringAngle, (O), [J]) then
\r
59 translate( [robotWidth/2, 0, 0] )
\r
62 def steerableAxleAssembly {
\r
63 {leftSteerableWheel}
\r
64 {rightSteerableWheel}
\r
68 def fixedAxleAssembly {
\r
69 put { translate( [-robotWidth/2, 0, 0] ) } {wheel}
\r
70 put { translate( [ robotWidth/2, 0, 0] ) } {wheel}
\r
74 def bodyopts [fillcolor=white]
\r
76 def bodyCorner # first octant "rounded corner"
\r
77 sweep [bodyopts]{ nArcSegs, rotate(90 / nArcSegs, (O), [I]) }
\r
78 sweep { nArcSegs, rotate(90 / nArcSegs, (O),-[K]) } (0,cornerRad)
\r
81 sweep [bodyopts] { 1, translate([K]) }
\r
82 sweep { nArcSegs, rotate(90 / nArcSegs, (O), -[K]) } (0,cornerRad,0)
\r
84 def xBodyEdge # positive y-z quadrant about x axis quarter-pipe of unit length
\r
85 sweep [bodyopts] { 1, translate([I]) }
\r
86 sweep { nArcSegs, rotate(90 / nArcSegs, (O), -[I]) } (0,0,cornerRad)
\r
89 def xOfs bodyWidth/2 - cornerRad
\r
90 def yOfs bodyHeight/2 - cornerRad
\r
91 def zOfs robotLength/2 + cornerRad
\r
94 put { translate([ xOfs, yOfs, zOfs]) } {bodyCorner}
\r
95 put { rotate(90, (O), [K]) then
\r
96 translate([-xOfs, yOfs, zOfs]) } {bodyCorner}
\r
97 put { rotate(180, (O), [K]) then
\r
98 translate([-xOfs, -yOfs, zOfs]) } {bodyCorner}
\r
99 put { rotate(270, (O), [K]) then
\r
100 translate([ xOfs, -yOfs, zOfs]) } {bodyCorner}
\r
102 put { scale([2*xOfs, 1, 1]) then
\r
103 translate([-xOfs, yOfs, zOfs]) } {xBodyEdge}
\r
104 put { scale([2*yOfs, 1, 1]) then
\r
105 rotate(90, (O), [K]) then
\r
106 translate([-xOfs,-yOfs, zOfs]) } {xBodyEdge}
\r
107 put { scale([2*xOfs, 1, 1]) then
\r
108 rotate(180, (O), [K]) then
\r
109 translate([ xOfs,-yOfs, zOfs]) } {xBodyEdge}
\r
110 put { scale([2*yOfs, 1, 1]) then
\r
111 rotate(270, (O), [K]) then
\r
112 translate([ xOfs, yOfs, zOfs]) } {xBodyEdge}
\r
113 def z zOfs + cornerRad
\r
114 polygon[bodyopts](xOfs,yOfs,z)(-xOfs,yOfs,z)(-xOfs,-yOfs,z)(xOfs,-yOfs,z)
\r
117 put { scale([1,1,2*zOfs]) then
\r
118 translate([xOfs, yOfs, -zOfs]) } {zBodyEdge}
\r
119 put { scale([1,1,2*zOfs]) then
\r
121 translate([-xOfs, yOfs, -zOfs]) } {zBodyEdge}
\r
123 polygon[bodyopts](xOfs,y,zOfs)(xOfs,y,-zOfs)(-xOfs,y,-zOfs)(-xOfs,y,zOfs)
\r
127 polygon[bodyopts](x,yOfs,zOfs)(x,-yOfs,zOfs)(x,-yOfs,-zOfs)(x,yOfs,-zOfs)
\r
132 put { rotate(180, (O), [I]) } {posZend}
\r
137 # bottom and negative X side
\r
138 put { rotate(180) } {
\r
145 {fixedAxleAssembly}
\r
146 put { translate([0, 0, -robotLength]) } {steerableAxleAssembly}
\r
147 put { translate([0, 0, -robotLength/2]) } {body}
\r
151 translate(robotLength/2 * [K])
\r
152 then rotate(90, (O), [J])
\r
159 def foreshorteningFactor
\r
189 def eyeAxis [10,7,10]
\r
190 def eyeI (O) + .5 * foreshorteningFactor * [eyeAxis]
\r
191 def dvI (O) - (eyeI)
\r
198 def up [0,1,0] then rotate(upRot, (O), -[eyeAxis])
\r
202 view ((eyeI), [dvI], [up])
\r
203 then rotate(-panAngle, (O), [panAxis])
\r
204 then perspective(|[dvI]|)
\r
205 then scale(1.5/winWidth)
\r
206 then scale([1,1,1000])
\r
207 <> view ((eyeI), [dvI], [up])
\r
208 then rotate(-panAngle, (O), [panAxis])
\r
209 then perspective(|[dvI]|)
\r
210 then scale(1.5/winWidth)
\r
213 line[linestyle=dashed](-1,-1, 1)( 1,-1, 1)(1,1, 1)(-1,1, 1)(-1,-1, 1)
\r
214 line[linestyle=dashed](-1,-1,-1)( 1,-1,-1)(1,1,-1)(-1,1,-1)(-1,-1,-1)
\r
215 line[linestyle=dashed](-1,-1, 1)(-1,-1,-1)
\r
216 line[linestyle=dashed]( 1,-1, 1)( 1,-1,-1)
\r
217 line[linestyle=dashed]( 1, 1, 1)( 1, 1,-1)
\r
218 line[linestyle=dashed](-1, 1, 1)(-1, 1,-1)
\r
222 def opts [linewidth=.2pt]
\r
225 def dx (robotLength+tireRad*2) + 2
\r
226 def dz (robotWidth+wheelWidth) + 2
\r
227 def y -tireRad-.001
\r
229 repeat { nX+1, translate([dx/nX,0,0]) } line[opts](-dx/2,y,-dz/2)(-dx/2,y,dz/2)
\r
230 repeat { nZ+1, translate([0,0,dz/nZ]) } line[opts](-dx/2,y,-dz/2)(dx/2,y,-dz/2)
\r
233 put { [[viewXformI]] } {
\r
234 put { [[centerXform]] } {robot}
\r
236 # put { scale([(robotLength+tireRad*2)/2, tireRad, (robotWidth+wheelWidth)/2]) } {dashframe}
\r
240 #put { [[viewXformI]] then translate(-frameOfs * [I]) } {robot}
\r
241 #put { [[viewXformI]] then translate(frameOfs * [I]) } {robot}
\r
242 #put { [[simpleViewXform]] then translate(2*frameOfs * [I]) } {robot}
\r
246 set [linewidth=.3pt]
\r
248 % set up a bounding box
\r
251 def cbp1 (-w,-w/ar,0)
\r
252 def cbp2 (w,w/ar,0)
\r
254 picturebox [.5] (cbp1)(cbp2)
\r