1 @use PhysicalControl.
\r
7 @use SistemaAutonomo.
\r
9 @define CELDAS_MAX_VELOCITY 5.
\r
10 @define CELDAS_TURNO 30.
\r
11 @define CELDAS_SENSOR_THRESHOLD 6.
\r
13 PhysicalControl : CeldasControl {
\r
14 % This class is used for building simple vehicle
\r
15 % simulations. To create a vehicle simulation,
\r
16 % subclass CeldasControl and use the init method to
\r
17 % create OBJECT(CeldasObstacle) and
\r
18 % OBJECT(CeldasVehicle) objects.
\r
22 floorShape (object).
\r
23 cloudTexture (object).
\r
27 self enable-lighting.
\r
28 #self enable-smooth-drawing.
\r
30 floorShape = new Shape.
\r
31 floorShape init-with-cube size (200, .2, 200).
\r
33 floor = new Stationary.
\r
34 floor register with-shape floorShape at-location (0, 0, 0).
\r
35 #floor catch-shadows.
\r
37 self point-camera at (0, 0, 0) from (3, 3, 24).
\r
39 #self enable-shadows.
\r
40 #self enable-reflections.
\r
42 cloudTexture = (new Image load from "images/clouds.png").
\r
43 self set-background-color to (.4, .6, .9).
\r
44 self set-background-texture-image to cloudTexture.
\r
48 MultiBody : CeldasLightVehicle (aka CeldasLightVehicles) {
\r
49 % This object is used in conjunction with OBJECT(CeldasControl) to
\r
50 % create simple vehicles.
\r
54 wheelShape (object).
\r
55 sensorShape (object).
\r
61 bodyShape = new Shape.
\r
62 bodyShape init-with-cube size (4.0, .75, 3.0).
\r
64 wheelShape = new Shape.
\r
65 wheelShape init-with-polygon-disk radius ( self get-wheel-radius ) sides 20 height ( self get-wheel-width ).
\r
68 sensorShape = new Shape.
\r
69 sensorShape init-with-polygon-cone radius .2 sides 5 height .5.
\r
72 bodyShape set-density to ( self get-density ).
\r
73 bodyLink = new Link.
\r
74 bodyLink set-shape to bodyShape.
\r
75 bodyLink set-mu to -1.0.
\r
76 bodyLink set-eT to .8.
\r
78 self set-root to bodyLink.
\r
80 self move to (0, 0.9, 0).
\r
81 self set-texture-scale to 1.5.
\r
86 - to get-wheel-width:
\r
89 - to get-wheel-radius:
\r
92 + section "Adding Wheels and Sensors to a Vehicle"
\r
94 + to add-wheel at location (vector):
\r
95 % Adds a wheel at location on the vehicle. This method returns
\r
96 % the wheel which is created, a OBJECT(CeldasWheel).
\r
98 wheel, joint (object).
\r
100 wheel = new CeldasWheel.
\r
101 wheel set-shape to wheelShape.
\r
103 joint = new RevoluteJoint.
\r
105 joint set-relative-rotation around-axis (1, 0, 0) by 1.5708.
\r
106 joint link parent bodyLink to-child wheel with-normal (0, 0, 1)
\r
107 with-parent-point location with-child-point (0, 0, 0).
\r
109 wheel set-eT to .8.
\r
110 wheel set-texture to 0.
\r
111 wheel set-joint to joint.
\r
112 joint set-strength-limit to (joint get-strength-hard-limit) / 2.
\r
113 wheel set-color to (.6, .6, .6).
\r
114 wheel set-mu to 100000.
\r
116 self add-dependency on joint.
\r
117 self add-dependency on wheel.
\r
119 push wheel onto wheels.
\r
123 + to add-sensor at location (vector) with-direction direction = (0,1,0)(vector) :
\r
124 % Adds a sensor at location on the vehicle. This method returns
\r
125 % the sensor which is created, a OBJECT(CeldasSensor).
\r
127 sensor, joint (object).
\r
129 sensor = new CeldasSensor.
\r
130 sensor set-direction to direction.
\r
132 sensor set-shape to sensorShape.
\r
134 joint = new RevoluteJoint.
\r
136 joint set-relative-rotation around-axis (0, 0, 1) by -1.57.
\r
137 joint link parent bodyLink to-child sensor with-normal (1, 0, 0)
\r
138 with-parent-point location with-child-point (0, 0, 0).
\r
140 joint set-double-spring with-strength 300 with-max 0.01 with-min -0.01.
\r
142 self add-dependency on joint.
\r
143 self add-dependency on sensor.
\r
145 sensor set-color to (0, 0, 0).
\r
147 #push sensor onto sensors.
\r
159 CeldasLightVehicle : CeldasVehicle (aka CeldasVehicles) {
\r
160 % A heavy duty version of OBJECT(CeldasLightVehicle), this
\r
161 % vehicle is heavier and harder to control, but more stable
\r
162 % at higher speeds.
\r
164 lSensor, rSensor, fSensor, bSensor (object).
\r
165 lfWheel,rfWheel,lbWheel,rbWheel (object).
\r
166 tleft,tright (int).
\r
167 avanzando,retrocediendo,girando_izq,girando_der(int).
\r
173 datos-finales (hash).
\r
174 plan-finished (int).
\r
175 posicion-inicial (vector).
\r
176 posicion-final (vector).
\r
181 - to get-wheel-width:
\r
184 - to get-wheel-radius:
\r
187 - to near position thePosition (vector) with-error error (float):
\r
189 vectorAux = (self get-location) - thePosition.
\r
191 #print "-----> (pos, other_pos, diff, error): ", (self get-location), thePosition, vectorAux, error.
\r
193 if ((|vectorAux::x| < error) && (|vectorAux::z| < error)):
\r
198 + to set-global-velocity to velocity (float):
\r
199 rfWheel set-velocity to velocity.
\r
200 lfWheel set-velocity to velocity.
\r
201 rbWheel set-velocity to velocity.
\r
202 lbWheel set-velocity to velocity.
\r
204 + to get-global-velocity:
\r
205 return ((rfWheel get-velocity) + (lfWheel get-velocity)) / 2.
\r
209 self rotate around-axis (0,1,0) by (-1.5709/CELDAS_TURNO)*tright.
\r
211 if (tright == CELDAS_TURNO):
\r
213 fSensor set-direction to (-1,0,0).
\r
214 bSensor set-direction to (1,0,0).
\r
215 lSensor set-direction to (0,0,-1).
\r
216 rSensor set-direction to (0,0,1).
\r
223 self rotate around-axis (0,1,0) by (1.5709/CELDAS_TURNO)*tleft.
\r
225 if (tleft == CELDAS_TURNO):
\r
227 fSensor set-direction to (-1,0,0).
\r
228 bSensor set-direction to (1,0,0).
\r
229 lSensor set-direction to (0,0,-1).
\r
230 rSensor set-direction to (0,0,1).
\r
234 + to get-sensor-value:
\r
235 return (fSensor get-sensor-value).
\r
239 +to update-entorno:
\r
240 entorno{"sensor_f"} = (fSensor get-sensor-value).
\r
241 entorno{"sensor_b"} = (bSensor get-sensor-value).
\r
242 entorno{"sensor_r"} = (rSensor get-sensor-value).
\r
243 entorno{"sensor_l"} = (lSensor get-sensor-value).
\r
244 sa update-entorno with entorno.
\r
247 # Configuracion de robot
\r
248 fSensor = (self add-sensor at (2.0, .4, 0)).
\r
249 fSensor set-direction to (1,0,0).
\r
250 #fSensor set-direction to (0,0,1).
\r
251 fSensor set-id at 1.
\r
252 fSensor set-body at self.
\r
253 bSensor = (self add-sensor at (-2.0, .4, 0)).
\r
254 bSensor set-direction to (-1,0,0).
\r
255 #bSensor set-direction to (0,0,1).
\r
256 bSensor set-id at 2.
\r
257 bSensor set-body at self.
\r
258 lSensor = (self add-sensor at (0, .4, 1.5)).
\r
259 lSensor set-direction to (0,0,1).
\r
260 #lSensor set-direction to (1,0,0).
\r
261 lSensor set-id at 3.
\r
262 lSensor set-body at self.
\r
264 rSensor = (self add-sensor at (0, .4, -1.5)).
\r
265 rSensor set-direction to (0,0,-1).
\r
266 #rSensor set-direction to (-1,0,0).
\r
267 rSensor set-id at 4.
\r
268 rSensor set-body at self.
\r
270 lfWheel = (self add-wheel at (2, 0, -1.5)).
\r
271 lbWheel = (self add-wheel at (-2, 0, -1.5)).
\r
272 rfWheel = (self add-wheel at (2, 0, 1.5)).
\r
273 rbWheel = (self add-wheel at (-2, 0, 1.5)).
\r
281 posicion-inicial = (self get-location).
\r
282 posicion-final = (0, 0, 0).
\r
284 # Configuracion de sistema autonomo
\r
285 sa = new SistemaAutonomo.
\r
286 sa init with-max-pasos 4 with-max-teorias 15.
\r
288 plan-finished = 1. # así planificamos apenas empezamos
\r
290 teorias = 4 new Teorias.
\r
291 teorias{0} init named "Avanzar" with-action "adelante".
\r
292 teorias{0} set-dato-inicial name "sensor_f" value 0.
\r
293 teorias{0} set-dato-inicial name "sensor_b" value ANY.
\r
294 teorias{0} set-dato-inicial name "sensor_r" value ANY.
\r
295 teorias{0} set-dato-inicial name "sensor_l" value ANY.
\r
296 teorias{0} set-dato-inicial name "movido" value ANY.
\r
297 teorias{0} set-dato-final name "sensor_f" value ANY.
\r
298 teorias{0} set-dato-final name "sensor_b" value ANY.
\r
299 teorias{0} set-dato-final name "sensor_r" value ANY.
\r
300 teorias{0} set-dato-final name "sensor_l" value ANY.
\r
301 teorias{0} set-dato-final name "movido" value 1.
\r
303 teorias{1} init named "Retroceder" with-action "atras".# executed 2.
\r
304 teorias{1} set-dato-inicial name "sensor_f" value 1.
\r
305 teorias{1} set-dato-inicial name "sensor_b" value ANY.
\r
306 teorias{1} set-dato-inicial name "sensor_r" value ANY.
\r
307 teorias{1} set-dato-inicial name "sensor_l" value ANY.
\r
308 teorias{1} set-dato-inicial name "movido" value ANY.
\r
309 teorias{1} set-dato-final name "sensor_f" value 0.
\r
310 teorias{1} set-dato-final name "sensor_b" value ANY.
\r
311 teorias{1} set-dato-final name "sensor_r" value ANY.
\r
312 teorias{1} set-dato-final name "sensor_l" value ANY.
\r
313 teorias{1} set-dato-final name "movido" value 1.
\r
315 teorias{2} init named "Rotar a derecha" with-action "derecha".
\r
316 teorias{2} set-dato-inicial name "sensor_f" value 1.
\r
317 teorias{2} set-dato-inicial name "sensor_b" value ANY.
\r
318 teorias{2} set-dato-inicial name "sensor_r" value ANY.
\r
319 teorias{2} set-dato-inicial name "sensor_l" value ANY.
\r
320 teorias{2} set-dato-inicial name "movido" value ANY.
\r
321 teorias{2} set-dato-final name "sensor_f" value 0.
\r
322 teorias{2} set-dato-final name "sensor_b" value ANY.
\r
323 teorias{2} set-dato-final name "sensor_r" value ANY.
\r
324 teorias{2} set-dato-final name "sensor_l" value 1.
\r
325 teorias{2} set-dato-final name "movido" value 0.
\r
327 teorias{3} init named "Rotar a izquierda" with-action "izquierda". # executed 2.
\r
328 teorias{3} set-dato-inicial name "sensor_f" value 1.
\r
329 teorias{3} set-dato-inicial name "sensor_b" value ANY.
\r
330 teorias{3} set-dato-inicial name "sensor_r" value ANY.
\r
331 teorias{3} set-dato-inicial name "sensor_l" value ANY.
\r
332 teorias{3} set-dato-inicial name "movido" value ANY.
\r
333 teorias{3} set-dato-final name "sensor_f" value 0.
\r
334 teorias{3} set-dato-final name "sensor_b" value ANY.
\r
335 teorias{3} set-dato-final name "sensor_r" value 1.
\r
336 teorias{3} set-dato-final name "sensor_l" value ANY.
\r
337 teorias{3} set-dato-final name "movido" value 0.
\r
339 sa add teoria teorias{0}.
\r
340 sa add teoria teorias{1}.
\r
341 sa add teoria teorias{2}.
\r
342 sa add teoria teorias{3}.
\r
344 datos-finales{"movido"} = 1.
\r
345 sa update-datos-finales with datos-finales.
\r
349 # Movimiento del robot
\r
352 self set-global-velocity to (CELDAS_MAX_VELOCITY).
\r
354 if (retrocediendo):
\r
356 self set-global-velocity to (-CELDAS_MAX_VELOCITY).
\r
360 self set-global-velocity to 0.
\r
362 #if (iterate): self rotate around-axis (0,1,0) by (1.570796/CELDAS_TURNO)*iterate.
\r
363 print "izq: ", (1.570796/CELDAS_TURNO)*iterate.
\r
367 self set-global-velocity to 0.
\r
369 #if (iterate): self rotate around-axis (0,1,0) by (-1.570796/CELDAS_TURNO)*iterate.
\r
370 print "der: ", (-1.570796/CELDAS_TURNO)*iterate.
\r
372 #print "vel: ", (bodyLink get-velocity).
\r
374 # Actualiza entorno
\r
375 self update-entorno.
\r
377 # Chequeo de objetivo
\r
378 if (self near position posicion-final with-error 5.0):
\r
380 print "Llegamos al FINAL!!!".
\r
381 self set-global-velocity to 0.
\r
386 if (plan-finished):
\r
388 # Actualiza entorno indicando que no se movió para que
\r
389 # el planificador actue
\r
390 sa set-entorno value 0 with-name "movido".
\r
391 sa plan. # Si no tenemos plan, lo hacemos
\r
394 if (! (sa has-next-theory)):
\r
397 print "El planificador no encuentra PLAN!!!".
\r
402 # Ejecución de teoría
\r
405 posicion-inicial = (self get-location).
\r
406 if (sa has-next-theory):
\r
408 teoria = sa get-next-theory.
\r
409 if ((teoria get-accion) == "adelante"):
\r
416 if ((teoria get-accion) == "atras"):
\r
423 if ((teoria get-accion) == "izquierda"):
\r
430 if ((teoria get-accion) == "derecha"):
\r
444 # Validación de teoría
\r
445 if (iterate == CELDAS_TURNO):
\r
447 # Actualiza entorno segun si se movio o no
\r
448 if (self near position posicion-inicial with-error 1.0):
\r
450 sa set-entorno value 0 with-name "movido".
\r
454 sa set-entorno value 1 with-name "movido".
\r
457 if (!(sa validate theory teoria)):
\r
470 Stationary : CeldasObstacle (aka CeldasObstacles) {
\r
471 % A CeldasObstacle is used in conjunction with OBJECT(CeldasControl)
\r
472 % and OBJECT(CeldasVehicle). It is what the OBJECT(CeldasSensor)
\r
473 % objects on the CeldasVehicle detect.
\r
475 % There are no special behaviors associated with the walls--they're
\r
476 % basically just plain OBJECT(Stationary) objects.
\r
480 direction (vector).
\r
483 + to init with-size theSize = (10, 3, .1) (vector) with-color theColor = (1, 0, 0) (vector) at-location theLocation = (0, 0, 0) (vector) with-rotation theRotation = [ ( 0, 0, 1 ), ( 0, 1, 0 ), ( 1, 0, 0 ) ] (matrix):
\r
484 self init-with-shape shape (new Shape init-with-cube size theSize) color theColor at-location theLocation with-rotation theRotation.
\r
487 + to init-with-shape shape theShape (object) color theColor = (1, 0, 0) (vector) at-location theLocation = (0, 0, 0) (vector) with-rotation theRotation = [ ( 1, 0, 0 ), ( 0, 1, 0 ), ( 0, 0, 1 ) ] (matrix):
\r
488 self register with-shape theShape at-location theLocation with-rotation theRotation.
\r
489 self set-color to theColor.
\r
494 + to set-direction at theDirection (vector):
\r
495 direction=theDirection.
\r
497 + to get-direction:
\r
501 Link : CeldasWheel (aka CeldasWheels) {
\r
502 % A CeldasWheel is used in conjunction with OBJECT(CeldasVehicle)
\r
503 % to build Celdas vehicles. This class is typically not instantiated
\r
504 % manually, since OBJECT(CeldasVehicle) creates one for you when you
\r
505 % add a wheel to the vehicle.
\r
514 - to set-joint to j (object):
\r
519 + section "Configuring the Wheel's Velocity"
\r
521 + to set-velocity to n (float):
\r
522 % Sets the velocity of this wheel.
\r
524 if n > CELDAS_MAX_VELOCITY: n = CELDAS_MAX_VELOCITY.
\r
527 joint set-joint-velocity to velocity.
\r
530 % Gets the velocity of this wheel.
\r
536 Link : CeldasSensor (aka CeldasSensors) {
\r
537 % A CeldasSensor is used in conjunction with OBJECT(CeldasVehicle)
\r
538 % to build Celdas vehicles. This class is typically not instantiated
\r
539 % manually, since OBJECT(CeldasVehicle) creates one for you when you
\r
540 % add a sensor to the vehicle.
\r
543 direction (vector).
\r
544 positiveDirection(vector).
\r
545 sensorAngle (float).
\r
552 direction = (1,0,1).
\r
553 positiveDirection= (1,0,1).
\r
556 draw = new Drawing.
\r
559 + section "Configuring the Sensor Values"
\r
560 + to set-id at n (int):
\r
563 + to set-body at robotBody(object):
\r
566 + to set-sensor-angle to n (float):
\r
567 % Sets the angle in which this sensor can detect obstacles. The default
\r
568 % value of 1.6 means that the sensor can see most of everything in
\r
569 % front of it. Setting the value to be any higher leads to general
\r
570 % wackiness, so I don't suggest it.
\r
574 + to set-direction to n (vector):
\r
576 positiveDirection::x=|n::x|.
\r
577 positiveDirection::y=|n::y|.
\r
578 positiveDirection::z=|n::z|.
\r
580 + section "Getting the Sensor Values"
\r
582 + to get-sensor-value:
\r
583 % Gets the sensor value. This should be used from post-iterate,
\r
584 % if not, the sensor reading correspond to the previous
\r
588 val = self get-data.
\r
589 if (val > CELDAS_SENSOR_THRESHOLD): return 0.
\r
600 wallBegin,wallEnd,wallCenter (float).
\r
602 posObstacle,destiny,yo(vector).
\r
608 foreach i in (all CeldasObstacles):
\r
610 posObstacle=i get-location.
\r
611 v = (body get-location) - (self get-location ).
\r
612 obsLoc::y=posObstacle::y.
\r
614 if (dot((i get-direction),(1,0,0))):
\r
616 obsLoc::x=((self get-location)::x + ((posObstacle::z - (self get-location)::z)*v::x/v::z)).
\r
617 obsLoc::z=posObstacle::z.
\r
621 obsLoc::z=((self get-location)::z + ((posObstacle::x - (self get-location)::x)*v::z/v::x)).
\r
622 obsLoc::x=posObstacle::x.
\r
626 if(dot((i get-direction),direction)==0):
\r
633 if(dot(direction,(1,1,1))<0):
\r
635 if(dot((body get-location),positiveDirection) > dot((self get-location),positiveDirection)):
\r
637 if((dot((self get-location),positiveDirection))>(dot(obsLoc,positiveDirection))):
\r
641 if((dot((self get-location),positiveDirection))<(dot(obsLoc,positiveDirection))):
\r
646 if(dot((body get-location),positiveDirection) < dot((self get-location),positiveDirection)):
\r
648 if((dot((self get-location),positiveDirection))<(dot(obsLoc,positiveDirection))):
\r
652 if((dot((self get-location),positiveDirection))>(dot(obsLoc,positiveDirection))):
\r
658 #Compruebo que el robot este frente a la pared
\r
659 wallCenter=dot((i get-location),(i get-direction)).
\r
660 wallBegin=wallCenter- (i get-large)/2.
\r
661 wallEnd=wallCenter + (i get-large)/2.
\r
664 yo=self get-location.
\r
665 destiny=i get-direction.
\r
669 if (dot((self get-location),(i get-direction)) > wallBegin) && (dot((self get-location),(i get-direction)) < wallEnd):
\r
677 if ((des2) && (des3)):
\r
681 dist=|obsLoc - (self get-location)|.
\r
682 if( (j==0) || (min>dist) ):
\r
687 #print "sensor: $id obstaculo: $posObstacle direP: $destiny direS: $direction yo: $yo ".
\r
698 draw set-color to (1, 0, 0).
\r
699 draw draw-line from (self get-location) to (obs).
\r