]> git.llucax.com Git - z.facultad/75.68/celdas.git/blob - trunk/src/breve/robot/Celdas-2-7.tz
Se avanza más con la integración (aun sin probar).
[z.facultad/75.68/celdas.git] / trunk / src / breve / robot / Celdas-2-7.tz
1 @use PhysicalControl.\r
2 @use Shape.\r
3 @use Stationary.\r
4 @use Link.\r
5 @use MultiBody.\r
6 @use Drawing.\r
7 @use SistemaAutonomo.\r
8 \r
9 @define CELDAS_MAX_VELOCITY 30.\r
10 @define CELDAS_TURNO 100.\r
11 \r
12 PhysicalControl : CeldasControl {\r
13         % This class is used for building simple vehicle \r
14         % simulations.  To create a vehicle simulation, \r
15         % subclass CeldasControl and use the init method to \r
16         % create OBJECT(CeldasObstacle) and \r
17         % OBJECT(CeldasVehicle) objects.\r
18 \r
19         + variables:\r
20                 floor (object).\r
21                 floorShape (object).\r
22                 cloudTexture (object).\r
23 \r
24 \r
25         + to init:\r
26                 self enable-lighting.\r
27                 #self enable-smooth-drawing.\r
28 \r
29                 floorShape = new Shape.\r
30                 floorShape init-with-cube size (200, .2, 200).\r
31 \r
32                 floor = new Stationary.\r
33                 floor register with-shape floorShape at-location (0, 0, 0).\r
34                 #floor catch-shadows.\r
35 \r
36                 self point-camera at (0, 0, 0) from (3, 3, 24).\r
37 \r
38                 #self enable-shadows.\r
39                 #self enable-reflections.\r
40 \r
41                 cloudTexture = (new Image load from "images/clouds.png"). \r
42                 self set-background-color to (.4, .6, .9).\r
43                 self set-background-texture-image to cloudTexture.\r
44 \r
45 }\r
46 \r
47 MultiBody : CeldasLightVehicle (aka CeldasLightVehicles) {\r
48         % This object is used in conjunction with OBJECT(CeldasControl) to\r
49         % create simple vehicles.\r
50 \r
51         + variables:\r
52                 bodyShape (object).\r
53                 wheelShape (object).\r
54                 sensorShape (object).\r
55                 bodyLink (object).\r
56 \r
57                 wheels (list).\r
58                 sensors (list).\r
59 \r
60         + to init:\r
61                 bodyShape = new Shape.\r
62                 bodyShape init-with-cube size (4.0, .75, 3.0).  \r
63 \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
66                 # 40\r
67 \r
68                 sensorShape = new Shape.\r
69                 sensorShape init-with-polygon-cone radius .2 sides 5 height .5.\r
70                 # 10\r
71 \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
77 \r
78                 self set-root to bodyLink.\r
79 \r
80                 self move to (0, 0.9, 0).\r
81                 self set-texture-scale to 1.5.\r
82 \r
83         - to get-density:\r
84                 return 1.0.\r
85 \r
86         - to get-wheel-width:\r
87                 return 0.1.\r
88 \r
89         - to get-wheel-radius:\r
90                 return 0.6.\r
91 \r
92         + section "Adding Wheels and Sensors to a Vehicle"\r
93 \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
97 \r
98                 wheel, joint (object).\r
99 \r
100                 wheel = new CeldasWheel.\r
101                 wheel set-shape to wheelShape.\r
102 \r
103                 joint = new RevoluteJoint.\r
104 \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
108 \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
115 \r
116                 self add-dependency on joint.\r
117                 self add-dependency on wheel.\r
118 \r
119                 push wheel onto wheels.\r
120 \r
121                 return wheel.\r
122 \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
126 \r
127                 sensor, joint (object).\r
128 \r
129                 sensor = new CeldasSensor.\r
130                 sensor set-direction to direction.\r
131                 \r
132                 sensor set-shape to sensorShape.\r
133 \r
134                 joint = new RevoluteJoint.\r
135 \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
139 \r
140                 joint set-double-spring with-strength 300 with-max 0.01 with-min -0.01.\r
141 \r
142                 self add-dependency on joint.\r
143                 self add-dependency on sensor.\r
144 \r
145                 sensor set-color to (0, 0, 0).\r
146 \r
147                 #push sensor onto sensors.\r
148 \r
149                 return sensor.\r
150 \r
151         + to destroy:\r
152                 free sensorShape.\r
153                 free wheelShape.\r
154                 free bodyShape.\r
155 \r
156                 super destroy.\r
157 }\r
158 \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
163         +variables:\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
168                 iterate(int).\r
169                 teorias (list).\r
170                 sa (object).\r
171                 teoria (object).\r
172                 entorno (hash).\r
173                 datos-finales (hash).\r
174                 plan_finished (int).\r
175         \r
176         - to get-density:\r
177                 return 20.0.\r
178 \r
179         - to get-wheel-width:\r
180                 return 0.4.\r
181 \r
182         - to get-wheel-radius:\r
183                 return 0.8.\r
184 \r
185         + to set-global-velocity to velocity (float):\r
186                 rfWheel set-velocity to velocity.\r
187                 lfWheel set-velocity to velocity.\r
188                 rbWheel set-velocity to velocity.\r
189                 lbWheel set-velocity to velocity.\r
190 \r
191         + to get-global-velocity:\r
192                 return ((rfWheel get-velocity) + (lfWheel get-velocity)) / 2.\r
193 \r
194         + to turn-right:                \r
195                 tright++.\r
196 \r
197                 self rotate around-axis (0,1,0) by (-1.5709/CELDAS_TURNO)*tright. \r
198                         \r
199                 if (tright == CELDAS_TURNO): tright=0.\r
200 \r
201 \r
202         + to turn-left:\r
203                 tleft++.\r
204 \r
205                 self rotate around-axis (0,1,0) by (1.5709/CELDAS_TURNO)*tleft. \r
206                         \r
207                 if (tleft == CELDAS_TURNO): tleft=0.\r
208 \r
209 \r
210         + to get-sensor-value:\r
211                 return (fSensor get-sensor-value).\r
212 \r
213         +to update-entorno:\r
214                 entorno{"sensor_f"} = (fSensor get-data).\r
215                 entorno{"sensor_b"} = (bSensor get-data).\r
216                 entorno{"sensor_r"} = (rSensor get-data).\r
217                 entorno{"sensor_l"} = (lSensor get-data).\r
218                 entorno{"movido"} = 0. # TODO\r
219                 sa update-entorno with entorno.            \r
220 \r
221         +to init:\r
222                 # Configuracion de robot\r
223                 fSensor = (self add-sensor at (2.0, .4, 0)).            \r
224                 fSensor set-direction to (1,0,0).\r
225                 #fSensor set-direction to (0,0,1).\r
226                 fSensor set-id at 1.\r
227                 fSensor set-body at self.\r
228                 bSensor = (self add-sensor at (-2.0, .4, 0)).\r
229                 bSensor set-direction to (-1,0,0).\r
230                 #bSensor set-direction to (0,0,1).\r
231                 bSensor set-id at 2.\r
232                 bSensor set-body at self.\r
233                 lSensor = (self add-sensor at (0, .4, 1.5)).\r
234                 lSensor set-direction to (0,0,1).\r
235                 #lSensor set-direction to (1,0,0).\r
236                 lSensor set-id at 3.\r
237                 lSensor set-body at self.\r
238 \r
239                 rSensor = (self add-sensor at (0, .4, -1.5)).\r
240                 rSensor set-direction to (0,0,-1).\r
241                 #rSensor set-direction to (-1,0,0).\r
242                 rSensor set-id at 4.\r
243                 rSensor set-body at self.\r
244 \r
245                 lfWheel = (self add-wheel at (2, 0, -1.5)).\r
246                 lbWheel = (self add-wheel at (-2, 0, -1.5)).\r
247                 rfWheel = (self add-wheel at (2, 0, 1.5)).\r
248                 rbWheel = (self add-wheel at (-2, 0, 1.5)).\r
249 \r
250                 tleft=tright=0.\r
251                 avanzando=0.\r
252                 retrocediendo=0.\r
253                 girando_izq=0.            \r
254                 girando_der=0.            \r
255 \r
256                 # Configuracion de sistema autonomo\r
257                 sa = new SistemaAutonomo.\r
258                 iterate = 0.\r
259                 plan_finished = 1. # así planificamos apenas empezamos\r
260 \r
261                 teorias = 4 new Teorias.\r
262                 teorias{0} init named "Avanzar" with-action "adelante".\r
263                 teorias{0} set-dato-inicial name "sensor_f" value 0.\r
264                 teorias{0} set-dato-inicial name "sensor_b" value ANY.\r
265                 teorias{0} set-dato-inicial name "sensor_r" value ANY.\r
266                 teorias{0} set-dato-inicial name "sensor_l" value ANY.\r
267                 teorias{0} set-dato-inicial name "movido" value ANY.\r
268                 teorias{0} set-dato-final name "sensor_f" value ANY.\r
269                 teorias{0} set-dato-final name "sensor_b" value ANY.\r
270                 teorias{0} set-dato-final name "sensor_r" value ANY.\r
271                 teorias{0} set-dato-final name "sensor_l" value ANY.\r
272                 teorias{0} set-dato-final name "movido" value 1.\r
273 \r
274                 teorias{1} init named "Retroceder" with-action "atras".\r
275                 teorias{1} set-dato-inicial name "sensor_f" value 1.\r
276                 teorias{1} set-dato-inicial name "sensor_b" value ANY.\r
277                 teorias{1} set-dato-inicial name "sensor_r" value ANY.\r
278                 teorias{1} set-dato-inicial name "sensor_l" value ANY.\r
279                 teorias{1} set-dato-inicial name "movido" value ANY.\r
280                 teorias{1} set-dato-final name "sensor_f" value 0.\r
281                 teorias{1} set-dato-final name "sensor_b" value ANY.\r
282                 teorias{1} set-dato-final name "sensor_r" value ANY.\r
283                 teorias{1} set-dato-final name "sensor_l" value ANY.\r
284                 teorias{1} set-dato-final name "movido" value 1.\r
285 \r
286                 teorias{2} init named "Rotar a derecha" with-action "derecha".\r
287                 teorias{2} set-dato-inicial name "sensor_f" value 1.\r
288                 teorias{2} set-dato-inicial name "sensor_b" value ANY.\r
289                 teorias{2} set-dato-inicial name "sensor_r" value ANY.\r
290                 teorias{2} set-dato-inicial name "sensor_l" value ANY.\r
291                 teorias{2} set-dato-inicial name "movido" value ANY.\r
292                 teorias{2} set-dato-final name "sensor_f" value 0.\r
293                 teorias{2} set-dato-final name "sensor_b" value ANY.\r
294                 teorias{2} set-dato-final name "sensor_r" value ANY.\r
295                 teorias{2} set-dato-final name "sensor_l" value 1.\r
296                 teorias{2} set-dato-final name "movido" value 0.\r
297 \r
298                 teorias{3} init named "Rotar a izquierda" with-action "izquierda".\r
299                 teorias{3} set-dato-inicial name "sensor_f" value 1.\r
300                 teorias{3} set-dato-inicial name "sensor_b" value ANY.\r
301                 teorias{3} set-dato-inicial name "sensor_r" value ANY.\r
302                 teorias{3} set-dato-inicial name "sensor_l" value ANY.\r
303                 teorias{3} set-dato-inicial name "movido" value ANY.\r
304                 teorias{3} set-dato-final name "sensor_f" value 0.\r
305                 teorias{3} set-dato-final name "sensor_b" value ANY.\r
306                 teorias{3} set-dato-final name "sensor_r" value 1.\r
307                 teorias{3} set-dato-final name "sensor_l" value ANY.\r
308                 teorias{3} set-dato-final name "movido" value 0.\r
309 \r
310                 sa add teoria teorias{0}.\r
311                 sa add teoria teorias{1}.\r
312                 sa add teoria teorias{2}.\r
313                 sa add teoria teorias{3}.\r
314 \r
315                 datos-finales{"movido"} = 1.\r
316                 sa update-datos-finales with datos-finales.\r
317 \r
318         +to iterate:\r
319                 fl, fr(float).\r
320 \r
321                 if (0): # TODO posicion_final == posicion_actual\r
322                 {\r
323                         print "Llegamos al FINAL!!!".\r
324                         return.\r
325                 }\r
326 \r
327                 if (plan_finished):\r
328                 {\r
329                         self update-entorno.\r
330                         sa plan. # Si no tenemos plan, lo hacemos\r
331                         plan_finished = 0.\r
332                         # TODO posicion_inicial = posicion_actual\r
333                         if (! sa-has-next-theory):\r
334                         {\r
335                                 print "El planificador no encuentra PLAN!!!".\r
336                                 return.\r
337                         }\r
338                 }\r
339 \r
340                 if (iterate == 0):\r
341                 {\r
342                         print "iteracion 0".\r
343                         if (sa has-next-theory):\r
344                         {\r
345                                 print "hay teoria".\r
346                                 teoria = sa get-next-theory.\r
347                                 if ((teoria get-accion) == "adelante"):\r
348                                 {\r
349                                         avanzando = 1.\r
350                                         retrocediendo = 0.\r
351                                         girando_izq = 0.\r
352                                         girando_der = 0.\r
353                                 }\r
354                                 if ((teoria get-accion) == "atras"):\r
355                                 {\r
356                                         avanzando = 0.\r
357                                         retrocediendo = 1.\r
358                                         girando_izq = 0.\r
359                                         girando_der = 0.\r
360                                 }\r
361                                 if ((teoria get-accion) == "izquierda"):\r
362                                 {\r
363                                         avanzando = 0.\r
364                                         retrocediendo = 0.\r
365                                         girando_izq = 1.\r
366                                         girando_der = 0.\r
367                                 }\r
368                                 if ((teoria get-accion) == "derecha"):\r
369                                 {\r
370                                         avanzando = 0.\r
371                                         retrocediendo = 0.\r
372                                         girando_izq = 0.\r
373                                         girando_der = 1.\r
374                                 }\r
375                         }\r
376                 }\r
377 \r
378                 if (iterate == CELDAS_TURNO):\r
379                 {\r
380                         self update-entorno.\r
381                         # TODO if (posicion_actual == posicion_inicial): movido = false. else movido = true.\r
382                         if (sa validate theory teoria):\r
383                         {\r
384                                 print "valida".\r
385                         }\r
386                         else\r
387                         {\r
388                                 print "Teoria no valida".\r
389                                 plan_finished = 1.\r
390                         }\r
391                 }\r
392 \r
393                 iterate++.\r
394                 if (iterate == CELDAS_TURNO + 1):\r
395                         iterate = 0.\r
396 \r
397                 # Movimiento del robot\r
398                 if (avanzando):\r
399                         self set-global-velocity to (15).\r
400                 if (retrocediendo):\r
401                         self set-global-velocity to (-15).\r
402                 if (girando_izq):\r
403                         self turn-left.\r
404                 if (girando_der):\r
405                         self turn-right.\r
406 \r
407 }\r
408 \r
409 Stationary : CeldasObstacle (aka CeldasObstacles) {\r
410         % A CeldasObstacle is used in conjunction with OBJECT(CeldasControl)\r
411         % and OBJECT(CeldasVehicle).  It is what the OBJECT(CeldasSensor)\r
412         % objects on the CeldasVehicle detect.\r
413         % <p>\r
414         % There are no special behaviors associated with the walls--they're \r
415         % basically just plain OBJECT(Stationary) objects.\r
416    \r
417         +variables:\r
418             large (float).\r
419             direction (vector). \r
420 \r
421 \r
422         + 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
423                 self init-with-shape shape (new Shape init-with-cube size theSize) color theColor at-location theLocation with-rotation theRotation.\r
424                 large=20.\r
425 \r
426         + 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
427                 self register with-shape theShape at-location theLocation with-rotation theRotation.\r
428                 self set-color to theColor.\r
429                 \r
430         + to get-large:\r
431             return large.\r
432 \r
433         + to set-direction at theDirection (vector):\r
434             direction=theDirection.\r
435 \r
436         + to get-direction:\r
437             return direction.\r
438 }\r
439 \r
440 Link : CeldasWheel (aka CeldasWheels) {\r
441         % A CeldasWheel is used in conjunction with OBJECT(CeldasVehicle)\r
442         % to build Celdas vehicles.  This class is typically not instantiated\r
443         % manually, since OBJECT(CeldasVehicle) creates one for you when you\r
444         % add a wheel to the vehicle.\r
445 \r
446         + variables:\r
447                 joint (object).\r
448                 velocity (float).\r
449 \r
450         + to init:\r
451                 velocity = 0.\r
452 \r
453         - to set-joint to j (object):\r
454                 % Used internally.\r
455 \r
456                 joint = j.\r
457 \r
458         + section "Configuring the Wheel's Velocity"\r
459 \r
460         + to set-velocity to n (float):\r
461                 % Sets the velocity of this wheel.\r
462 \r
463                 if n > CELDAS_MAX_VELOCITY: n = CELDAS_MAX_VELOCITY.\r
464                 velocity = n.\r
465 \r
466                 joint set-joint-velocity to velocity.\r
467 \r
468         + to get-velocity:\r
469                 % Gets the velocity of this wheel.\r
470                 \r
471                 return velocity.\r
472 \r
473 }\r
474 \r
475 Link : CeldasSensor (aka CeldasSensors) {\r
476         % A CeldasSensor is used in conjunction with OBJECT(CeldasVehicle)\r
477         % to build Celdas vehicles.  This class is typically not instantiated\r
478         % manually, since OBJECT(CeldasVehicle) creates one for you when you\r
479         % add a sensor to the vehicle.\r
480 \r
481         + variables:\r
482                 direction (vector).\r
483                 positiveDirection(vector).\r
484                 sensorAngle (float).\r
485                 value (float).\r
486                 draw (object).\r
487                 body(object).\r
488                 id(int).\r
489 \r
490         + to init :\r
491                 direction = (1,0,1).\r
492                 positiveDirection= (1,0,1).\r
493                 sensorAngle = 1.6.\r
494                 value = 0.0.\r
495                 draw = new Drawing.\r
496                                 \r
497 \r
498   + section "Configuring the Sensor Values"\r
499         + to set-id at n (int):\r
500             id=n.\r
501 \r
502         + to set-body at robotBody(object):\r
503                 body=robotBody.\r
504                 \r
505         + to set-sensor-angle to n (float):\r
506                 % Sets the angle in which this sensor can detect obstacles.  The default\r
507                 % value of 1.6 means that the sensor can see most of everything in\r
508                 % front of it.  Setting the value to be any higher leads to general\r
509                 % wackiness, so I don't suggest it.\r
510 \r
511                 sensorAngle = n.\r
512 \r
513         + to set-direction to n (vector):\r
514                 direction = n.\r
515                 positiveDirection::x=|n::x|.\r
516                 positiveDirection::y=|n::y|.\r
517                 positiveDirection::z=|n::z|.\r
518 \r
519   + section "Getting the Sensor Values"\r
520 \r
521         + to get-sensor-value:\r
522                 % Gets the sensor value. This should be used from post-iterate,\r
523                 % if not, the sensor reading correspond to the previous\r
524                 % iteration.\r
525         \r
526         #+ to iterate:\r
527         \r
528         + to get-data:\r
529                 i (object).\r
530                 min,dist (float).\r
531                 v,obs(vector).\r
532                 aux(float).\r
533                 j (int).\r
534                 des2,des3(int).\r
535                 wallBegin,wallEnd,wallCenter (float).\r
536                 \r
537                 toObstacle(vector).\r
538                 largeWall (float).\r
539                 \r
540                 obsLoc (vector).                \r
541                 location (vector).\r
542                 posObstacle,destiny,yo(vector).\r
543                                              \r
544                 draw clear.\r
545                 value = 0.0.\r
546                 j=0.\r
547                 min=0.\r
548                 foreach i in (all CeldasObstacles): \r
549                         {\r
550                          posObstacle=i get-location.\r
551                          v = (body get-location) - (self get-location ).\r
552                          obsLoc::y=posObstacle::y.\r
553                          \r
554                          if (dot((i get-direction),(1,0,0))):\r
555                           {\r
556                            obsLoc::x=((self get-location)::x + ((posObstacle::z - (self get-location)::z)*v::x/v::z)).\r
557                            obsLoc::z=posObstacle::z.\r
558                           }                             \r
559                           else\r
560                           {\r
561                            obsLoc::z=((self get-location)::z + ((posObstacle::x - (self get-location)::x)*v::z/v::x)).\r
562                            obsLoc::x=posObstacle::x.\r
563                           } \r
564                                                                 \r
565                         #!\r
566                         if(dot((i get-direction),direction)==0):\r
567                                 des1=1.\r
568                         else\r
569                                 des1=0.\r
570                         !#\r
571 \r
572                         des2=0.\r
573                         if(dot(direction,(1,1,1))<0):\r
574                         {                        \r
575                             if((dot((self get-location),positiveDirection))>(dot(obsLoc,positiveDirection))):\r
576                                         des2=1.      \r
577                         }\r
578                         else\r
579                         {\r
580                             if((dot((self get-location),positiveDirection))<(dot(obsLoc,positiveDirection))):\r
581                                         des2=1.         \r
582                         }                       \r
583 \r
584 \r
585                         #Compruebo que el robot este frente a la pared\r
586                         wallCenter=dot((i get-location),(i get-direction)).\r
587                         wallBegin=wallCenter- (i get-large)/2.\r
588                         wallEnd=wallCenter + (i get-large)/2.           \r
589 \r
590                         \r
591                         yo=self get-location.\r
592                         destiny=i get-direction.\r
593 \r
594                                                                                                                 \r
595 \r
596                         if (dot((self get-location),(i get-direction)) > wallBegin) && (dot((self get-location),(i get-direction)) < wallEnd):\r
597                                 des3=1.\r
598                         else\r
599                         {\r
600                                  des3=0.\r
601                                  \r
602                         }                               \r
603                        \r
604                         if ((des2) && (des3)):\r
605                          {                                    \r
606                                 draw clear.\r
607 \r
608                                 dist=|obsLoc - (self get-location)|.\r
609                                 if( (j==0) || (min>dist) ):\r
610                                  {\r
611                                         min=dist.\r
612                                         obs=obsLoc.\r
613                                         j++.\r
614                                         #print "sensor: $id obstaculo: $posObstacle direP: $destiny direS: $direction yo: $yo ".        \r
615                                  }\r
616 \r
617                          }                                              \r
618 \r
619                         \r
620                 } #end for\r
621 \r
622                 if(j!=0):\r
623                         {\r
624                           #Dibujo el laser\r
625                           draw set-color to (1, 0, 0).\r
626                           draw draw-line from (self get-location) to (obs).\r
627                           return min.\r
628                         }\r
629                 \r
630 \r
631                 value = -1.\r
632                 return value.\r
633 \r
634 \r
635 }\r
636                 \r