Sunteți pe pagina 1din 70

Cómo utilizar el reproductor / Etapa

jennifer Owen

10 de julio de, 2009

Este documento pretende ser una guía para cualquier persona que aprende de DVD / etapa para la primera vez.
En él se explica el proceso de creación de un nuevo entorno de simulación y cómo luego hacer su simulación hacer
algo, usando un estudio de caso en el camino. Si bien está dirigido a usuarios Player / Stage, aquellos que sólo
deseen utilizar jugador en su robot también puede presentar secciones nd de este documento útil (particularmente
las partes acerca de la codificación con el jugador).

Si tiene alguna pregunta sobre el uso de DVD / etapa hay una guía para obtener ayuda de la
comunidad jugador aquí:

http://playerstage.sourceforge.net/wiki/Getting_help

1
Contenido
1. Introducción 3
1.1 Una nota sobre Instalación jugador / Fase. . . . . . . . . . . . . . . . . 3

2 Los fundamentos 3
2.1 Tipos de archivos importantes . . . . . . . . . . . . . . . . . . . . . . . .3

2.2 Interfaces, controladores y dispositivos. . . . . . . . . . . . . . . . . . . 4

3 Construyendo un Mundo 5
3.1 La construcción de un mundo vacío. . . . . . . . . . . . . . . . . . . . . . 7
3.1.1 Modelos . . . . . . . . . . . . . . . . . . . . . . . . . . . .8

3.1.2 Describir la ventana del reproductor / Fase. . . . . . . . . . . . 11


3.1.3 Haciendo un Mundo Básico fi l. . . . . . . . . . . . . . . . . . 12
3.2 La construcción de un robot. . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.2.1 Sensores y dispositivos. . . . . . . . . . . . . . . . . . . . . 13
3.2.2 Un Ejemplo Robot. . . . . . . . . . . . . . . . . . . . . . 17
3.3 y siguientes de construcciones o Stu. . . . . . . . . . . . . . . . . . . . . . . . . 27

4 Escribir una con fi guración (.cfg) 31


4.1 las direcciones del dispositivo - llave: host: robot: Interfaz: índice. . . . . . . . . 33
4.2 Poner la con fi guración de archivo junto. . . . . . . . . . . . . . 34

5 Obtención de su simulación para ejecutar el código 36


5.1 Conexión con el servidor proxy y con su código. . . . . . 37
5.1.1 Configuración de las conexiones: un Ejemplo. . . . . . . . . . . . 39
5.2 Interacción con apoderados. . . . . . . . . . . . . . . . . . . . . . . 40
5.2.1 Position2dProxy. . . . . . . . . . . . . . . . . . . . . . . 40
5.2.2 SonarProxy. . . . . . . . . . . . . . . . . . . . . . . . . . 42
5.2.3 LaserProxy. . . . . . . . . . . . . . . . . . . . . . . . . . 43
5.2.4 RangerProxy. . . . . . . . . . . . . . . . . . . . . . . . . 43
5.2.5 Blob fi nderProxy. . . . . . . . . . . . . . . . . . . . . . . 44
5.2.6 GripperProxy. . . . . . . . . . . . . . . . . . . . . . . . . 45
5.2.7 SimulationProxy. . . . . . . . . . . . . . . . . . . . . . . 46
5.2.8 Comandos Utiles Generales. . . . . . . . . . . . . . . . . 47
5.3 El uso de proxies: Un estudio de caso. . . . . . . . . . . . . . . . . . . . 47
5.3.1 La arquitectura de control. . . . . . . . . . . . . . . . . . 48
5.3.2 A partir del código. . . . . . . . . . . . . . . . . . . . . 48
5.3.3 Wander. . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
5.3.4 Evitación de Obstáculos. . . . . . . . . . . . . . . . . . . . . 51
5.3.5 pasar a un elemento. . . . . . . . . . . . . . . . . . . . . . . . . 52
5.3.6 recojan el artículo. . . . . . . . . . . . . . . . . . . . . . . . . . 54
5.4 La simulación de múltiples robots. . . . . . . . . . . . . . . . . . . . . 56

6 Enlaces de interés 58

7 Apéndices 59

2
1. Introducción
Player / Stage es una herramienta de simulación de robots, forma parte de un programa, el jugador, que es una Hardware
capa de abstracción. Eso quiere decir que habla con los bits de hardware en el robot (como una garra o una
cámara) y le permite controlarlos con su código, lo que significa que no tiene que preocuparse acerca de cómo
las diversas partes del trabajo del robot. Etapa es un plugin para Player que escucha lo que jugador está diciendo
que hacer y convierte estas instrucciones en una simulación de su robot. También simula los datos del sensor y
envía esta al jugador que a su vez hace que los datos de los sensores a disposición del código.

Una simulación entonces, se compone de tres partes:

• Tu codigo. Esto se refiere al jugador.

• Jugador. Esto toma su código y envía instrucciones a un robot. Desde el robot se pone los datos del
sensor y la envía a su código.

• Escenario. interfaces de etapa con el jugador en la misma forma que el hardware de un robot. Se
recibe instrucciones del jugador y mueve un robot simulado en un mundo simulado, se pone datos
de los sensores del robot en la simulación y envía esta al jugador.

Junto jugador y la etapa se llaman jugador / de la etapa, y hacen una simulación de sus robots.

Estas instrucciones se centran en cómo utilizar Player / Stage para hacer una simulación, pero espero que
esto seguirá siendo un recurso útil para cualquier persona simplemente usando el jugador (que es lo mismo, pero
en un robot real, sin ningún tipo de software de simulación).

1.1 Una nota sobre Instalación de DVD / Etapa

Las instrucciones sobre cómo instalar el reproductor / Fase en su ordenador no son realmente el foco de este
documento. Es muy di fi culto sin embargo. Si tienes suerte, la instalación funcionará vez primera, pero hay un
gran número de dependencias que pueden necesitar la instalación. En Linux existen los programas de instalación
“sinápticas” o “aptitud” que instalará un paquete y también obtener sus dependencias, pero estos no son
comunes a todas las distribuciones de Linux. Hay otro programa de instalación llamado “apt-get”, pero esto no va
a instalar las dependencias para usted. Para ordenadores con Ubuntu hay un conjunto razonable de
instrucciones aquí:

http://www.control.aau.dk/~tb/wiki/index.php/Installing_Player_
and_Stage_in_Ubuntu

Por otra parte, intenta las sugerencias sobre el jugador “Obtención de ayuda” en la página:

http://playerstage.sourceforge.net/wiki/Getting_help

2 Los fundamentos

2.1 Tipos de archivos importantes

En Reproductor / Fase hay 3 tipos de fi l que usted necesita entender para ponerse en marcha con el jugador /
Fase:

3
• un .world fi l

• un .cfg (con fi guración) fi le

• un .inc (incluir) fi le

El .world fi l le dice a jugador / Fase qué cosas están disponibles para poner en el mundo. En este
expediente que usted describe su robot, los elementos que pueblan el mundo y la disposición del mundo. El
.inc fi l sigue la misma sintaxis y formato de una
. mundo fi l, pero puede ser incluido. Así que si hay un objeto en el mundo que es posible que desee utilizar en
otros mundos, como un modelo de un robot, poniendo la descripción robot en un .inc fi l sólo hace que sea
más fácil de copiar, sino que también significa que si cada vez que desee cambiar su descripción robot a
continuación, sólo tiene que hacerlo en un lugar y sus múltiples simulaciones se cambian también.

El .cfg fi l es lo que lee jugador para obtener toda la información sobre el robot que se va a uso.Este fi l
dice Player que los conductores que necesita para utilizar con el fin de interactuar con el robot, si está
utilizando un robot real éstos los conductores están integradas en jugador 1, Alternativamente, si desea hacer
una simulación, el conductor es siempre el escenario (así es como jugador utiliza la etapa de la misma forma
en que utiliza un robot: se cree que es un controlador de hardware y se comunica con ella como tal). los

. cfg fi l dice Reproductor de cómo hablar con el conductor, y cómo interpretar los datos desde el controlador de modo que
pueda ser presentado a su código. Los productos que se describen en el
. fi l mundo debe describirse en el .cfg fi l si desea que su código sea capaz de interactuar con el elemento
(como un robot), si usted no necesita el código para interactuar con el artículo entonces esto no es
necesario. El .cfg fi le hace todo esta especificación usando interfaces y los conductores, que serán
discutidos en la sección siguiente.

2.2 Interfaces, Controladores y dispositivos

• Los conductores son piezas de código que hablar directamente con el hardware. Estos están integrados en jugador
por lo que no es importante saber cómo escribir éstos a medida que comienza a aprender jugador / Fase. Los
conductores son específico a una pieza de hardware por lo que, por ejemplo, un conductor de láser será di ff Erent a
un controlador de la cámara, y también di ff Erent a un controlador para una marca Erent di ff de láser. Esta es la
misma que la forma en que los controladores para tarjetas gráficas di ff er para cada marca y modelo de la tarjeta. Los
conductores producen y leen la información que se ajusta a una “interfaz”.

• Las interfaces son una manera establecida para un conductor para enviar y recibir información de jugador. Al igual que

los conductores, las interfaces también están integradas en jugador y hay una gran lista de ellos en el manual del

jugador 2. En ellas se indica la sintaxis y la semántica de cómo interactúan los conductores y jugador.

• Un dispositivo es un controlador que está vinculada a una interfaz de modo que el jugador puede hablar
con él directamente. Esto significa que si usted está trabajando en un robot real que se puede interactuar

con un dispositivo real (láser, pinzas, cámara, etc.) en el robot real, en un robot simulado se puede

interactuar con sus simulaciones. La documentación o fi cial realidad describe estas 3 cosas bastante bien

con un ejemplo.

1 O se puede descargar o escribir sus propios controladores, pero no voy a hablar acerca de cómo hacer esto aquí.

2 http://playerstage.sourceforge.net/doc/Player-2.1.0/player/group interfaces.html

4
Considere la interfaz láser. Esta interfaz define un formato en el que un planar
gama-sensor puede volver lecturas de rango (básicamente una lista de rangos, con algo de
meta-datos). La interfaz del láser es sólo eso: una interfaz. No se puede hacer nada con
ella.
Consideremos ahora el conductor sicklms200. Este controlador controla un LMS200
SICK, que es sensor rango particular planar que es popular en aplicaciones de robots
móviles. El conductor sicklms200 sabe cómo comunicarse con el LMS200 de SICK sobre una
línea serie y recuperar datos de distancia de ella. Pero no desea acceder a los datos de
rango en algún formato SICK-específica. Por lo que el conductor también sabe cómo traducir
los datos recuperados para que sea compatible con el formato definido por la interfaz de
láser.

El conductor sicklms200 se puede unir a la interfaz de láser. . . para crear un


dispositivo, que podría tener la siguiente dirección:
localhost: 6665: láser: 0
Los campos en esta dirección corresponden a las entradas en la estructura devaddr t jugador: host,
robot, de la interfaz, y el índice. Los campos de acogida y robot fi (localhost y 6665) indican donde se
encuentra el dispositivo. El campo interfaz fi indica que la interfaz Los soportes del dispositivo, y por lo
tanto la forma en que se puede utilizar. Debido a que es posible que tenga más de un láser, el campo de
índice fi le permite escoger entre los dispositivos compatibles con la interfaz dada y se encuentran en el
equipo dado robot Otros láseres en el mismo host: el robot se le asignaría índices di ff Erent.

El último párrafo no se hace un poco técnico, pero no se preocupe. conversaciones jugador a partes de los puertos
de robots usando (el puerto por defecto es 6665), si está usando Etapa entonces el jugador y la etapa se
comunican a través de estos puertos (incluso si están en ejecución en el mismo equipo). Toda esta línea hace es
decirle qué puerto jugador para escuchar y qué tipo de datos que puede esperar. En el ejemplo que es los datos
láser que está siendo transmitida en el puerto 6665 de la computadora que el jugador se está ejecutando en
(localhost). Se podía conectar fácilmente a otro equipo utilizando su dirección IP en lugar de “localhost”. La
especificidad cs de escribir una dirección de dispositivo de esta manera se describe en la sección 4.

3 Construyendo un Mundo

En primer lugar vamos a correr un mundo y con fi guración fi l que viene incluido con el escenario. En su cáscara
del golpe vaya a la carpeta / Etapa mundos, por defecto (en Linux por lo menos) esto es / / share / stage / usr /
local mundos. Una vez en la carpeta correcta escriba el siguiente comando para ejecutar el “mundo simple” que
viene con el jugador / Fase:

El jugador simple.cfg

Suponiendo jugador / Stage está instalado correctamente, debería tener ahora una ventana abierta que se ve
figura 1. En esta etapa se puede arrastrar y soltar el robot alrededor de su mundo con el ratón, pero también
puede tele-operar el robot usando el programa Visor de jugador . en un terminal separada mientras que la
ventana de simulación Player / Stage es todavía abierto, escriba:

playerv --position2d --laser

5
Figura 1: El mundo simple.cfg después de estar de ejecución

6
Figura 2: El mundo visto simple.cfg con el Visor de jugador

Figura 3: Cómo mando a distancia (tele-operar) el Robot Etapa

Los -- position2d y - láser Opciones cuentan la playerv (Visor jugador) pro- grama que desea buscar en los
datos de posición y los datos de láser que está disponible para el robot. Esto debería abrir una ventana que
se parece a la fi gura 2.
Para ser capaz de controlar a distancia el robot hace clic dispositivo → position2d: 0 →
Comando como se muestra en la fi gura 3. Un retículo debería aparecer sobre el robot en la ventana del
visor Player, que si se arrastra alrededor hará que el robot se mueva en el / simulación Etapa jugador (la fi
gura 1).

3.1 La construcción de un mundo vacío

Como se puede ver en la sección 3, cuando decimos a jugador para construir un mundo en el que solamente damos la
.cfg fi l como una entrada. Este .cfg fi l tiene que decirnos dónde hallar nuestra .world fi l, que es donde se describen
todos los elementos de la simulación. Para explicar cómo construir un mundo Etapa contiene nada más que paredes
utilizaremos un ejemplo. Para empezar a construir un mundo vacío que necesitamos un .cfg fi l. En primer lugar crear
un documento llamado empty.cfg y copiar el código siguiente en él:

controlador (

nombre de "etapa"
plug-in "libstageplugin"

proporciona [ "simulación: 0"]

7
# cargar el archivo con el nombre en el simulador Worldfile
"empty.world"
)

La con fi guración fi l de sintaxis se describe en la sección 4, pero básicamente lo que está sucediendo aquí
es que su con fi guración fi l jugador está diciendo que hay un conductor llamado escenario en el libstageplugin
biblioteca, y esto dará a los datos del jugador que se ajusta a la simulación interfaz. Para construir la
simulación jugador tiene que buscar en el mundo fi l de llamada Mundo vacío que se almacena en la misma
carpeta que este .cfg. Si se almacena en otro lugar que tendría que incluir un lepath fi, por ejemplo ./ mundos
/ empty.world. Las líneas que comienzan con el símbolo de almohadilla (#) son comentarios. Cuando se
construye una simulación, cualquier simulación, en la etapa del trozo de código anterior debe ser siempre la
primera cosa que la con fi guración fi l dice. Obviamente el nombre del mundo fi l se debe cambiar en función
de lo que llamó él sin embargo.

Ahora, una básica con fi guración fi l se ha escrito, es el momento de decirle reproductor / Fase qué
poner en esta simulación. Esto se hace en el .world fi l.

3.1.1 Modelos

A fi mundo le es básicamente una lista de los modelos que se describen todos los FF Stu en la simulación.
Esto incluye el entorno básico, robots y otros objetos. El tipo básico de modelo se denomina “modelo”, y
que definen un modelo utilizando la siguiente sintaxis:

definir modelo nombre_del_modelo (

# parámetros
)

Esto le dice a jugador / Stage que son definiendo un modelo que ha llamado
nombre del modelo, y todo el ff Stu en los paréntesis son parámetros del modelo. Para comenzar a entender
los parámetros de DVD / modelo de etapas, vamos a ver el map.inc fi le que viene con la etapa, esto se utiliza
para describir la ronment bientes básico en la simulación (por ejemplo, paredes de los robots pueden topar
en):

definir modelo de mapa (

# sombría, sensible, de color artística


"negro"

# la mayoría de los mapas tendrán un límite de cuadro delimitador


1

gui_nose 1 gui_grid 1
gui_movemask 0
gui_outline 0

fiducial_return 0 0
gripper_return

8
)

Podemos ver en la línea de primera que son de fi nir una modelo llamado mapa.

• color: Le dice a jugador / Fase de qué color para rendir este modelo, en este caso va a ser negro.

• límite: si hay o no un cuadro delimitador alrededor del modelo. Este es un ejemplo de un parámetro
binario, que significa que el si el número al lado de él es 0 entonces es falso, si es 1 o más,
entonces es cierto. Así que aquí tenemos una caja alrededor de nuestro modelo “mapa” para que el
robot no puede vagar fuera de nuestro mapa.

• gui_nose: esto le dice a jugador / de la etapa que debería indicar en qué dirección se enfrenta el
modelo. La Figura 4 muestra la rencia ff di entre un mapa con una nariz y una sin.

• gui_grid: esto va a superponer una cuadrícula sobre el modelo. La Figura 5 muestra un mapa con una cuadrícula.

• gui_movemask: esto indica si debe ser posible arrastrar y soltar el modelo. Aquí es 0, por lo que no
se puede mover el modelo de mapa una vez jugador / de la etapa ha sido ejecutado. En la sección
3, cuando el ejemplo de DVD / Etapa
simple.cfg se ejecutó fue posible arrastrar y soltar el robot, ya que su gui_movemask variable se
establece en 1.

• gui_outline: indica si el modelo preciso describirlo. Esto no tiene ningún rencia di ff a un mapa, pero
puede ser útil cuando se realizan modelos de objetos dentro del mundo.

• fiducial_return: cualquier parámetro de la forma alguna de retorno del sensor de- escribas cómo ese
tipo de sensor debe reaccionar con el modelo. “De referencia” es un tipo de sensor de robot que se
describirá más adelante en la sección 3.2.1. Ajuste fiducial_return a 0 significa que el mapa no puede
ser detectada por un sensor de ducial fi.

• gripper_return: Me gusta fiducial_return, gripper_return le dice a jugador / Etapa de que su modelo puede ser
detectado por el sensor correspondiente, es decir, puede ser agarrado por una pinza. Este parámetro también
indica si el modelo puede ser empujado. aquí gripper_return está ajustado a 0 de modo que el mapa no puede
ser empujado por un robot y no puede ser agarrado por una pinza. Para hacer uso de la map.inc fi l ponemos el
siguiente código en nuestro mundo fi l:

incluir "map.inc"

Esto inserta el map.inc fi l en nuestro mundo fi l, donde la línea include es. Esto supone que el mundo fi l y map.inc
fi l están en la misma carpeta, si se no, entonces usted tendrá que incluir la lepath fi en las cotizaciones.
Una vez hecho esto podemos modificar nuestra de fi nición del modelo de mapa para ser utilizado en la
simulación. Por ejemplo:

9
Figura 4: La imagen izquierda muestra un mapa vacío sin una nariz. La imagen de la derecha muestra el
mismo mapa con una nariz para indicar la orientación, esta es la línea horizontal desde el centro del mapa a
la derecha, muestra que el mapa es en realidad enfrenta a la derecha.

Figura 5: un mapa vacío con rejilla de interfaz gráfica de usuario habilitado. Con rejilla de interfaz gráfica de usuario desactivado esta no sería

más que un cuadrado blanco vacío.

10
Figura 6: La imagen de la izquierda es nuestro mapa de bits “helloworld.png”, la imagen de la derecha es lo Reproductor / Fase
interpreta que el mapa de bits. Las áreas negras son las paredes, el robot puede mover en cualquier otro lugar.

mapa (

mapa de bits "mapas de bits / helloworld.png" tamaño


[12 5]
)

Lo que esto significa es que estamos usando el modelo de “mapa”, y hacer algunas definiciones adicionales de fi; tanto
“mapa de bits” y “tamaño” son parámetros de un modelo de DVD / escenario. Aquí le estamos diciendo a jugador /
Etapa que de fi ne un montón de parámetros para un tipo de modelo llamado “mapa” (contenido en map.inc) y ahora
estamos utilizando este “mapa” modelo de definición y la adición de algunos parámetros adicionales.

• mapa de bits: este es el fi lepath a un mapa de bits, que puede ser de tipo bmp, jpeg, gif o png. Las
áreas negras en el mapa de bits indican el modelo de lo que se forma, las áreas no negros no son
prestados, esto se ilustra en la fi gura 6. En el map.inc fi l le dijimos al mapa que su “color” sería
negro. Este parámetro no un ff ect cómo se leen los mapas de bits, Reproductor / Fase siempre
buscará negro en el mapa de bits, el parámetro de “color” apenas altera el color lo que el mapa se
representa en la simulación.

• tamaño: Este es el tamaño en metros de la simulación. Todos los tamaños que usted da en el mundo
fi l están en metros, y representan el tamaño real de las cosas. Si tiene 4m x 3m arena de pruebas
para robots que desea simular entonces el tamaño aquí es [3,0 4,0]. El primer número es el tamaño
en el X dimensión, la segunda es la y dimensión.

Una lista completa de los parámetros del modelo y sus descripciones se puede encontrar en el o fi cial
manual de la Etapa 3. La mayoría de los parámetros útiles ya se han descrito aquí, sin embargo hay algunos otros
tipos de modelos que son relevantes para las simulaciones de construcción de robots, éstos se describirán más
adelante en la sección 3.2.

3.1.2 Describir la ventana del reproductor / Etapa

El mundo le fi también se puede utilizar para describir la ventana de simulación que crea jugador / Fase.
Reproductor / Fase hará automáticamente una ventana para la simulación si

3 http://playerstage.sourceforge.net/doc/stage-3.0.1/group model.html

11
usted no pone ningún detalle de ventana en el mundo fi le, sin embargo, a menudo es útil para poner esta
información en cualquier caso. Esto evita que una gran simulación de ser demasiado grande para la ventana, o
para aumentar o disminuir el tamaño de la simulación.
Como un modelo, una ventana es una entidad incorporada de alto nivel con una gran cantidad de parámetros. A
diferencia de los modelos sin embargo, no puede haber sólo una ventana en una simulación y sólo unos pocos de sus
parámetros son realmente necesarios. La ventana de simulación se describe con la siguiente sintaxis:

ventana (

parámetros ...
)

Los dos parámetros más importantes para la ventana son tamaño y escala.

• tamaño: Este es el tamaño será la ventana de simulación en píxeles. Que necesita para de fi nir la
anchura y la altura de la ventana con la siguiente sintaxis: tamaño [altura anchura].

• escala: Esta es la cantidad de metros del entorno simulado cada píxel muestra. Cuanto más grande
sea este número, menor es la simulación se convierte. El valor óptimo para la escala es Tamaño de mapa

tamaño de ventana y debe ser redondeado


ligeramente hacia arriba de modo que la simulación es un poco más pequeña que la ventana que se encuentra.

Una lista completa de los parámetros de la ventana se puede encontrar en el manual de la etapa en “WorldGUI” 4.

3.1.3 Realización de una base mundial fi l

Ya hemos hablado de los conceptos básicos de mundo fi l edificio: modelos y la ventana. Hay sólo unos
pocos parámetros para describir más que no pertenecen, ya sea en un modelo o una descripción de la
ventana que debe ser de fi nido y luego el mundo fi l se puede construir.

• tamaño: En este nivel esto representa lo grande, en metros, todo el entorno ción simu- será. Esto es
completamente independiente del tamaño del mapa, ya que podría ser más grande y puede haber
varios mapas Erent di ff Run-Ning en la misma simulación (por lo que más de una simulación se
puede ejecutar a la vez). En general, aunque esto sólo tiene que ser el mismo que el tamaño del
mapa. Este parámetro debe ser incluido en la fi le mundo de otro modo la simulación no funcionará.

• interval_sim: Este es el número de milisegundos simulada hay Tween BE- cada actualización de la
ventana de simulación, el valor predeterminado es de 100 milisegundos.

• interval_real: Este es el número de milisegundos real hay entre cada actualización de la ventana de
simulación. Equilibrio de este parámetro y el
intervalo de \ _sim parámetro controla la velocidad de la simulación. Una vez más, el valor predeterminado es de 100
milisegundos, tanto estos valores predeterminados de los parámetros de intervalo son bastante sensible, por lo que no
siempre es necesario redefinir ellos.

4 http://playerstage.sourceforge.net/doc/stage-3.0.1/group worldgui.html

12
El manual contiene una lista Etapa del mundo de alto nivel fi l parámetros 5.
Finalmente, somos capaces de escribir un mundo fi l!

incluir "map.inc"

# tamaño de todo el tamaño de simulación [15


15]

# configurar la ventana ventana de interfaz gráfica de

usuario (

tamaño [700,0 700,0]


# 15/700 redondeado hasta una escala de
bits 0,025
)

# cargar un mapa de entorno de mapa de bits (

mapa de bits "mapas de bits / cave.png"


tamaño [15 15]
)

Si salvamos el código anterior como empty.world (corregir cualquier lepaths fi si es necesario) podemos ejecutar su
correspondiente empty.cfg fi l (ver sección 3.1) para obtener la simulación se muestra en la fi gura 7.

3.2 La construcción de un robot

En Reproductor / Etapa un robot es sólo un tipo poco avanzado de modelo, todos los paráme- tros descritos en la
sección 3.1.1 todavía se pueden aplicar.

3.2.1 sensores y dispositivos

Hay seis clases incorporadas de modelo que ayudan a la construcción de un robot, que se utilizan para definir los
sensores y actuadores que el robot tiene. Estos están asociados con un conjunto de parámetros del modelo que
de fi ne por qué sensores el modelo puede ser detectado (estos son los _ regreso s se mencionó anteriormente).
Cada uno de ellos incorporado en los modelos actúa como una interfaz ( véase la sección 2.2) entre la simulación y
el jugador. Si su robot tiene uno de estos tipos de sensores en él, entonces es necesario utilizar el modelo
pertinente para describir el sensor, de lo contrario la etapa y del jugador no será capaz de pasar los datos entre sí.
Es posible escribir sus propias interfaces, pero el ff Stu ya incluido en el reproductor / escenario debería ser su
ciente FFI para las necesidades de la gente. Una lista completa de interfaces que soportan los jugadores se
pueden encontrar en el manual del jugador 6 aunque sólo la siguiente están soportados por la distribución de
corriente de la etapa (versión 3.0.1). A menos que se indique lo contrario, estos modelos utilizan la interfaz de
jugador que le da nombre:

5 http://playerstage.sourceforge.net/doc/stage-3.0.1/group mundo.html
6 http://playerstage.sourceforge.net/doc/Player-2.1.0/player/group interfaces.html

13
Figura 7: Nuestro mundo vacío.

cámara 7 El modelo de la cámara añade una cámara para el modelo de robot y permite que su código para
interactuar con la cámara simulada. Los parámetros de la cámara son los siguientes:

• resolución [xy]: la resolución, en píxeles, de la imagen de la cámara.

• Rango [min max]: la distancia mínima y máxima que la cámara puede detectar

• fov [xy]: el campo de visión de la cámara en grados.

• PanTilt [Pan Tilt]: el ángulo horizontal de la cámara se puede mover a través de (pan) y el ángulo
vertical (inclinación). Así, por ejemplo, PanTilt [90 20] al- mínimos a la cámara moverse 45 ◦ izquierda
y 45 ◦ a la derecha y 10 ◦ y 10 ◦ abajo.

blob visor 8 Esto simula el software de detección de color que se puede ejecutar en la imagen de la cámara
del robot. No es necesario incluir un modelo de la cámara en su descripción del robot si se desea utilizar un
visor burbuja, la burbuja visor funcionará por sí sola. El visor burbuja fi sólo puede encontrar un modelo si
su
blob_return parámetro es cierto. Los parámetros para el visor burbuja fi se describen en el manual de la
etapa, pero los más útiles son aquí:

• colors_count <int>: el número de colores Erent di ff la burbuja del visor puede detectar

7 http://playerstage.sourceforge.net/doc/stage-3.0.1/group camera.html modelo


8 http://playerstage.sourceforge.net/doc/stage-3.0.1/group modelo blob fi nder.html

14
• colores [ ]: los nombres de los colores se pueden detectar. Esto se da a la mancha visor definición
en forma [" negro" 'azul' 'cian']. Estos nombres de colores son de la construcción en la base de datos
X11 rgb.txt color. Este está integrado en Linux. 9

• imagen [xy]: el tamaño de la imagen de la cámara, en píxeles.

• gama <flotar>: El alcance máximo que la cámara puede detectar, en Tres me-.

• FOV <float>: campo de visión de la burbuja del visor en radianes.

Es importante tener en cuenta que la sintaxis para el modelo blob visor es Erent di ff en la Etapa versiones
2.XX y 3.XX Los parámetros anteriores son específica a la Etapa
3.XX, en la etapa 2.XX tienen nombres di ff Erent pero hacen lo mismo:

• channel_count <int>: mismas que cuentan colores.

• canales []: mismo que los colores [].

• imagen [xy]: igual que en la etapa 3.XX

• range_max <float>: mismo como gama

• PTZ [pan_angle tilt_angle zoom_angle]: controla las áreas que la cámara puede ver. Esto funciona
como Pan Tilt del modelo de cámara, la
zoom_angle es el campo de vista en grados.

Además, en la etapa 2.XX burbuja visor es un hijo de un modelo obsoleto llamada PTZ. Todo esto significa
básicamente es que cuando se de fi nir el modelo de burbuja visor es necesario utilizar esta sintaxis en su lugar:

definir PTZ nombre_del_modelo (

blobfinder (

# parámetros
)
)

fi ducial visor 10 Un ducial fi es un punto fijo en una imagen, por lo que la fi nder ducial fi simula el software de
procesamiento de imágenes que localiza puntos fi jos en una imagen. La fi nder ducial fi es capaz de localizar
objetos en la simulación cuya fiducial_return
parámetro se establece en verdadero. Etapa también le permite especificar los tipos di ff Erent de fi ducial
utilizando el fiducial_key parámetro de un modelo. Esto significa que usted puede hacer que los robots capaz
de decirle al rencia di ff ff entre di fi ducials Erent por qué clave que transmiten. La fi nder ducial fi y el
concepto de fiducial_key s se explica adecuadamente en el manual del escenario.

9 rgb.txt normalmente se puede encontrar en /usr/share/X11/rgb.txt suponiendo que se haya instalado correctamente, alternativamente,

una búsqueda en Google de “rgb.txt” le dará el documento.


10 http://playerstage.sourceforge.net/doc/stage-3.0.1/group modelo fi ducial.html

15
guardabosque 11 Esto simula cualquier tipo de dispositivo de detección de obstáculos (por ejemplo, los sonares o
sensores de infrarrojos). Estos modelos pueden localizar cuyos ranger_return es verdad. Utilizando un modelo
Ranger se puede de fi nir cualquier número de dispositivos Ranger y aplicarlas todas a un solo robot. A diferencia de
los otros tipos de modelos que no se utiliza la interfaz con su nombre, pero en lugar de la sonar interfaz, hay más
sobre esto en la sección 4.2. Los parámetros para el guardabosque modelo y sus entradas se describen en el
manual de la etapa, pero básicamente:

• scount <int>: El número de sensores Ranger en este modelo ranger

• Spose [ranger_number] [guiñada xy]: Indica al simulador donde los Rangers se colocan alrededor del
robot. Cómo escribir el [ guiñada xy] los datos se explica en la sección 3.2.2.

• ssize [xy]: lo grande que son los sensores.

• sview [min fov max]: define el máximo y distancias mínimas que puede ser detectada y también el
campo de vista en grados.

láser 12 Un láser es un caso especial del sensor de guardabosques que sólo permite un guardaparques (así que no hay
ninguna de las scount, Spose ff Stu), pero tiene un gran campo de visión. Si un modelo tiene su laser_return parámetro
activado a continuación, un láser puede detectarlo. Los detalles sobre los parámetros del láser se pueden encontrar en el
manual de la etapa, sin embargo, los parámetros más útiles son:

• range_min: El alcance mínimo del láser.

• range_max: el alcance máximo del láser.

• FOV: el campo de visión del láser. En la etapa 3.XX esto es en radianes, en la etapa 2.XX es en
grados.

pinza 13 El modelo de pinza es una simulación de la pinza se obtiene en un robot Pioneer. 14 Si coloca una
pinza en su modelo de robot que significa que el robot es capaz de recoger objetos y moverlos dentro de la
simulación. El manual de la etapa en línea dice que las pinzas están en desuso en la etapa 3.XX, sin
embargo, esto no es realmente el caso y pinzas son muy útiles si desea que su robot sea capaz de
manipular y mover elementos. Los parámetros que se pueden utilizar para personalizar el modelo de agarre
son:

• tamaño [xy]: La dimensiones X e Y de la pinza.

• plantear [guiñada xy]: Cuando la pinza se coloca en el robot.


11 http://playerstage.sourceforge.net/doc/stage-3.0.1/group ranger.html modelo
12 http://playerstage.sourceforge.net/doc/stage-3.0.1/group laser.html modelo
13 http://playerstage.sourceforge.net/doc/Stage-2.0.0/group gripper.html modelo
14 Las pinzas de Pioneer se ve como un gran bloque en la parte frontal del robot con dos grandes deslizadores que se cierran alrededor de un

objeto.

dieciséis
posición 15 El modelo simula la posición de odometría del robot, esto es cuando el robot realiza un
seguimiento de dónde está registrando cuántas veces sus ruedas giran y el ángulo que gira. Este modelo de
robot es el más importante de todos porque permite que el modelo de robot que se encarna en el mundo, lo
que significa que puede colisionar con cualquier cosa que tiene su obstacle_return parámetro establece en
true. El modelo de la posición utiliza el position2d interfaz, que es esencial para el jugador porque le dice a
jugador donde el robot es en realidad en el mundo. Los parámetros más útiles de la modelo de posición son:

• manejar: Narra la odometría cómo se conduce el robot. Esto es por lo general “di ff” que significa que el
robot se controla cambiando las velocidades de las ruedas izquierda y derecha de forma independiente.
Otros valores posibles son “coche” que significa que el robot utiliza una velocidad y un ángulo de dirección,
o “omni” que significa que puede controlar cómo se mueve a lo largo de la X y y ejes de la simulación.

• localización: le dice al modelo de cómo debe registrar la “Odom” odometría si el robot calcula que a medida
que se mueve a lo largo o “GPS” para el robot para tener un perfecto conocimiento acerca de dónde se
encuentra en la simulación.

• odom_error [ángulo xy]: La cantidad de error que el robot hará en las grabaciones de odometría.

• masa <int>: ¿Cuánto pesa el robot.

3.2.2 Un Ejemplo Robot

Para demostrar cómo construir un modelo de un robot en el reproductor / Fase vamos a construir nuestro propio
ejemplo. En primer lugar vamos a describir las propiedades físicas del robot, tales como tamaño, forma y masa. A
continuación, vamos a añadir sensores en él para que pueda interactuar con su entorno.

Cuerpo del robot Digamos que queremos modelar un robot basura recogiendo llamado “bigbob”. Lo primero
que tenemos que hacer es describir su forma básica, para ello es necesario conocer las dimensiones de su
robot en metros. La Figura 8 muestra la forma básica de bigbob dibujado en algunas coordenadas cartesianas,
las coordenadas de las esquinas de la robot se han registrado. entonces podemos construir este modelo
utilizando el polígonos parámetro de modelo dieciséis:

definir la posición bigbob (

# la forma de polígonos bigbob 1 polígono


[0] .points 6 polígono [0] .point [0] [0 0]
polígono [0] .point [1] [0 1] polígono [0] .point
[2] [0.75 1] polígono [0] .point [3] [1 0,75]
polígono [0] .point [4] [1 0,25]

15 http://playerstage.sourceforge.net/doc/stage-3.0.1/group position.html modelo


dieciséis En este ejemplo estamos utilizando polígonos con el tipo de modelo posición pero igualmente podríamos utilizarlo con otros tipos de

modelos.

17
Figura 8: La forma básica queremos hacer bigbob, las unidades en los ejes están en metros.

polígono [0] .point [5] [0,75 0]


)

En la línea primera de este código decimos que somos una de fi nición posición modelo llamado bigbob. Siguiente
polígonos 1 dice que este modelo será construido de un polígono. Las siguientes líneas van a describir la
forma de este polígono;
polígono [0] .points 6 dice que el polígono tiene 6 esquinas y polígono [número] .point [número] [xy]
da las coordenadas de cada vértice del polígono a su vez. Es importante ir alrededor del robot haciendo cada
esquina a su vez (en sentido horario o antihorario) de lo contrario Player / Stage se representan correctamente el
polígono. Ahora bien, en la misma forma que hemos construido el cuerpo podemos añadir en algunos dientes de
bigbob para recoger la basura entre:

definir la posición bigbob (

# tamaño real
tamaño [1,25 1]

# la forma de polígonos bigbob 3

# cuerpo

polígono [0] .points 6 polígono [0] .point [0] [0


0] polígono [0] .point [1] [0 1] polígono [0]
.point [2] [0,75 1] polígono [0] .point [3] [1
0,75]

18
Figura 9: La nueva forma de bigbob.

polígono [0] .point [4] [1 0,25] polígono [0]


.point [5] [0,75 0]

# primer polígono diente [1] .points 4 polígono [1]


.point [0] [1 0,75] polígono [1] .point [1] [1,25 0,75]
polígono [1] .point [2] [1.25 0.625] polígono [ 1] .point
[3] [1 0.625]

# segundo polígono diente [2] .points 4 polígono [2]


.point [0] [1 0.375] polígono [2] .point [1] [1.25 0.375]
polígono [2] .point [2] [1,25 0,25] polígono [ 2] .point
[3] [1 0,25]

Declarar el tamaño del robot se utiliza el tamaño [altura anchura] ter paráme-, esto hará que el
polígono se describe a ser escalado a fi t en una caja que es
alto x ancho en tamaño. El tamaño predeterminado es 1 x 1 metro, por lo que debido a la adición de los dientes
de recogida de basuras hizo bigbob más largo, se necesita el parámetro de tamaño de detener Player / Etapa
de hacer el robot más pequeño de lo que debería ser. De esta manera podríamos tener especi fi cada polígono
coordina a ser 4 veces la distancia de separación y luego declaró su tamaño ser 1,25 x 1 metros, y nos darían un
robot del tamaño que queríamos. Para un robot tan grande como bigbob esto no es realmente importante, pero
que podría ser útil en la construcción de modelos de muy pequeños robots. Debe tenerse en cuenta que en
realidad no importa en qué parte del sistema de coordinación nate cartesiano se coloca el polígono, en lugar de
a partir de ( 0, 0) podría fácilmente haber comenzado al (- 1000, 12 345). Con el parámetro polígono que
acabamos

19
Figura 10: Una cuadrícula cartesiana que muestra cómo se describen ángulos.

describe el forma del robot, no su tamaño o ubicación en el mapa. Es posible que haya notado que en figuras 8 y
9 bigbob se enfrenta a la derecha de la cuadrícula. Al colocar cualquier elemento de una simulación de DVD /
Etapa son, por defecto, frente a la parte derecha de la simulación. La figura 5 muestra que las rejillas utilizan un
sistema de coordenadas cartesiano típico, y por lo que si desea modificar la dirección de un objeto en la
simulación está apuntando (su “guiñada”) cualquier ángulo das utilizar el eje x como una referencia, al igual
vectores en un sistema de coordenadas cartesiano (ver fi gura 10) y por lo que la guiñada por defecto es 0 ◦. Esta
es también la razón en el apartado 3.1 del

gui_nose muestra el mapa se enfrenta a la derecha. La Figura 11 muestra algunos ejemplos de robots con pian
Erent di ff.
Por defecto, el jugador / Fase asume el centro del robot de rotación está en su centro geométricas en
base a qué valores se dan al robot de tamaño parámetro. de Bob grande- tamaño es 1,25 x 1 lo que el
jugador / Fase colocará su centro en ( 0,625, 0,5),
lo que significa que las ruedas del bigbob estarían más cerca de sus dientes. En su lugar vamos a decir que el
centro de rotación de bigbob se encuentra en el centro de su cuerpo principal (que se muestra en la fi gura 8), que
pone el centro de rotación al ( 0.5, 0.5). Para cambiar esto en modelo de robot se utiliza el origen [x-offset
y-desplazamiento z-offset] mando:

definir la posición bigbob (

# tamaño real
tamaño [1,25 1]
# centro de origen compensar la rotación
[0,125 0 0]

# la forma de polígonos bigbob 3

. . .
. . .
. . .
)

Por último vamos a especificar el masa y manejar de bigbob, estos son los dos paráme- tros de la posición
modelo y se han descrito anteriormente.

20
Figura 11: A partir de la parte superior derecha robot y trabajando en sentido antihorario, los pian de estos
robots son 0, 90, -45 y 200.

definir la posición bigbob (

# tamaño real
tamaño [1,25 1]
# centro de origen compensar la rotación
[0,125 0 0]

# la forma de polígonos bigbob 3

. . .
. . .
. . .

# cosas positonal masa 10,0


unidad de "Diferencias"

Sensores del robot Ahora que el cuerpo de bigbob se ha construido movimiento Vamos a los sensores. Vamos a
poner sonar y sensores de burbuja fi Nding en bigbob para que se pueda detectar paredes y ver manchas de color
se puede interpretar como basura a recoger. También vamos a poner un láser entre los dientes de bigbob por lo
que puede detectar cuando un artículo pasa entre ellos.

Vamos a empezar con los sonares. Lo primero que hay que hacer es para definir un modelo para el
grupo sonar que va a ser unido a bigbob:

21
Figura 12: La posición de sonares de bigbob (en rojo) con respecto a su origen. El origen está marcado con una
cruz, algunas de las distancias desde el origen a los sensores han sido marcados. El resto de las distancias se
pueden hacer mediante inspección.

definir ranger bigbobs_sonars (

# parámetros ...
)

Aquí nos dirá jugador / de la etapa que vamos a definir un conjunto de sensores de sonar llamado
bigbobs_sonars y estamos utilizando el tipo de modelo guardabosque para contar jugador / Etapa de que este es un modelo
de algunos dispositivos que van. Vamos a poner cuatro sonares en bigbob, uno en la parte frontal de cada diente, y uno en la
parte frontal izquierda y las esquinas delanteras derecha de su cuerpo.

Cuando se construye el cuerpo de bigbob hemos sido capaces de utilizar cualquier ubicación en una cuadrícula nar dinación

que queríamos y podría declarar nuestros polígonos de forma para ser cualquier distancia de separación que quería, siempre que el

cambio de tamaño que el modelo con tamaño. En contraste, los sensores - no todos los sensores sólo guardabosques - deben estar

colocados de acuerdo con el

El robot de origen y tamaño real. Para calcular las distancias en metros que ayuda a hacer un dibujo del lugar donde
los sensores se pondrán a la del robot y sus distancias desde el origen del robot. Cuando nos salió a la forma del
cuerpo de bigbob utilizamos su tamaño real, de modo que podemos utilizar los mismos dibujos de nuevo a trabajar a
cabo las distancias de los sensores desde el origen como se muestra en la fi gura 12.

Ahora sabemos cuántos sensores que queremos, y sus coordenadas en relación con el origen podemos
empezar a construir nuestro modelo de la matriz de sónar. Aquí vamos a utilizar el scount y Spose parámetros
mencionados en 3.2.1. Los valores para Spose son
[Guiñada xy], recuerde que guiñada está en grados y se mide en relación con el X
eje.

definir ranger bigbobs_sonars (

# número de sonares

22
scount 4

# definir la postura de cada transductor [xpos ypos partida] spose [0] [0,75 0,1875 0] #fr
diente izquierdo Spose [1] [0,75 -0,1875 0] #fr diente derecho Spose [2] [0,25 0,5 30] #
esquina izquierda Spose [3] [0.25] -0.5 -30 # esquina derecha

El proceso de elaboración de donde los sensores van en relación con el origen del robot es la parte más
complicada de describir el sensor, el resto es fácil. Para definir el tamaño, el alcance y ámbito de la vista de los
sonares que basta consultar la ficha técnica del aparato de sonar.

definir ranger bigbobs_sonars (

# número de sonares scount


4

# definir la postura de cada transductor [xpos ypos partida] spose [0] [0,75 0,1875 0] #fr
diente izquierdo Spose [1] [0,75 -0,1875 0] #fr diente derecho Spose [2] [0,25 0,5 30] #
esquina izquierda Spose [3] [0.25] -0.5 -30 # esquina derecha

# definir el campo de visión de cada transductor


# [Range_min range_max view_angle] sview [0,3 2,0
10]

# definir el tamaño de cada transductor [xsize ysize] en metros ssize [0,01 0,05]

Ahora que los sonares de bigbob se hacen vamos a adjuntado una burbuja nder fi:

definir bigbobs_eyes blobfinder (

# parámetros
)

Bigbob es una basura de colector por lo que aquí hay que decirle qué color de la basura para buscar. Digamos
que la aplicación prevista del bigbob está en una fábrica de zumo de naranja y que recoge las naranjas callejeros o
cartones de jugo que caen en el suelo. Las naranjas son de color naranja, y cartones de jugo son (digamos) de
color azul oscuro por lo nder burbuja de fi bigbob buscará estos dos colores:

definir bigbobs_eyes blobfinder (

# número de colores para buscar colors_count 2

23
# qué colores para buscar colores [ "naranja"
"DarkBlue"]
)

A continuación, definimos las propiedades de la cámara, de nuevo éstos provienen de la ficha técnica:

definir bigbobs_eyes blobfinder (

# número de colores para buscar colors_count 2

# qué colores para buscar colores [ "naranja"


"DarkBlue"]

# imagen parámetros de la cámara [160


120] gama #resolution 5,00

fov 3.14159 / 3 # 60 grados = pi / 3 radianes


)

En la etapa 2.XX el siguiente código se debe utilizar en su lugar:

# blobfinder de bigbob definir


bigbobs_eyes PTZ (

blobfinder (

# número de colores para buscar channels_count


2

# qué colores para buscar canales [ "naranja"


"DarkBlue"]

# imagen parámetros de la cámara [160


120] #resolution range_max 5,00 PTZ [0 0
60]

)
)

El último sensor que hay que añadir a bigbob es el láser, que se utiliza para detectar cuando un pedazo
de basura que se ha recogido. Siguiendo los mismos principios que para nuestros modelos de sensores
anteriores podemos crear una descripción de este láser:

definir láser bigbobs_laser (

0.0 range_min

# distancia entre los dientes en metros range_max


0,25

24
Figura 13: La posición del láser de bigbob (en rojo) y su distancia, en metros, en relación a su origen
(marcado con una cruz).

fov 3,14159 / 9 # 20 grados = pi / 9 radianes


# FOV 20 # utilizar esta línea en lugar de por encima de si se utiliza 2.XX etapa

plantear [0,625 0,125 270] tamaño


[0,025 0,025]
)

Con este láser hemos establecido su alcance máximo a ser la distancia entre los dientes, y el campo de
vista se fija arbitrariamente a 20 ◦. Hemos calculado el láser de
pose exactamente de la misma manera que los sonares Spose, mediante la medición de la distancia del centro del láser al
centro de la robot de rotación, de guiñada del láser se establece en 270 ◦ de manera que apunte a través de los dientes de
bigbob. También establecemos el tamaño del láser para ser 2,5 cm cuadrado, de manera que no obstruya el espacio entre
los dientes de bigbob.
Ahora que tenemos un cuerpo y sensores modelos de robot todos los que tenemos que hacer es ponerlos
juntos y colocarlos en el mundo. Para agregar los sensores en el cuerpo que tenemos que volver a la bigbob
posición modelo:

definir la posición bigbob (

# tamaño real
tamaño [1,25 1]
# centro de origen compensar la rotación
[0,125 0 0]

# la forma de polígonos bigbob 3

. . .
. . .
. . .

25
# cosas positonal masa 10,0
unidad de "Diferencias"

# sensores conectados a bigbob


bigbobs_sonars () bigbobs_eyes () ()
bigbobs_laser

La línea adicional bigbobs_sonars () agrega el modelo de sonar llamada bigbobs_sonars ()


sobre la bigbob modelo, del mismo modo para bigbobs_eyes () y bigbobs_laser ().
Después de este paso fi nal ahora tenemos un modelo completo de nuestra bigbob robot, el código completo del que
se puede encontrar en el Apéndice A. En este punto vale la pena copiar esto en un .inc fi l, por lo que el modelo
podría ser utilizado de nuevo en otras simulaciones o mundos.

Para poner nuestro modelo bigbob en nuestro mundo vacío (véase la sección 3.1.3) tenemos que añadir el robot a
nuestro mundo fi l empty.world:

Incluir "map.inc" incluyen


"bigbob.inc"

# tamaño de todo el tamaño de simulación [15


15]

# configurar la ventana ventana de interfaz gráfica de

usuario (

tamaño [700,000 700,000] escalar


0,025
)

# cargar un mapa de entorno de mapa de bits (

mapa de bits "mapas de bits / cave.png"


tamaño [15 15]
)

bigbob (

nombrar "bob1" pose [-5


-6 45] de color "rojo"

Aquí hemos puesto todo el ff Stu que describe bigbob en un .inc fi l bigbob.inc,
y cuando incluimos esto, todo el código de la .inc fi l se inserta en el

26
. fi l mundo. La sección aquí es donde ponemos una versión del modelo bigbob en nuestro mundo:

bigbob (

nombrar "bob1" pose [-5


-6 45] de color "verde"

Bigbob es una descripción del modelo, al no incluir cualquier definir ff Stu en la línea superior no significa que
estamos haciendo una instancia de ese modelo, con el nombre bob1. Usando una analogía de programación
orientado a objetos, bigbob Es nuestra clase, y bob1 es nuestro objeto de clase bigbob. los plantear [xy de
guiñada] las obras de los parámetros de la misma fue tan Spose [guiñada xy] hace. Los únicos erences ff di son
las coordenadas que utilizan el centro de la simulación como un punto de referencia y pose

nos permite especificar la posición inicial y el rumbo de la totalidad bob1 modelo, no sólo un sensor dentro de
ese modelo. Finalmente especificamos qué color bob1 debe ser, por defecto, ésta es de color rojo. los pose y color
parámetros podrían haber sido especificados en nuestro modelo bigbob sino por dejarlos fuera que nos
permite variar el color y la posición de los robots para cada robot di ff Erent de tipo bigbob, para que
pudiéramos declarar múltiples robots que son del mismo tamaño, forma y con los mismos sensores, sino que
son prestados por el jugador / Fase en colores Erent di ff y se inicializan en puntos di ff Erent en el mapa.

Cuando corremos el nuevo empty.world con el jugador / Fase vemos nuestro robot bigbob está ocupando el mundo,
como se muestra en la fi gura 14. La marca oscura en la parte superior del robot es la cámara burbuja visor.

FF 3.3 Otros edificios Stu

Hemos establecido en el apartado 3.2.2 que bigbob trabaja en una fábrica de zumo de naranja recogida de naranjas y
cartones de jugo. Ahora tenemos que construir modelos para representar las naranjas y cartones de jugo de manera que
bigbob puede interactuar con las cosas.
Vamos a empezar por la construcción de un modelo de una naranja:

definir modelo de color naranja (

# parámetros ...
)

El primero que fi para definir es la forma de la naranja. los polígonos parámetro es una forma de hacer esto, que
podemos utilizar para construir una aproximación de bloque de un círculo. Una alternativa a esto es utilizar mapa
de bits que anteriormente vimos que utilizamos para crear un mapa. Lo que el comando de mapa de bits que
realmente hace es tomar una imagen, y convertirla en una serie de polígonos que están conectados juntos para
hacer un modelo de la misma forma que la imagen. Esto se ilustra en la fi gura 15. Para deshacerse de los
contornos de los bloques añadir gui_outline 0 a la descripción del modelo, con el gran fantasma en la fi gura 15
que no se trata tanto de un problema, pero con modelos más pequeños, como una naranja, los contornos negros
prevenir el color del modelo de ser visibles.

27
Figura 14: Nuestro robot bob1 colocado en el mundo vacío.

Figura 15: La imagen de la izquierda es la imagen original, la imagen de la derecha es su interpretación


jugador / Fase.

28
Figura dieciséis:

. /bitmaps/circle.png

Figura 17: El modelo de naranja prestados en la misma ventana del


reproductor / Stage como bigbob.

definir modelo de color naranja (

mapa de bits "mapas de bits / circle.png" tamaño


de [0,15 0,15] de color "naranja"

gui_outline 0
gripper_return 1
)

En este código se describe un modelo llamado naranja que utiliza un mapa de bits para definir su forma y
representa un objeto que es de 15 cm por 15 cm y de color naranja. los gripper_return parámetro es un tipo
especial de retorno, porque significa que el modelo puede ser agarrado por pinzas de un robot pero además significa
que el objeto puede ser empujado un poco en la simulación. Queremos que nuestro modelo de color naranja que
se puede empujar a ser así, a pesar de que no tiene bigbob pinza, el naranja de gripper_return

parámetro se establece en verdadero. La figura 17 muestra nuestro modelo de naranja junto a bigbob.

La construcción de un modelo de cartón de jugo es igualmente muy fácil:

definir modelo de caja de cartón (

# una caja de cartón es retangular


# así que hacer una forma y uso tamaño cuadrado [] polígonos
1 polígono [0] .points 4 polígono [0] .point [0] [0 0] polígono [0]
.point [1] [0 1] polígono [0]. punto [2] [1 1] polígono [0] .point [3]
[1 0]

# tamaño medio de la caja de cartón es de ~ 20 cm x 10 cm x 5 cm de tamaño


[0,1 0,2]

Color "DarkBlue"
gripper_return 1
)

29
Podemos utilizar el polígonos comandos desde cartones de jugo son en forma de caja, con las cosas en forma de caja
que es un poco más fácil para describir la forma con polígono que dibujar un mapa de bits y el uso de eso.

Ahora que hemos descrito básica naranja y caja de cartón modelos es el momento de poner un poco de
naranjas y cajas de cartón en la simulación. Esto se realiza de la misma manera que nuestro robot ejemplo, se puso
en el mundo:

naranja (

nombrar "Orange1"
pose [-2 -5 0]
)

cartón (

nombrar "carton1"
pose [-3 -5 0]
)

Hemos creado modelos de naranjas y cartones, y ahora estamos declarando que no habrá una instancia de
estos modelos (llamado Orange1 y carton1 respectivamente) en las posiciones dadas. A diferencia con el
robot, declaramos la color de los modelos en la descripción, así que no tenemos que hacer eso aquí. Si
tuviéramos colores Erent di ff para cada color naranja o cartón entonces sería estropear la burbuja hallazgo
en bigbob porque el robot sólo es la búsqueda de naranja y azul oscuro. En este punto, sería útil si
pudiéramos tener más de una naranja o cartón en el mundo (bigbob no sería muy ocupado si no había
mucho para recoger), resulta que esto también es bastante fácil:

naranja (nombre "Orange1" pose [-1 -5 0]) naranja (nombre


"orange2" pose [-2 -5 0]) naranja (nombre "orange3" pose [-3
-5 0]) naranja (nombre "orange4 "pose [-4 -5 0])

caja de cartón (nombre "carton1" pose [-2 -4 0]) del cartón


(nombre "carton2" pose [-2 -3 0]) del cartón (nombre
"carton3" pose [-2 -2 0]) del cartón ( "carton4 nombre "pose
[-2 -1 0])

Hasta ahora hemos descrito los modelos con cada parámetro en una nueva línea, esto es sólo una
forma de hacer más legible para el programador - especialmente si hay una gran cantidad de parámetros.
Si hay sólo unos pocos parámetros o si desea repetir el código (como lo hemos hecho aquí) todo se puede
poner sobre una línea. Aquí declaramos que habrá cuatro naranja modelos de la simulación con los
nombres Orange1 a orange4, también tenemos que especificar Erent di ff posa para los modelos por lo que
no son todos una encima de la otra. Propiedades que los modelos de color naranja tienen en común (como
forma, color o tamaño) todos deben estar en el modelo de definición.

El mundo lleno fi l se incluye en el apéndice B, esto incluye los modelos de cartón de color naranja y,
así como el código de su puesta en la simulación. La Figura 18 muestra el poblado de simulación / Stage
jugador.

30
Figura 18: El robot bigbob colocado en la simulación a lo largo de basura para que pueda recoger.

4 Escribir una con fi guración (.cfg)


Como se mencionó anteriormente, el jugador es una capa de abstracción de hardware que conecta el
código al hardware del robot. Para ello, actuando como un programa de tipo servidor / cliente en su código
y sensores del robot son clientes a un servidor de jugador que luego pasa los datos e instrucciones en torno
a donde todo tiene que ir. Este ff Stu se explicará adecuadamente en la sección 5, todo suena más
complicado de lo que se debe a jugador / de la etapa se encarga de toda la di fi ff Stu culto. La con fi
guración fi l se necesita con el fin de indicar al servidor de Jugador que los conductores utilizar y una
interfaz u los conductores van a utilizar.

Para cada modelo en la simulación o dispositivo en el robot que desea interactuar con, tendrá que
especificar un controlador. Esto es mucho más fácil que escribir mundo fi l de la información, y sigue la
misma sintaxis general. La especificación conductor fi es en la forma:

controlador (

nombre "driver_name" proporciona


[DEVICE_ADDRESS]
# otros parámetros ...
)

los nombre y proporciona parámetros son datos obligatorios, sin ellas jugador no sabrá qué controlador de
usar (dada por nombre) y qué tipo de informa- ción proviene de que el conductor ( proporciona). los nombre parámetro
no está

31
arbitraria, que debe ser el nombre de uno de los conductores incorporados del jugador 17 que se han escrito para el jugador
para interactuar con un dispositivo de robot. Una lista de los nombres de los controladores compatibles es en el Manual del
jugador 18, aunque cuando se utiliza etapa el único que se necesita es " escenario".

los proporciona parámetro es un poco más complicado de lo nombre. Es aquí que le diga qué jugador interfaz
para utilizar con el fin de interpretar la información dada por el conductor (a menudo se trata de información de los
sensores de un robot), cualquier información que un conductor proporciona puede ser utilizado por su código. Para un
robot simulado la etapa " escenario" conductor puede proporcionar las interfaces a los sensores discutidos en la
sección
3.2.1. Cada interfaz comparte el mismo nombre que el modelo de sensor, por lo que por ejemplo una guardabosque
modelo usaría el guardabosque interfaz para interactuar con el jugador y así sucesivamente (la única excepción a
esto es el posición modelo que utiliza el
position2d interfaz). El manual Player contiene una lista de todas las interfaces Erent di ff que se puede
utilizar 19, los más útiles ya se han mencionado en la sección 3.2.1, aunque hay otros también numerables
para enumerarlos aquí.
La entrada a la proporciona parámetro es una “dirección de dispositivo”, que es especificaciones qué puerto de una interfaz
a un dispositivo de robot TCP se pueden encontrar, sección 4.1 tiene más información acerca de las direcciones del dispositivo.
Este utiliza la clave: host: robot: forma de índice separado por espacios en blanco: interfaz.

proporciona [ "clave: host: robot: Interfaz: índice"


"Clave: host: robot: Interfaz: Índice tecla" ": host:
robot: Interfaz: índice"
. . .]

Después de los dos parámetros obligatorios, el siguiente parámetro piloto más útil es modelo. Esto sólo se
utiliza si " escenario" es el conductor, que le dice a jugador, que en particular modelo en el mundo fi l se establecen
las interfaces de este controlador en particular. Se necesita un conductor Erent di ff para cada modelo que desea
utilizar. Los modelos que no están obligados a hacer nada (como un mapa, o en el ejemplo de la sección 3.3
naranjas y cajas) no necesita tener un controlador por escrito para ellos. Los parámetros del controlador restantes
son requiere y enchufar. los requiere se utiliza para los conductores que necesitan información de entrada, tales
como " VFH", se dice que este conductor donde de encontrar esta información y cuál es la interfaz que utiliza. los requiere
rámetro pa- utiliza la misma clave: host: robot: sintaxis índice como la: Interfaz proporciona

parámetro. Finalmente, el enchufar parámetro se utiliza para contar jugador dónde hallar toda la información
sobre el controlador que se utiliza. Anteriormente hemos hecho una .cfg fi l con el fin de crear una simulación de
un mundo vacío (o al menos sin moverse), la .cfg fi l dice lo siguiente:

controlador (

nombre de "etapa"
plug-in "libstageplugin"

proporciona [ "simulación: 0"]

17 También es posible construir sus propios controladores para un dispositivo de hardware, pero este documento no voy a entrar en cómo hacer

esto porque no es relevante para el Jugador / Fase.


18 http://playerstage.sourceforge.net/doc/Player-2.1.0/player/group drivers.html
19 http://playerstage.sourceforge.net/doc/Player-2.1.0/player/group interfaces.html

32
# cargar el archivo con el nombre en el simulador Worldfile
"empty.world"
)

Esto tiene que ser hecho en el comienzo de la con fi guración fi l porque cuenta del jugador que hay un conductor
llamado " escenario" que vamos a utilizar y el código para hacer frente a este controlador se puede encontrar en el libstageplugin
enchufar. Esto tiene que ser especi fi cado para la Etapa Etapa porque es un add-on para el jugador, para los
conductores que están integradas en el reproductor por defecto enchufar no necesita ser especi fi cado.

4.1 las direcciones del dispositivo - llave: host: robot: Interfaz: Índice

Una dirección del dispositivo se utiliza contar jugador donde el conductor está haciendo presentará (o
recibir) información y qué interfaz utilizar con el fin de leer esta información. Se trata de una cadena de la
forma clave: host: robot: Interfaz: Índice
donde cada campo está separado por dos puntos.

• llave: El jugador manual indica que: “El propósito de la esfera clave es permitir un controlador que
soporta múltiples interfaces del mismo tipo para mapear esas interfaces en dispositivos Erent di ff” [ 1].
Esto es una cosa nivel de controlador y tiene mucho que ver con el nombre del controlador que está
utilizando, generalmente para
"escenario" el llave no tiene que ser utilizado. Si está utilizando jugador sin Etapa entonces hay una sección útil
acerca de las teclas de dirección del dispositivo en el manual del jugador 20.

• anfitrión: Esta es la dirección del servidor donde está ubicado el dispositivo. Con un robot que podría
ser la dirección IP del robot. El host predeterminado es “localhost”, que significa que el equipo en el
que se está ejecutando jugador.

• robot: este es el puerto TCP a través de la cual el jugador debe esperar para recibir datos desde la
interfaz por lo general un solo robot y todas sus caras necesarias interrelaciones son asignados a un
puerto. El puerto por defecto es 6665, si había dos robots en la simulación de los puertos podría ser
6665 y 6666 aunque no hay regla que dicho número de puertos que puede o no puede usar.

• interfaz: La interfaz a utilizar con el fin de interactuar con los datos. No hay un valor predeterminado
para esta opción, ya que es un campo obligatorio.

• índice: Si un robot tiene varios dispositivos del mismo tipo, por ejemplo que tiene 2 cámaras para dar
la percepción de la profundidad robot, cada dispositivo utiliza la misma interfaz pero da ligeramente di
información ff Erent. El campo de índice fi le permite dar un poco di ff dirección Erent a cada
dispositivo. Así que dos cámaras podrían ser Cámara: 0 y la cámara: 1. Esto es muy di ff Erent de la llave

campo porque tener un “conductor que soporta múltiples interfaces del mismo tipo” no es lo mismo que
tener múltiples dispositivos que utilizan la misma interfaz. Una vez más no existe un índice por defecto,
ya que este es un campo obligatorio en la dirección del dispositivo, pero se debe utilizar 0 como el
índice si no hay uno solo de ese tipo de dispositivo.

Si desea utilizar cualquiera de los valores por defecto que sólo se puede dejar fuera de la dirección del dispositivo. Así
que podríamos utilizar el host y el puerto predeterminados robot y especificar (por ejem- plo) una interfaz láser sólo por
hacer " láser: 0" . Sin embargo, si desea especificar

20 http://playerstage.sourceforge.net/doc/Player-2.1.0/player/group con fi g.html clave del dispositivo tutorial #

33
campos al comienzo de la dirección del dispositivo, pero no en el medio después de los dos puntos de calificación
SEPA deben permanecer. Por ejemplo si tenemos un anfitrión " 127.0.0.1" con un láser Interfaz entonces sería
especificar la dirección como " 127.0.0.1::laser:0" ,
el campo robot fi está vacía, pero los dos puntos a su alrededor todavía están allí. Usted puede notar que la fi eld clave
aquí fue dejada o FF como antes.

4.2 Poner el archivo de con fi guración de Juntos

Hemos examinado los comandos necesarios para construir un controlador para un modelo en el mundo fi l, ahora
es sólo un caso de poner a todos juntos. Para demostrar este proceso vamos a construir una con fi guración fi l
para el mundo desarrollado fi l en el apartado
3. En este mundo queremos que nuestro código sea capaz de interactuar con el robot, por lo que en nuestra con fi guración fi l
tenemos que especificar un controlador para este robot.

controlador (

# parámetros ...
)

El conductor incorporado que el jugador / Etapa utiliza para simulaciones se llama " escenario"
por lo que el nombre del controlador es " etapa".

controlador (

nombre de "etapa"
)

Los usos robot bigbob posición, láser, blobfinder y guardabosque sensores. Estos corresponden a la position2d,
láser, blobfinder e interfaces respectiva- mente. los guardabosque sensor es un caso especial ya que la
interfaz de guardaparques no se ha implementado en la actualidad (para las versiones de la etapa 3.0.1 o
anterior). Para solucionar este tendrá que utilizar el sonar interfaces de su lugar (hay al parecer una interfaz
IR que podría ser utilizado en lugar de guardabosque, pero no parece funcionar en cualquier etapa 2 o etapa
3).

Queremos que nuestro código sea capaz de leer a partir de estos sensores, por lo que necesitamos para declarar
las interfaces para ellos y decirle reproductor dónde hallar los datos de cada dispositivo, para ello se utilizan las con fi
guración fi l de proporciona parámetro. Esto requiere que construimos direcciones de dispositivo para cada sensor;
recordar, esto es en la clave: host: formato de índice: robot: interfaz. No estamos utilizando los controladores de lujo,
por lo que no es necesario especificar una clave. Estamos funcionando con nuestro robot en una simulación en el
mismo equipo como nuestro Sever jugador, por lo que el nombre de host es localhost que es el valor por defecto, por lo
que también no es necesario especificar un host. El robot es un puerto TCP para recibir información robot sobre,
recogida de qué puerto usar es bastante arbitraria, sino que lo que suele ocurrir es que el primer robot utiliza el puerto
por defecto utilizan 6665 y los robots posteriores 6666, 6667, 6668, etc. Sólo hay un robot en nuestra simulación de lo
que vamos a utilizar el puerto 6665 para toda nuestra información de los sensores de este robot. Sólo tenemos un
sensor de cada tipo, por lo que nuestros dispositivos no necesitan índices separados. ¿Qué pasaría si tuviéramos
varios sensores del mismo tipo (como decir dos cámaras) es que ponemos el dispositivo primero en el índice 0 y
dispositivos posteriores utilizando la misma interfaz que el índice 1, luego 2, luego 3 y así sucesivamente. 21 Finalmente
nosotros

21 Hay un montón de sensores de guardaparques en nuestro modelo, pero cuando creamos sensores del robot en el apartado 3.2.2 que

poner a todos en el mismo modelo Ranger. En lo que a la con fi guración fi l

34
utilizar interfaces apropiadas para los sensores del robot tiene, por lo que en nuestro ejemplo se trata de la posición,
láser, blobfinder interfaces y para nuestra guardabosque dispositivos que utilizarán sonar.

Juntando todo esto bajo la proporciona parámetro nos da:

controlador (

nombre de "etapa"
proporciona [ "6665: position2d: 0"
"6665: el sonar: 0" "6665:
blobfinder: 0" "6665: láser: 0"]

Las direcciones de los dispositivos pueden estar en la misma línea que el uno al otro o separados líneas, con tal de que
están separados por alguna forma de espacio en blanco.
La última cosa que hacer en nuestro conductor es la modelo "nombre_del_modelo" parámetro que debe ser
especi fi cado porque estamos utilizando jugador / Fase. Esto le dice al software de simulación que cualquier cosa
que hacer con este controlador a una ff ect el modelo
"nombre del modelo" en la simulación. En la simulación se construyó hemos llamado a nuestro robot modelo “bob1”, por lo
que nuestro conductor fi nal para el robot será:

controlador (

nombre de "etapa"
proporciona [ "6665: position2d: 0"
"6665: sonar: 0" "6665:
blobfinder: 0" "6665: láser: 0"]
modelo "bob1"

Si nuestra simulación tenía múltiples robots en bigbob, las con fi guración fi l de los conductores serían muy
similares entre sí. Si creamos un segundo robot en nuestro mundo fi le y lo llamamos “bob2” entonces el
conductor sería la siguiente:

controlador (

nombre de "etapa"
proporciona [ "6666: position2d: 0"
"6666: sonar: 0" "6666:
blobfinder: 0" "6666: láser: 0"]
modelo "bob2"

Tenga en cuenta que el número de puerto y el nombre del modelo son los únicos erences di ff debido a que los robots tienen todos

los mismos sensores.

se refiere sólo hay un dispositivo que rabia utilizando el sonar o interfaz IR, porque todos los dispositivos de Ranger separados se agrupan
en éste modelo. No necesitamos que declaren cada Ranger en un índice de su propio.

35
Un conductor de este tipo se puede construir para cualquier modelo que se encuentra en la fi le mundo, no sólo a los
robots. Por ejemplo, un controlador de mapa se puede hacer que utiliza el
mapa interfaz y le permitirá obtener datos de tamaño, origen y ocupación sobre el mapa. El único requisito es
que si quieres hacer algo para el modelo con su código, entonces usted necesita para construir un controlador
para ello en la con fi guración fi l. Finalmente, cuando ponemos el bit que declara la escenario controlador
(esta parte es obligatoria para cualquier simulación con fi guración fi l) junto con nuestros conductores para el
robot nos encontramos con nuestro final con fi guración fi l:

controlador (

nombre de "etapa"
plug-in "libstageplugin"

proporciona [ "simulación: 0"]

# cargar el archivo con el nombre en el simulador Worldfile


"worldfile_name.world"
)

controlador (

nombre de "etapa"
proporciona [ "6665: position2d: 0"
"6665: sonar: 0" "6665:
blobfinder: 0" "6665: láser: 0"]
modelo "bob1"

5 Obtención de su simulación para ejecutar el código


Para aprender cómo escribir código para el jugador o el jugador / Etapa ayuda a entender la estructura básica de
cómo funciona jugador. Jugador utiliza una estructura de servidor / cliente con el fin de transmitir datos e
instrucciones entre el código y el hardware del robot. El jugador es un servidor y un dispositivo de hardware 22 en el
robot está suscrito como cliente al servidor a través de una cosa que se llama una apoderado. El .cfg fi l asociado
con el robot (o su simulación) se encarga de decirle al servidor de Jugador que los dispositivos están conectados a
la misma, por lo que cuando se corre el comando El jugador some_cfg.cfg esto se pone en marcha el servidor
Player y conecta todos los dispositivos de hardware necesarios para el servidor. La Figura 19 muestra un diagrama
de bloques básico de la estructura de jugador cuando se implementa en un robot. En Reproductor / Fase mismo
comando iniciará el servidor del jugador y la carga hasta el mundo fi l en una ventana de simulación, este se ejecuta
en el ordenador y permite que su código para interactuar con la simulación en lugar de hardware. La Figura 20
muestra un diagrama de bloques básico de la estructura del jugador / Fase. El código también debe inscribirse en el
servidor del jugador para que pueda acceder a estos servidores proxy y por lo tanto controlar el robot. Jugador tiene
funciones y clases que será

22 recuerde, un dispositivo es una pieza de hardware que utiliza un controlador que se ajusta a una interfaz. Véase la sección 2.2

36
Figura 19: La estructura de control de servidor / cliente de jugador cuando se utiliza en un robot. Puede haber varios
servidores proxy conectados al servidor en cualquier momento.

hacer todo esto para usted, pero usted todavía tiene que llamar en realidad estas funciones con su código y saber
cómo usarlos.
Player es compatible con C, C ++ o código Python, sin embargo, en este manual vamos a realmente sólo
utilizaremos C ++, ya que es el más sencillo de entender. El proceso de escribir código de jugador es
prácticamente el mismo para cada idioma Erent di ff sin embargo. Las funciones de proxy del jugador y el jugador
tienen nombres di ff Erent para cada idioma, pero el trabajo en más o menos de la misma manera, por lo que
incluso si usted no planea usar C ++ o etapa de esta sección todavía contendrán información útil.

Antes de iniciar un proyecto, es muy recomendable que para cualquier programa que no sean ejemplos
básicos que siempre debe envolver los comandos del jugador alrededor de sus propias funciones y clases para
que todas las interacciones de su código con el jugador se mantienen juntos el mismo archivo. Esto no es un
requisito del jugador, es sólo una buena práctica. Por ejemplo, si la actualiza jugador o si por alguna razón se
rompe el robot y una cierta función ya no funciona sólo tiene que cambiar parte de un expediente en lugar de
buscar a través de todo el código para los lugares donde se han utilizado las funciones del reproductor.

Por último, con el fin de compilar el programa que utilice los siguientes comandos (en Linux):

g ++ -o example0 `pkg-config --cflags playerc ++` `example0.cc pkg-config


- - libs playerc ++ `
Eso va a compilar un programa a un fi l de llamada example0 desde el C ++ código fi le example0.cc. Si
está codificando en C entonces utilizar la siguiente com- mand:

gcc -o example0 `pkg-config --cflags playerc` example0.c` pkg-config


- - libs playerc`

5.1 Conexión con el servidor proxy y con su código

La primera cosa que hacer fi dentro de su código es incluir la cabecera jugador fi l. Suponiendo jugador / Stage
está correctamente instalado en su máquina, entonces esto puede ser

37
Figura 20: La estructura de control de servidor / cliente de jugador / Stage cuando se utiliza como un simulador. Puede
haber varios servidores proxy conectados al servidor en cualquier momento.

hecho con la línea # incluir <libplayerc ++ / playerc ++. h> ( si estás usando C # a continuación, escriba incluir
<libplayerc / playerc.h> en lugar).
Lo siguiente que necesitamos para establecer un Cliente jugador, que interactuará con el servidor de jugador para usted.
Para ello utilizamos la línea:

client_name PlayerClient (nombre de host, puerto);

Lo que hace esta línea es declarar un nuevo objeto que se llama un PlayerClient
nombre del cliente que conecta con el servidor del jugador en la dirección indicada. El nombre de host y el
puerto es como se discutió en la sección 4.1. Si el código esté en funcionamiento, en el mismo equipo (o
robot) como el servidor de jugador que desee conectar a continuación el nombre de host es “localhost” de lo
contrario será la dirección IP del ordenador o un robot. El puerto es un parámetro opcional por lo general
sólo es necesario para las simulaciones, será el mismo que el puerto que diste en el .cfg fi l. Esto sólo es
útil si la simulación tiene más de un robot y se necesita el código para conectarse a los dos robots. Así que
si usted dio su puerto robot primera 6665 y el segundo de 6666 (al igual que en el ejemplo de la sección
4.2) entonces se necesitarían dos PlayerClients, uno conectado a cada robot, y que harían esto con el
siguiente código:

PlayerClient robot1 ( "localhost", 6665); PlayerClient robot2 (


"localhost", 6666);

Si sólo está utilizando un robot y en su .cfg fi l que ha dicho que operaría en el puerto 6665, entonces no se
necesita el parámetro de puerto a la clase PlayerClient.

Una vez que hemos establecido una PlayerClient debemos conectar nuestro código para los vice proxies de-
manera que podamos intercambiar información con ellos. ¿Qué servidores proxy se puede conectar a su
código depende de lo que han puesto en su con fi gura- ción fi l. Por ejemplo, si su con fi guración fi l dice que
el robot está conectado a un láser, pero no es una cámara se puede conectar al dispositivo láser, pero no la
cámara, incluso si el robot (o simulación de robots) tiene una cámara en él.

38
Proxies toman el nombre de la interfaz que los conductores utilizan para hablar con jugador. Vamos a tomar
parte del ejemplo bigbob con fi guración fi l de la sección 4.2:

controlador (

nombre de "etapa"
proporciona [ "6665: position2d: 0"
"6665: el sonar: 0" "6665:
blobfinder: 0" "6665: láser: 0"]

Aquí hemos dijeron que el servidor que nuestro jugador “robot” tiene dispositivos que utilizan las interfaces
position2d, sonar, nder burbuja fi y láser. En nuestro código, a continuación, hay que conectarse a los position2d,
sonar, nder burbuja fi y láser proxies, así:

Position2dProxy positionProxy_name (y client_name, index); SonarProxy


sonarProxy_name (y client_name, index);
BlobfinderProxy blobProxy_name (y client_name, index); LaserProxy
laserProxy_name (y client_name, index);

Una lista completa de los cuales como proxy soportes del jugador se puede encontrar en el manual del jugador 23,

todos ellos siguen la convención de ser el nombre de la interfaz que utilizan. En el caso anterior xProxy_name
es el nombre que desea dar al objeto proxy,
nombre del cliente es el nombre que le dio el objeto anterior y PlayerClient índice es el índice que el
dispositivo se le dio en su con fi guración fi l (probablemente 0).

5.1.1 Configuración de las conexiones: un Ejemplo.

Para un ejemplo de cómo conectar a las severas Player y dispositivos proxies usaremos el ejemplo con fi guración
fi l desarrollado en la sección 4.2. Para mayor comodidad esto se reproduce a continuación:

controlador (

nombre de "etapa"
plug-in "libstageplugin"

proporciona [ "simulación: 0"]

# cargar el archivo con el nombre en el simulador Worldfile


"worldfile_name.world"
)

controlador (

nombre de "etapa"
proporciona [ "6665: position2d: 0"
"6665: el sonar: 0" "6665:
blobfinder: 0"
23 http://playerstage.sourceforge.net/doc/Player-2.1.0/player/classPlayerCc 1 1ClientProxy.html

39
"6665: láser: 0"] modelo
"bob1"
)

Para configurar una PlayerClient y luego conectarse a servidores proxy en ese servidor podemos utilizar los principios
discutidos en esta sección para desarrollar el siguiente código:

# incluir <stdio.h>
# incluir <libplayerc ++ / playerc ++. h>

int main (int argc, char * argv []) {

/ * Necesita hacer esta línea en C ++ solamente * / PlayerCc


utilizando espacio de nombres;

PlayerClient robot ( "localhost");

Position2dProxy p2dProxy (y robot, 0); SonarProxy


sonarProxy (y robot, 0);
BlobfinderProxy blobProxy (y robot, 0); LaserProxy
laserProxy (y robot, 0);

// cierto control código de


retorno 0; }

5.2 Interacción con los servidores proxy

Como se puede esperar, cada proxy está especializada hacia el control del dispositivo que se conecta. Esto
significa que cada proxy tendrá comandos di ff Erent Dependiendo de lo que controla. En Player versión 2.1.0
hay 38 di ff proxies Erent que se puede optar por utilizar, muchas de las cuales no son aplicables a jugador /
Fase. Este manual no pretende explicar a todos ellos, una lista completa de los proxies avaliable y sus
funciones se encuentra en el manual del jugador 24, aunque las devoluciones, parámetros y propósito de la
función proxy no siempre se explica. Los siguientes pocos servidores proxy son probablemente los más útiles
para cualquier persona que utilice jugador o jugador / Fase.

5.2.1 Position2dProxy

El Position2dProxy es el número uno de proxy más útil que existe. Controla los motores del robot y realiza
un seguimiento de odometría del robot (donde el robot piensa que se basa en lo lejos que sus ruedas se
han movido).

Obtener / SetSpeed los Velocidad fijada comando se utiliza para contar los motores del robot lo rápido que a su vez. Hay
dos di ff Erent Velocidad fijada los comandos que se pueden llamar, es uno de los robots que se pueden mover en
cualquier dirección y el otro es para robots con ff on diferencial o unidades de automóviles similares.

• SetSpeed ​(doble xSpeed, doble YSpeed, doble YawSpeed)


24 http://playerstage.sourceforge.net/doc/Player-2.1.0/player/classPlayerCc 1 1ClientProxy.html

40
Figura 21: Un robot en una cuadrícula cartesiana. . Esto muestra qué direcciones X e Y velocidades hará que
el robot se mueva en una velocidad de guiñada positiva a su vez, el robot en la dirección de la flecha +, una
velocidad de guiñada negativa es la dirección de la - flecha.

• SetSpeed ​(doble xSpeed, doble YawSpeed)

• SetCarlike (doble xSpeed, doble DriveAngle)

La Figura 21 muestra la dirección en las direcciones X, Y y guiñada velocidades son en relación con el robot. La
velocidad de x es la velocidad a la que el robot se mueve hacia adelante y la velocidad y es la velocidad del robot hacia
los lados, ambos son para ser dado en metros por segundo. La velocidad y sólo será útil si el robot que desee simular o
de control es una bola, ya que los robots con ruedas no se pueden mover hacia los lados. Los controles de velocidad
de guiñada lo rápido que el robot está girando y se da en radianes por segundo, jugador tiene una función global
llamada incorporado DTOR () que convierte un número en grados en un número en radianes, que podría ser útil cuando
se ajuste de la velocidad de guiñada. Si desea simular o controlar un robot con un sistema de accionamiento diferencial
di ff entonces usted necesita para convertir velocidades de las ruedas izquierda y derecha en una velocidad de avance
y una velocidad de giro antes de enviarlo al proxy. Para las unidades de coche-como existe la SetCarlike

que, de nuevo es la velocidad de avance en m / s y el ángulo de accionamiento en radianes.


los GetSpeed comandos son esencialmente el reverso de la SetSpeed ​com- Mand. En lugar de establecer una
velocidad regresan la velocidad actual en relación con el robot (lo que x es la velocidad de avance, de guiñada es la
velocidad de giro y así sucesivamente).

• GetXSpeed: velocidad de avance (m / seg).

• GetYSpeed: de lado (perpendicular) Velocidad (metros / seg).

• GetYawSpeed: la velocidad de giro (radianes / seg).

Obtener Pos Esta función interactúa con odometría del robot. Se le permite controlar que el robot piensa
que es. Valores de coordenadas se dan en relación a su punto de partida, y el pian son en relación con su
guiñada de partida.

• GetXPos (): da x actuales de coordenadas respecto a su posición x de partida.

41
• GetYPos (): da y actual de coordenadas respecto a su posición y de partida.

• GetYaw (): da guiñada actual en relación con su guiñada de partida. En la sección 3.2.1, que se
especi fi ca si sería grabar odometría por mensurables ing la cantidad de sus ruedas se han convertido, o si
el robot tendrían conocimiento perfecto de sus coordenadas actuales (por defecto el robot no registra
odometría en absoluto) . Si establece el robot para grabar odometría utilizando sus ruedas a continuación,
las posiciones devueltos por éstos reciben órdenes serán cada vez más inexacta como la simulación
continúa. Si desea registrar su posición de robots mientras se mueve alrededor, estas funciones junto con la
odometría perfecta 25 ajuste se puede utilizar.

SetMotorEnable () Esta función toma una entrada booleana, contando jugador si desea activar los motores o no.
Si los motores están desactivados, el robot no se mueve, no importa lo que se les da órdenes para que, si los
motores se activan entonces los motores trabajarán siempre, esto no es tan deseable si el robot está en un
escritorio o algo y es probable que Dañarse. De ahí que los motores están habilitados es opcional. Si está
utilizando Reproductor / Stage, entonces siempre se habilitarán los motores y este comando no necesita ser
ejecutado. Sin embargo, si alguna vez es probable que su código para ser trasladado a un robot real y los
motores no están habilitadas de forma explícita en el código, entonces puede llegar a gastar mucho tiempo
tratando de averiguar por qué el robot no está funcionando.

5.2.2 SonarProxy

El proxy sonar puede ser utilizado para recibir la distancia desde el sonar de un obstáculo en metros. Para
ello se utiliza el comando:

• sonarProxy_name [sonar_number]

Dónde sonarProxy_name es el objeto SonarProxy y sonar_number es el número de la Ranger. En


Reproductor / Fase de sonar los números provienen del orden en el que usted describe los dispositivos
Ranger en el mundo fi l. En la sección 3.2.2 describimos los sensores de Ranger para el robot bigbob así:

definir ranger bigbobs_sonars (

# número de sonares scount


4

# definir la postura de cada transductor [xpos ypos partida] spose [0] [0,75 0,1875 0] #fr
diente izquierdo Spose [1] [0,75 -0,1875 0] #fr diente derecho Spose [2] [0,25 0,5 30] #
esquina izquierda Spose [3] [0.25] -0.5 -30 # esquina derecha

En este ejemplo sonarProxy_name [0] nos da la distancia desde el Ranger solo diente a un obstáculo, sonarProxy_name
[1] da la distancia del diente delantero derecho de un obstáculo, y así sucesivamente. Si no se detecta
ningún obstáculo, entonces la función devolverá lo alcance máximo del explorador es.

25 Véase la sección 3.2.1 para saber cómo dar el robot odometría perfecto.

42
Figura 22: ¿Cómo se hace referencia a los ángulos de láser. En este diagrama el láser está apuntando a la derecha a lo largo
de la línea de puntos, el ángulo θ es el ángulo de un punto de exploración láser, en este ejemplo θ es negativo.

5.2.3 LaserProxy

Un láser es un caso especial de dispositivo Ranger, que hace que alcance regularmente espaciados surements
medi- de giro de un ángulo mínimo para un ángulo máximo. Cada medi- ción, o punto de exploración, se trata como
está haciendo con un guarda separado. Cuando se dan los ángulos que se indican con referencia a la parte central
delantera del láser (véase la fi gura 22).

• GetCount: El número de puntos de escaneo láser que las medidas de láser.

• laserProxy_name [laser_number] La gama devuelto por el laser_number º


punto de escrutinio. puntos de escaneo se numeran desde el ángulo mínimo en el índice
0, para el ángulo máximo en el índice GetCount ().

• GetBearing [laser_number]: Esto consigue el ángulo del punto de escaneo láser.

• GetRange [laser_number]: devuelve el rango medido por el punto de exploración


laser_number. Esto es lo mismo que hacer laserProxy_name [laser_number].

• MinLeft: Da la distancia mínima que devuelve un punto de exploración en el lado izquierdo del láser.

• MinRight: Da la distancia mínima que devuelve un punto de exploración en el lado derecho del láser.

5.2.4 RangerProxy

El RangerProxy es un proxy para que van más general, es compatible con el sonar, láser y proxies IR.
Tiene la misma función que el SonarProxy en que puede utilizar el código rangerProxy_name
[ranger_number] para devolver la distancia de guardabosques ranger_number a un obstáculo. También
tiene muchas de las mismas funciones

43
Figura 23: Un escáner de láser. El ángulo mínimo es el ángulo de la exploración láser más a la derecha, el ángulo
máximo es el escaneo láser más a la izquierda. θ es la resolución de escaneado del láser, que es el ángulo entre
cada exploración láser, dada en 0,01 grados.

como el LaserProxy, tal como un ángulo mínimo y un ángulo máximo y una resolución de escaneado, la mayoría de
estos son para la recuperación de datos acerca de cómo los rangers están dispuestos o qué tamaño de los
dispositivos que van son.

5.2.5 Blob fi nderProxy

El módulo de burbuja visor análisis de imagen de la cámara para las áreas de un color deseado y devuelve una matriz de
la estructura playerc_blobfinder_blob_t, esta es la estructura utilizada para almacenar datos BLOB. En primer lugar vamos
a cubrir cómo obtener estos datos desde el proxy nder burbuja fi, a continuación, vamos a discutir los datos almacenados
en la estructura.

• GetCount: Devuelve el número de manchas visto.

• blobProxy_name [blob_number]: Esto devuelve los datos de la estructura burbuja de la burbuja con
el índice blob_number. Burbujas son ordenados por índice en el orden en que aparecen en la
imagen de izquierda a derecha. Esto también se puede lograr con la función Blob fi nderProxy GetBlob
(blob_number).

Una vez que recibamos la estructura burbuja desde el proxy podemos extraer los datos que necesitamos. los playerc_blobfinder_blob_t
estructura contiene los siguientes campos:

• color: El color de la mancha se detectó. Esto se da como un valor hexadecimal.

• zona: El área del cuadro delimitador de la burbuja.

• X: La coordenada horizontal del centro geométrico del cuadro delimitador del blob (ver figura 24).

• y: La coordenada vertical del centro geométrico del cuadro delimitador del blob (ver figura 24).

• izquierda: La coordenada horizontal del lado izquierdo del cuadro de ING obligados- de la burbuja (ver figura
24).

44
Figura 24: Lo que los campos en playerc blob blob visor t significan. La mancha de la izquierda tiene un centro
geométrico al ( x, y), la burbuja de la derecha tiene un cuadro delimitador con la esquina superior izquierda en ( izquierda,
arriba) píxeles, y una coordenada inferior derecha al ( boton derecho) píxeles. Las coordenadas se indican con
referencia a la esquina superior izquierda de la imagen.

• derecho: La coordenada horizontal del lado derecho del cuadro delimitador de la burbuja (ver figura
24).

• parte superior: La coordenada vertical de la parte superior del cuadro delimitador del blob (ver figura 24).

• fondo: La coordenada vertical de la parte inferior del cuadro delimitador del blob (ver figura 24).

5.2.6 GripperProxy

El GripperProxy le permite controlar la pinza, una vez que la pinza es la celebración de un elemento, el robot
simulado va a llevar a todas partes donde quiera que va. Sin una pinza que sólo se puede empujar un
elemento de la simulación y que tendría que contar manualmente la simulación qué hacer con un elemento.
El GripperProxy también se puede saber si un artículo está entre los dientes de agarre debido a que el
modelo de pinza tiene vigas incorporado que puede detectar si están rotos.

• GetBeams: Este comando le dirá si hay un elemento dentro del per desde agarrar. Si se trata de un valor superior
a 0, entonces existe un elemento para agarrar.

• GetState: Esto le dirá si la pinza se abre o se cierra. Si el comando devuelve un 1, entonces la pinza
está abierta, si devuelve 2 a continuación, la pinza se cierra.

• Abierto: Le dice a la pinza para abrir. Esto hará que todos los elementos que se estaban llevando a dejarse
caer.

45
• Cerca: Le dice a la pinza para cerrar. Esto hará que se recoja cualquier cosa entre sus dientes.

5.2.7 SimulationProxy

El proxy de simulación permite que el código para interactuar y cambiar aspectos de la simulación, como
pose o su color de un elemento.

Obtener / Establecer propiedad Para cambiar una propiedad de un elemento de la simulación se utiliza la siguiente
función:
SetProperty (char * item_name, char * propiedad, * valor nulo, value_len size_t)

• nombre del árticulo: este es el nombre que le dio al objeto en el mundo fi l, podría ser alguna modelo que
usted ha descrito en el mundo fi l. Por ejemplo, en el apartado 3.2.2 en el mundo fi l que declaramos un
robot tipo bigbob que hemos denominado “bob1” por lo que la nombre del árticulo para ese objeto es “bob1”.
Del mismo modo en la sección 3.3 hemos construido algunos modelos de naranjas y llamado el “Orange1” a
“orange4” por lo que el nombre del artículo de uno de estos sería “Orange1”. Todo lo que es un modelo en
su mundo fi l puede ser alterado por esta función, sólo tiene que haber llamado él, no hay controladores
deben ser declarados en la con fi guración fi l para que esto funcione bien. No escribimos controladores
para las naranjas, pero todavía podría alterar sus propiedades de esta manera.

• propiedad: Sólo hay ciertas propiedades sobre un modelo que se puede cambiar. Se especifica cuál de
ellos desea con una cadena. Dado que las propiedades que puede cambiar son fijos a continuación,
estas cadenas son prede fi nido (ver stage.hh):

- "_mp_color": El color del artículo.

- "_mp_watts": El número de vatios que necesita el artículo.

- "_mp_mass": La masa del elemento.

- "_mp_fiducial_return": establece si el artículo es detectable a la fi ducial visor en un robot.

- "_mp_laser_return": establece si el artículo es detectable al láser en un robot.

- "_mp_obstacle_return": Establece si el robot puede chocar con el artículo.

- "_mp_ranger_return": establece si el artículo es detectable a los Rangers en un robot.

- "_mp_gripper_return": establece si el artículo puede ser agarrado por una pinza o empujado
por el robot de chocar con ella.

• valor: El valor que se desea asignar a la propiedad. Para los parámetros de retorno esto
simplemente puede ser un 0 o un 1, por los vatios y de masa que puede ser un valor numérico.
Para el color del tema se trata de una uint32_t 8 dígitos número de larga hexadecimal. La primera 2
dígitos son el valor alfa del color, el segundo dos son su valor rojo, los dos siguientes son su valor
verde y el final dos son el valor del color azul. Así rojo, por ejemplo, sería uint32 t = 0 x FFFF0000
rojo, verde sería ff00ff00 0x y azul es ff0000ff 0x. Un buen tono de amarillo podría ser CC11 ffff 0x.

46
• value_len: es el tamaño del valor que le dio en bytes. Esto puede ser fácilmente encontrado con el C o
C ++ tamaño de() operador.

Del mismo modo la siguiente función se puede utilizar para obtener información de la propiedad:

GetProperty (char * item_name, char * propiedad, void * Valor, size_t value_len)


En lugar de establecer la propiedad dada del artículo, éste será escribirlo en el bloque de memoria a la que
apunta * valor.

Get / Set Pose La pose de este elemento es un caso especial de la función get / SetProperty, porque es
probable que alguien querría mover un elemento en el mundo crearon una función especial para hacerlo.

SetPose2d (char * item_name, x dobles, doble Y, doble guiñada)


En este caso nombre del árticulo es como con Get / SetProperty, pero podemos especificar directamente sus nuevas
coordenadas y de guiñada (coordenadas y el pian se indican con referencia al origen del mapa).

GetPose2d (char * item_name, doble y x, doble & Y, doble y guiñada)


Esto es como SetPose2d sólo que esta vez escribe las coordenadas y de guiñada a las direcciones indicadas en la
memoria.

5.2.8 Comandos generales útiles Read () Para realizar la actualización de servidores proxy con el nuevo sensor de datos

que necesitamos para indicar al servidor reproductor de actualizar, podemos hacer esto mediante el objeto PlayerClient y

que usamos para conectar con el servidor. Todo lo que tenemos que hacer es ejecutar el comando

playerClient_name.Read () cada vez que los datos necesita ser actualizado (donde nombre del cliente player- es el
nombre que le dio el objeto PlayerClient). Hasta que se ejecute este comando, los proxies y cualquier información
de los sensores de ellos estarán vacíos. Los dispositivos en un robot típico son asíncronos y los dispositivos en una
simulación de DVD / etapa también son asíncronas, por lo que la ejecución del Leer() comando no se actualizará
siempre todo al mismo tiempo, lo que puede tardar varias llamadas antes de algunas estructuras de datos de gran
tamaño (imagen de la cámara), como se actualizan.

GetGeom () La mayor parte de los apoderados tienen una función llamada GetGeom o GetGeometry
o RequestGeometry, o algo por el correo ff ect. Lo que estas funciones hacen es decir el proxy recuperar
información sobre el dispositivo, por lo general su tamaño y plantean (en relación con el robot). Los proxies no
saben esto por defecto ya que esta información es específico para el robot o el modelo de robot jugador / Fase.
Si el código necesita conocer este tipo de información acerca de un dispositivo, entonces el proxy debe ejecutar
este primer comando.

5.3 El uso de proxies: Un estudio de caso

Para demostrar cómo escribir código para controlar un dispositivo de jugador o jugador de simulación / Fase
vamos a utilizar el ejemplo de robot “bigbob” desarrollado en las secciones 3.2 y 4, que recoge las naranjas y
los cartones de jugo de una fábrica de solado. En las secciones anteriores hemos desarrollado el modelo de
la etapa para este robot y su entorno y la con fi guración fi l de controlarlo. Ahora podemos empezar a poner
todo junto para crear una simulación de trabajo de este robot.

47
Figura 25: Las transiciones de estado que seguirá a la basura recogida robot bigbob.

5.3.1 La arquitectura de control

Para recoger la basura que tenemos tres comportamientos básicos:

• Errante: para buscar basura.

• Avanzar hacia la máquina: para cuando un artículo está manchado y el robot quiere recogerlo

• La recogida de material: para tratar los puntos de recogida.

El robot también evitar los obstáculos, pero una vez hecho esto se cambiará de nuevo a su comportamiento
anterior. El control seguirá las transiciones de estado que se muestran en la fi gura 25.

5.3.2 A partir del Código

En la sección 5.1.1 discutimos cómo conectar con el servidor proxy Player y conectado al servidor, y
desarrollamos el siguiente código:

# incluir <stdio.h>
# incluir <libplayerc ++ / playerc ++. h>

int main (int argc, char * argv []) {

/ * Necesita hacer esta línea en C ++ solamente * / PlayerCc


utilizando espacio de nombres;

PlayerClient robot ( "localhost");

48
Position2dProxy p2dProxy (y robot, 0); SonarProxy
sonarProxy (y robot, 0);
BlobfinderProxy blobProxy (y robot, 0); LaserProxy
laserProxy (y robot, 0);

// cierto control código de


retorno 0; }

Usando nuestro conocimiento de los proxies discutidos en la sección 5.2 podemos construir código de arrastre con- en la
parte superior de este código básico. En primer lugar, es una buena práctica para permitir a los motores y solicitar la
geometría para todos los proxies. Esto significa que el robot se moverá y que si lo que necesitamos saber acerca de los
dispositivos de detección de los proxies que tendrá la información disponible.

// activar motores
p2dProxy.SetMotorEnable (1);

// petición geometrías p2dProxy.RequestGeom ();


sonarProxy.RequestGeom (); laserProxy.RequestGeom
(); // blobfinder no tiene la geometría

Una vez que las cosas se inicializan podemos entrar en el bucle de control principal. En este punto hay que decir que el
robot para leer en los datos de sus dispositivos a los proxies.

while (true) {

robot.Read ();

// código de control}

5.3.3 Wander

primero vamos a inicializar un par de variables que será la velocidad de avance y la velocidad de giro del
robot, vamos a poner esto con las inicializaciones de proxy.

Position2dProxy p2dProxy (y robot, 0); SonarProxy


sonarProxy (y robot, 0);
BlobfinderProxy blobProxy (y robot, 0); LaserProxy
laserProxy (y robot, 0);

doble forwardSpeed, turnSpeed;

Digamos que la velocidad máxima de bigbob es de 1 metro / segundo y se puede convertir 90 ◦ un segundo.
Vamos a escribir una pequeña sub-función para asignar al azar hacia adelante y girando velocidades entre 0 y las
velocidades máximas.

Wander vacío (doble * forwardSpeed, doble * turnSpeed) {

int MAXSPEED = 1;

49
int maxTurn = 90; doble fspeed,
tspeed;

// fspeed está entre 0 y 10 fspeed = rand ()%


11;
// (fspeed / 10) está comprendida entre 0 y 1 fspeed =
(fspeed / 10) * MAXSPEED;

tspeed = rand ()% (2 * maxTurn); tspeed =


tspeed-maxTurn;
// tspeed es entre -maxTurn y + maxTurn

* forwardSpeed ​= fspeed;
* turnSpeed ​= tspeed; }

En el bucle de control se incluye una llamada a esta función y después fijar las velocidades resultantes a los
motores.

while (true) {

// leer desde el proxies robot.Read ();

//deambular
Wander (y forwardSpeed, y turnSpeed);

// set motores
p2dProxy.SetSpeed ​(forwardSpeed, DTOR (turnSpeed)); }

En la actualidad los motores se actualizan cada vez que ecutes este bucle de control ex, y esto
conduce a un comportamiento errático del robot. Utilizando el
dormir() 26 comando le diremos el lazo de control que esperar un segundo entre cada ejecución. En este punto
también hay que inicializar el generador de números aleatorios con el momento actual, de modo que el
comportamiento vagar no es exactamente el mismo cada vez. Para el comando del sueño tendremos que
incluir unistd.h y la semilla del generador de números aleatorios con la hora actual del sistema tendremos que
incluir
time.h.

# incluir <stdio.h>
# incluir <unistd.h>
# incluir <time.h>
# incluir <libplayerc ++ / playerc ++. h>

Wander vacío (doble * forwardSpeed, doble * turnSpeed) {

// código de vagar ...}

26 sleep () es una función estándar de C y está incluido en la cabecera unistd.h.

50
int main (int argc, char * argv []) {

/ * Necesita hacer esta línea en C ++ solamente * / PlayerCc


utilizando espacio de nombres;

// conectarse a servidores proxy doble


forwardSpeed, turnSpeed;

srand (time (NULL));

// // activar motores de solicitud


de geometrías

while (true) {

// leer desde el proxies robot.Read ();

//deambular
Wander (y forwardSpeed, y turnSpeed);

// set motores
p2dProxy.SetSpeed ​(forwardSpeed, DTOR (turnSpeed)); sueño (1); }}

5.3.4 Evitación de Obstáculos

Ahora tenemos que escribir una función parcial que comprueba los sonares de cualquier obstáculo y modifica las velocidades
del motor en consecuencia.

AvoidObstacles void (* forwardSpeed ​doble, doble * turnSpeed, \


SonarProxy y sp) {

// será evitar los obstáculos más cerca de 40 cm doble


avoidDistance = 0,4; // se apartarán a 60 grados / int sec
avoidTurnSpeed ​= 60;

// esquina izquierda hay un sonar. 2 // esquina


derecha hay un sonar. 3 si (sp [2]
<avoidDistance) {

* forwardSpeed ​= 0; //dobla a
la derecha
* turnSpeed ​= (-1) * avoidTurnSpeed; regreso; }

else if (sp [3] <avoidDistance)

51
{
* forwardSpeed ​= 0; //girar a la
izquierda
* turnSpeed ​= avoidTurnSpeed; regreso; }

else if ((SP [0] <avoidDistance) && \


(Sp [1] <avoidDistance)) {

// retroceder un poco
* forwardSpeed ​= -0,2;
* turnSpeed ​= avoidTurnSpeed; regreso; }

regreso; //hacer nada }

Esta es una subfunción muy básico evitación de obstáculos actualizará las velocidades del motor sólo si hay un
obstáculo a evitar. Si llamamos a esta función antes de enviar los datos a los motores entonces se sobreponen a
cualquier otro comportamiento de manera que se pueda evitar el obstáculo. Una vez que el obstáculo ya no está en el
camino a continuación, el robot seguirá siendo como lo era es que esto nos va a permitir la transición de cualquier
comportamiento en evitación de obstáculos y luego de vuelta otra vez, como por la exigencia de nuestra estructura de
control. Todo lo que tenemos que hacer ahora es llamar a esta función en nuestro lazo de control:

while (true) {

// leer desde el proxies robot.Read ();

//deambular
Wander (y forwardSpeed, y turnSpeed);

// evitar obstáculos
AvoidObstacles (y forwardSpeed, y turnSpeed, sonarProxy);

// set motores
p2dProxy.SetSpeed ​(forwardSpeed, DTOR (turnSpeed)); sueño (1); }

5.3.5 pasar a un elemento

Para este estado queremos que el robot se mueva hacia una burbuja que se ha visto. Puede haber varias
manchas en su punto de vista a la vez, por lo que voy a decir que el robot se mueva a mayor, porque es
probablemente el más cercano al robot. La siguiente fi subfunción NDS la mancha más grande y se vuelve el
robot de modo que el centro de la mancha está cerca del centro de la imagen. El robot se moverá hacia la
burbuja.

52
MoveToItem anular (doble * forwardSpeed, doble * turnSpeed, \
BlobfinderProxy y BFP) {

int i, centro;
int noBlobs = bfp.GetCount (); blob
playerc_blobfinder_blob_t; int turningSpeed ​= 10;

/ * Número de píxeles del centro de la imagen una burbuja puede ser estar en frente
del robot * / int margen = 10;

int biggestBlobArea = 0; int biggestBlob


= 0;

// encontrar la mancha más grande for


(i = 0; i <noBlobs; i ++) {

// obtener blob de Proxy


playerc_blobfinder_blob_t currBlob = BFP [i];

si (currBlob.area> biggestBlobArea) {

biggestBlob = i;
biggestBlobArea = currBlob.area; }}

blob = BFP [biggestBlob];

// hallazgo centro de centro de la imagen =


bfp.GetWidth () / 2;

// ajustar su vez para centrar la burbuja en la imagen / * si el centro de la burbuja se encuentra dentro
de un margen del centro de la imagen a continuación, se mueve hacia delante, de lo contrario girar de
modo que quede centrado. * /

// blob a la izquierda del centro si (blob.x


<centro-margen) {

* forwardSpeed ​= 0; //girar a la
izquierda
* turnSpeed ​= turningSpeed; }

// burbuja a la derecha del centro else if (blob.x>


centro + margen) {

* forwardSpeed ​= 0; //dobla a
la derecha
* turnSpeed ​= -turningSpeed; }

53
// de lo contrario seguir recto else {

* forwardSpeed ​= 0,5;
* turnSpeed ​= 0; }

regreso; }

Queremos que el robot para la transición a este estado cada vez que se ve un elemento, así que pusimos una sentencia

condicional en nuestro circuito de regulación de esta manera:

si (blobProxy.GetCount () == 0) {

//deambular
Wander (y forwardSpeed, y turnSpeed); } Else {

// avanzar hacia el elemento


MoveToItem (y forwardSpeed, y turnSpeed, blobProxy); }

5.3.6 recojan el artículo

Este comportamiento será el más dif'ıcil de código porque la etapa no soporta objetos empujables (la física requerida es
demasiado complejo), lo que sucede en cambio, es que el robot ejecuta sobre el objeto y simplemente empuja un poco.
Como solución alternativa a este problema tendremos que encajar de alguna manera averiguar qué elemento se
encuentra entre los dientes de bigbob para que podamos encontramos su “nombre” y luego cambiamos la pose de ese
elemento (para lo cual necesitamos el nombre del elemento), de modo que no es ya en la simulación. En esencia, en
lugar de tener nuestro robot comer basura y almacenarlo dentro de su cuerpo, lo que estamos haciendo está haciendo el
láser zap la basura fuera de la existencia.

Podemos hallar el nombre de un elemento entre los dientes de bigbob por referencias cruzadas pose del
robot con las ubicaciones de los artículos en el mundo de encontrar qué elemento es más cercana láser del
robot. El primer paso es crear una lista de todos los elementos en el mundo, sus nombres y sus posturas en la
inicialización. Puesto que sabemos los nombres de los elementos son “Orange1” a “orange4” y “carton1” a
“carton4”, podemos hallar sus poses con una simple llamada a un proxy de simulación. Vamos a tener que
conectarse al proxy simulación con nuestro código primero utilizando la línea

SimulationProxy simProxy (y robot, 0) ;, entonces podemos tener acceso a esta información y ponerla en una
estructura.

Artículo struct {

nombre char [16];


doble X; doble y; }
Typedef item_t;

Podemos rellenar la estructura con la información usando el siguiente código:

54
item_t elementoLista [8];

RefreshItemList vacío (item_t * elementoLista, SimulationProxy y simProxy) {

int i;

// obtener las poses de las naranjas for (i = 0; i


<4; i ++) {

Char orangeStr [] = "naranja% d"; sprintf (elementoLista [i] .name, orangeStr, i +


1); doble imbécil; // variable ficticia, no es necesario el pian.
simProxy.GetPose2d (elementoLista [i] .name, \

elementoLista [i] .x, elementoLista [i] .y, simulado);


}

// obtener las poses de las cajas de cartón para (i =


4; i <8; i ++) {

Char cartonStr [] = "caja de cartón% d"; sprintf (elementoLista [i] .name,


cartonStr, i-3); doble imbécil; // variable ficticia, no es necesario el pian.
simProxy.GetPose2d (elementoLista [i] .name, \

elementoLista [i] .x, elementoLista [i] .y, simulado);


}

regreso; }

Dónde lista de articulos es una item_t matriz de longitud 8.


A continuación podemos empezar el comportamiento “Suma de artículos”, que se desencadena por algo que
se rompe el rayo láser. Cuando esto sucede, vamos a comprobar el área alrededor de los dientes de bigbob, como
indica la fi gura 26. Sabemos que la distancia desde el centro de este círculo de búsqueda de origen de bigbob
(0.625m) y el radio del círculo de búsqueda (0,375 M), podemos conseguir que el robot de pose exacta con el
siguiente código.

x dobles, y, de guiñada;
simProxy.GetPose2d ( "bob1", x, y, guiñada);

Referencias cruzadas posición del robot con las posiciones de los elementos es una cuestión de
trigonometría, no vamos a reproducir el código aquí, pero el código completo y final desarrollado para la
basura bigbob recoger robot está incluida en el Apéndice D. El método que usamos es encontrar la distancia
euclidiana de los artículos al centro del círculo, y la distancia más pequeña es el elemento que queremos
destruir. Hicimos una subfunción llamada FindItem que devuelve el índice del elemento a ser destruido.

Ahora que podemos hallar el punto de destruir es bastante simple para activar nuestra función parcial cuando
el láser está roto, así que podemos hallar y destruir un elemento.

si (laserProxy [90] <0,25) {

55
Figura 26: ¿Dónde buscar elementos que pueden haber pasado por láser de bigbob.

int destroyThis;

/ * Primer parámetro es la lista de elementos en el mundo es la segunda


longitud de esta lista
tercer parámetro es el proxy de simulación con la información pose en
ella * /
destroyThis = FindItem (elementoLista, 8, simProxy);

// coloca fuera de la simulación


simProxy.SetPose2d (elementoLista [destroyThis] .name, -10, -10, 0); RefreshItemList
(elementoLista, simProxy); }

El láser tiene 180 puntos, por lo que el punto número 90 es la que es perpendicular a los dientes de bigbob. Este
punto devuelve un máximo de 0,25, por lo que si su rango fue a caer por debajo de esto, entonces algo ha pasado
a través del rayo láser. A continuación, encontramos el elemento más cercano a los dientes del robot y nos
movemos ese elemento para coordinar ( - 10, - 10) por lo que ya no es visible o accesible.

Por último, tenemos una simulación de trabajo de una recogida de basura robot! El listado de código completo está incluido
en el Apéndice D, el mundo de simulación y con fi guración de los archivos se encuentran en los apéndices B y C,
respectivamente.

5.4 La simulación de múltiples robots

Nuestro estudio de caso de simulación de robot sólo muestra cómo simular un único robot en un entorno
jugador / Fase. Es muy probable que una simulación podría querer más de un robot en el mismo. En esta
situación tendrá que construir un modelo de todos los robots que necesita en el mundo fi l, y luego a su
conductor asociado en la con fi guración fi l. Vamos a echar un vistazo a nuestra fi le mundo para el estudio de
caso, añadiremos

56
un nuevo modelo de un nuevo robot bigbob llamado “bob2”:

bigbob (

nombrar "bob1" pose [-5


-6 45] de color "verde"

bigbob (

nombrar "bob2" pose


[5 6 225] de color
"amarillo"
)

Si hay varios robots en la simulación, la práctica habitual es poner cada robot en su propio puerto (ver
sección 4.1). Para implementar esto en la con fi guración fi l tenemos que decirle qué puerto jugador de
encontrar nuestro segundo robot en:

conductor (nombre de "etapa"


proporciona [ "6665: position2d: 0" "6665: sonar: 0" "6665: blobfinder: 0"
"6665: láser: 0"] modelo "bob1")

conductor (nombre de "etapa"


proporciona [ "6666: position2d: 0" "6666: sonar: 0" "6666: blobfinder: 0"
"6666: láser: 0"] modelo "bob2")

Si usted planea en la simulación de un gran número de robots, entonces es probable que vale la pena escribir un script para
generar el mundo y con fi guración de los archivos.
Cuando se inicia jugador / de la etapa, el servidor El jugador conecta automáticamente a todos los
puertos utilizados en la simulación y el control de los robots por separado con objetos di ff Erent PlayerClient
en su código. Por ejemplo:

// primero robot
PlayerClient robot1 ( "localhost", 6665); p2dprox1
Position2dProxy (y robot1,0); sprox1 SonarProxy (y robot1,0);

// segundo robot
PlayerClient robot2 ( "localhost", 6666); p2dprox2
Position2dProxy (y robot2,0); sprox2 SonarProxy (y robot2,0);

Cada cliente jugador representa un robot, es por eso que cuando se conecta a un proxy del PlayerClient es un
parámetro de constructor. Cada robot tiene un proxy para cada uno de sus dispositivos, no hay robots compartir un
proxy, por lo que es importante que el código se conecta a cada representación de todos los robots con el fin de
leer la información de los sensores. ¿Cómo manejar las PlayerClients y proxies adicionales depende de la escala
de la simulación y de sus propias preferencias personales de codificación. Es una buena idea, si hay

57
quizá más de 2 robots en la simulación, para hacer una clase de robot que se ocupa de la conexión a
servidores proxy y el servidor y procesa toda la información internamente para controlar el robot. A
continuación, puede crear una instancia de esta clase para cada robot simulado 27 y todos los robots
simulados van a ejecutar el mismo código.
Una alternativa al uso de un puerto para cada robot es utilizar el mismo puerto pero un índice de di ff
Erent. Esto sólo funcionará si los robots son todos del mismo (o al menos usar las mismas interfaces,
aunque robots di ff Erent podrían ejecutarse en un di ff puertos Erent) y los robots sólo utilizan un índice para
cada uno de sus dispositivos. Por ejemplo, el robot bigbob utiliza interfaces y los índices: position2d: 0,
sonar: 0, gota visor: 0 y láser: 0 por lo que nunca utiliza más de un índice. Si nos con fi gurar dos robots
bigbob a utilizar el mismo puerto, pero un índice Erent ff di nuestra con fi guración fi l iba a ser así:

conductor (nombre de "etapa"


proporciona [ "6665: position2d: 0" "6665: sonar: 0" "6665: blobfinder: 0"
"6665: láser: 0"] modelo "bob1")

conductor (nombre de "etapa"


proporciona [ "6665: position2d: 1" "6665: sonar: 1" "6665: blobfinder: 1"
"6665: láser: 1"] modelo "bob2")

En nuestro código entonces podríamos establecer los proxies utilizando sólo una PlayerClient:

PlayerClient robot ( "localhost", 6665);

// primero robot
Position2dProxy p2dprox1 (y robot, 0); SonarProxy
sprox1 (y robot, 0);

// segundo robot
Position2dProxy p2dprox2 (y robot, 1); SonarProxy
sprox2 (y robot, 1);

// compartido de proxy Simultion ...


SimulationProxy sim (y robot, 0);

La principal ventaja de con fi gurar el enjambre robot de esta manera es que nos permite disponer de un
único proxy de simulación que es compartida por todos los robots. Esto es bueno ya que hay solo una
ventana de simulación que se puede interactuar con múltiples proxies y así simulación son innecesarias.

6 Enlaces de interés

• 2.1.0 Manual de jugador


http://playerstage.sourceforge.net/doc/Player-2.1.0/player/

27 obviamente, el número de puerto del robot tendría que ser un parámetro de lo contrario todos ellos van a conectar al mismo puerto y

por lo tanto el mismo robot.

58
• Etapa 3.0.1 Manual
http://playerstage.sourceforge.net/doc/stage-3.0.1/

• Etapa 2.0.0 Manual


http://playerstage.sourceforge.net/doc/Stage-2.0.0/

• Todos los poderes jugador en C

http://playerstage.sourceforge.net/doc/Player-2.1.0/player/group_ _playerc__proxies.html

• Todos los poderes jugador en C ++

http://playerstage.sourceforge.net/doc/Player-2.1.0/player/namespacePlayerCc. html

• Interfaces utilizadas por el jugador

http://playerstage.sourceforge.net/doc/Player-2.1.0/player/group_ _interfaces.html

referencias
[1] Brian Gerkey, Richard Vaughan, y Andrew Howard. Manual del jugador: De-
vice direcciones. http://playerstage.sourceforge.net/doc/Player-2.1. 0 / jugador /
group__tutorial__config.html # device_addresses.

7 Apéndices

Apéndice A. Generalidades Etapa Modelo de bigbob

# bigbob.inc
# modelo para el robot "bigbob"
# Autor: Jennifer Owen

# sonares de bigbob
definir ranger bigbobs_sonars (

# número de sonares scount


4

# definir la postura de cada transductor [xpos ypos partida] spose [0] [0,75 0,1875 0] #fr
diente izquierdo Spose [1] [0,75 -0,1875 0] #fr diente derecho Spose [2] [0,25 0,5 30] #
esquina izquierda Spose [3] [0.25] -0.5 -30 # esquina derecha

# definir el campo de visión de cada transductor


# [Range_min range_max view_angle] sview [0,3 2,0
10]

# definir el tamaño de cada transductor


# [Xsize ysize] en metros

59
ssize [0,01 0,05]
)

# blobfinder de bigbob definir


bigbobs_eyes PTZ (

blobfinder (

# número de colores para buscar channels_count


2

# qué colores para buscar canales [ "naranja"


"DarkBlue"]

# imagen parámetros de la cámara [160


120] #resolution range_max 5,00 PTZ [0 0
60]

)
)

# láser de bigbob
definir láser bigbobs_laser (

0.0 range_min

# distancia entre los dientes en metros range_max


0,25

# no necesita ser grande FOV 20

plantear [0,625 0,125 270] tamaño


[0,025 0,025]
)

# el cuerpo de bigbob definir


bigbob posición (

# tamaño real tamaño


[1,25 1 1]

# centro de rotación de bigbob está desplazado de su centro de origen de la zona [0,125 0 0]

# masa estimada en 15,0 kg de


masa

# la forma de bigbob

60
polígonos 3 polígono [0] .points 6 polígono [0]
.point [0] [0 0] polígono [0] .point [1] [0 1]
polígono [0] .point [2] [0,75 1] polígono [ 0]
.point [3] [1 0,75] polígono [0] .point [4] [1
0,25] polígono [0] .point [5] [0,75 0]

polígono [1] .points 4 polígono [1] .point [0] [1 0,75]


polígono [1] .point [1] [1,25 0,75] polígono [1] .point
[2] [1.25 0.625] polígono [1] .point [3] [1 0.625]

polígono [2] .points 4 polígono [2] .point [0] [1 0.375]


polígono [2] .point [1] [1.25 0.375] polígono [2] .point
[2] [1,25 0,25] polígono [2] .point [3] [1 0,25]

# diferencial de dirección de accionamiento


modelo "diff"

# sensores conectados a bigbob


bigbobs_sonars () bigbobs_eyes () ()
bigbobs_laser

Apéndice B. Mundial fi l, que contiene Robot y productos en Mundial

# mundo poblado por robot bigbob


# Autor: Jennifer Owen

Incluir "map.inc" incluyen


"bigbob.inc"

# tamaño de todo el tamaño de simulación [15


15]

# configurar la ventana ventana de interfaz gráfica de

usuario (

tamaño [700,000 700,000] escalar


0,025

61
)

# cargar un mapa de entorno de mapa de bits (

mapa de bits "mapas de bits / cave.png"


tamaño [15 15]
)

bigbob (

nombrar "bob1" pose [-5


-6 45] de color "verde"

definir modelo de color naranja (

# esta es una imagen de un mapa de bits círculo negro


"mapas de bits / circle.png" tamaño de [0,15 0,15] de color
"naranja"

gui_outline 0
gripper_return 1
)

definir modelo de caja de cartón (

# una caja de cartón es retangular


# así que una forma cuadrada y usar el tamaño de los polígonos [?]
1
polígono [0] .points 4 polígono [0] .point
[0] [0 0] polígono [0] .point [1] [0 1]
polígono [0] .point [2] [1 1] polígono [0]
.point [3] [1 0]

# tamaño medio de la caja de cartón litro es de ~ 20 cm x 10 cm x 5 cm de tamaño [0,1


0,2]

Color "DarkBlue"
gripper_return 1
)

naranja (nombre "Orange1" pose [-1 -5 0]) naranja (nombre


"orange2" pose [-2 -5 0]) naranja (nombre "orange3" pose [-3
-5 0])

62
naranja (nombre de "orange4" pose [-4 -5 0])

caja de cartón (nombre "carton1" pose [-2 -4 0]) del cartón


(nombre "carton2" pose [-2 -3 0]) del cartón (nombre
"carton3" pose [-2 -2 0]) del cartón ( "carton4 nombre "pose
[-2 -1 0])

Apéndice C. Con fi guración fi l de bigbob Mundial

# archivo de configuración de ejemplo del jugador para controlar dispositivos etapa: la descripción
# Autor: Jennifer Owen
# Fecha: 22/05/2009

controlador (

nombre de "etapa"
plug-in "libstageplugin"

proporciona [ "simulación: 0"]

# cargar el archivo con el nombre en el simulador Worldfile


"robots_and_junk.world"

# el controlador principal robot


bob1 (

nombre de "fase"
ofrece [
"6665: position2d: 0" "6665:
sonar: 0" "6665: blobfinder: 0"
"6665: láser: 0"] modelo "bob1"

Apéndice D. Código de Control de bigbob Robot de simulación

# incluir <stdio.h>
# incluir <unistd.h>
# incluir <time.h>
# incluir <libplayerc ++ / playerc ++. h>

63
Artículo struct {

nombre char [16];


doble X; doble y; }
Typedef item_t;

utilizando PlayerCc espacio de nombres;

/ **
Al azar asigna nuevas velocidades en las direcciones que se indican. Esta función siempre
va a escribir a las direcciones que se indican. * @param forwardSpeed ​la dirección de la
variable de la velocidad de avance desea esta función para cambiar. * @param turnSpeed
​la dirección de la variable de velocidad de giro que desea esta función para cambiar.

*/
Wander vacío (doble * forwardSpeed, doble * turnSpeed) {

int MAXSPEED = 1; int maxTurn =


90; doble fspeed, tspeed;

// fspeed está entre 0 y 10 fspeed = rand ()%


11;
// (fspeed / 10) está comprendida entre 0 y 1 fspeed =
(fspeed / 10) * MAXSPEED;

tspeed = rand ()% (2 * maxTurn); tspeed =


tspeed-maxTurn;

* forwardSpeed ​= fspeed;
* turnSpeed ​= tspeed; }

/ **
Comprueba los sonares de obstáculos y actualiza las direcciones que se indican con las velocidades de las ruedas.
Esta función será escribir a las direcciones sólo si hay un obstáculo presente. Muy básico evitación de obstáculos
solamente. * @param forwardSpeed ​la dirección de la variable de la velocidad de avance desea esta función para
cambiar.

* @param turnSpeed ​la dirección de la variable de velocidad de giro que desea esta función para
cambiar.
@param y sp El proxy sonar que desea esta función para supervisar.
*/
AvoidObstacles void (* forwardSpeed ​doble, doble * turnSpeed, \
SonarProxy y sp)

64
{
// será evitar los obstáculos más cerca de 40 cm doble
avoidDistance = 0,4; // se apartarán a 60 grados / int sec
avoidTurnSpeed ​= 60;

// esquina izquierda hay un sonar. 2 // esquina


derecha hay un sonar. 3 si (sp [2]
<avoidDistance) {

* forwardSpeed ​= 0; //dobla a
la derecha
* turnSpeed ​= (-1) * avoidTurnSpeed; printf ( "evitando
obstáculos \ n"); regreso; }

else if (sp [3] <avoidDistance) {

* forwardSpeed ​= 0; //girar a la
izquierda
* turnSpeed ​= avoidTurnSpeed; printf ( "evitando
obstáculos \ n"); regreso; }

else if ((SP [0] <avoidDistance) && \


(Sp [1] <avoidDistance)) {

// retroceder un poco
* forwardSpeed ​= -0,2;
* turnSpeed ​= avoidTurnSpeed; printf ( "evitando
obstáculos \ n"); regreso; }

regreso; //hacer nada }

/ **
Si se han detectado manchas esta función a su vez, el robot hacia la mancha más grande. Esta será la burbuja
más cercano (con suerte!). Si se llama a esta función siempre se sobreponen a la información en las direcciones
que se indican.

* @param forwardSpeed ​la dirección de la variable de la velocidad de avance desea esta función
para cambiar.
* @param turnSpeed ​la dirección de la variable de velocidad de giro que desea esta función para
cambiar.
@param y BFP El proxy blobfinder que desea esta función para supervisar.

*/

sesenta y cinco
MoveToItem anular (doble * forwardSpeed, doble * turnSpeed, \
BlobfinderProxy y BFP) {

int i, centro;
int noBlobs = bfp.GetCount (); blob
playerc_blobfinder_blob_t; int turningSpeed ​= 10;

/ * Número de píxeles del centro de la imagen una burbuja puede ser estar en frente
del robot * / int margen = 10;

int biggestBlobArea = 0; int biggestBlob


= 0;

// encontrar la mancha más grande for


(i = 0; i <noBlobs; i ++) {

// obtener blob de Proxy


playerc_blobfinder_blob_t currBlob = BFP [i];

si (currBlob.area> biggestBlobArea) {

biggestBlob = i;
biggestBlobArea = currBlob.area; }}

blob = BFP [biggestBlob];

// hallazgo centro de centro de la imagen =


bfp.GetWidth () / 2;

// ajustar su vez para centrar la burbuja en la imagen / * si el centro de la burbuja se encuentra dentro
de un margen del centro de la imagen a continuación, se mueve hacia delante, de lo contrario girar de
modo que quede centrado. * /

// blob a la izquierda del centro si (blob.x


<centro-margen) {

* forwardSpeed ​= 0; //girar a la
izquierda
* turnSpeed ​= turningSpeed; }

// burbuja a la derecha del centro else if (blob.x>


centro + margen) {

* forwardSpeed ​= 0; //dobla a
la derecha
* turnSpeed ​= -turningSpeed; }

66
// de lo contrario seguir recto else {

* forwardSpeed ​= 0,5;
* turnSpeed ​= 0; }

regreso; }

/ **
Rellena la matriz lista de elementos con los nombres y las posiciones de los elementos de la simulación

@param elementoLista este es el elemento de la lista que contiene los nombres y posiciones de
todos los elementos de la simulación.
@param simProxy el proxy de simulación para la simulación de DVD / escenario.
*/
RefreshItemList vacío (item_t * elementoLista, SimulationProxy y simProxy) {

int i;

// obtener las poses de las naranjas for (i = 0; i


<4; i ++) {

Char orangeStr [] = "naranja% d"; sprintf (elementoLista [i] .name, orangeStr, i +


1); doble imbécil; // variable ficticia, no es necesario el pian.
simProxy.GetPose2d (elementoLista [i] .name, \

elementoLista [i] .x, elementoLista [i] .y, simulado);


}

// obtener las poses de las cajas de cartón para (i =


4; i <8; i ++) {

Char cartonStr [] = "caja de cartón% d"; sprintf (elementoLista [i] .name,


cartonStr, i-3); doble imbécil; // variable ficticia, no es necesario el pian.
simProxy.GetPose2d (elementoLista [i] .name, \

elementoLista [i] .x, elementoLista [i] .y, simulado);


}

regreso; }

67
/ **
Se encuentra un elemento de la simulación que está cerca de los dientes del robot. @param elementoLista
este es el elemento de la lista que contiene los nombres y posiciones de todos los elementos de la
simulación. @param listLength El número de elementos en la simulación @param sim el proxy de
simulación para la simulación / Fase jugador. @return devuelve el índice del elemento de la matriz que está
dentro de los dientes del robot. Si no se encuentra ningún elemento y esto devolverá -1.

*/
int FindItem (item_t * elementoLista, int listLength, SimulationProxy y SIM) {

doble radio = 0,375; doble distBotToCircle = 0,625;


doble robotX, Roboty, robotYaw; doble circleX,
circleY;

// encontrar el robot ...


sim.GetPose2d ((char *) "bob1", robotX, Roboty, robotYaw);

/ * Ahora nos encontramos con el centro del círculo de búsqueda. esto es


distBotToCircle metros desde el origen del robot a lo largo de su guiñada * /

/ * Desplazamiento horizontal de origen robot * / circleX =


distBotToCircle * cos (robotYaw);

/ * Desplazamiento vertical de origen robot * / circleY =


distBotToCircle * sin (robotYaw);

// encontrar centro real relativa a la simulación. circleX = robotX +


circleX; circleY = Roboty + circleY;

/ * Para encontrar los elementos que se encuentran dentro de este círculo nos encontramos
con la distancia euclidiana al centro del círculo. Encontrar el más cercano y si es la distancia
es menor que el radio del círculo y luego volver a su índice * /

doble smallestDist = 1000000; int closestItem = 0;


int i;

for (i = 0; i <listLength; i ++) {

dobles x, y, dist; x = circleX - elementoLista [i]


.x; y = circleY - elementoLista [i] .y;

// encontrar la distancia euclidiana

68
dist = (x * x) + (y * y); dist = sqrt
(dist);

si (dist <smallestDist) {

smallestDist = dist; closestItem =


i; }}

volver closestItem; }

int main (int argc, char * argv []) {

/ * Necesita hacer esta línea en C ++ solamente * / PlayerCc


utilizando espacio de nombres;

PlayerClient robot ( "localhost", 6665);

Position2dProxy p2dProxy (y robot, 0); SonarProxy


sonarProxy (y robot, 0);
BlobfinderProxy blobProxy (y robot, 0); LaserProxy
laserProxy (y robot, 0);
SimulationProxy simProxy (y robot, 0);

doble forwardSpeed, turnSpeed; item_t


elementoLista [8];

RefreshItemList (elementoLista, simProxy);

srand (time (NULL));

// activar motores
p2dProxy.SetMotorEnable (1);

// petición geometrías p2dProxy.RequestGeom ();


sonarProxy.RequestGeom (); laserProxy.RequestGeom
(); // blobfinder no tiene la geometría

/ * Aquí para que laserProxy [90] no segfault en primer bucle * / robot.Read ();

while (true) {

// leer de los proxies

69
robot.Read ();

si (blobProxy.GetCount () == 0) {

//deambular
printf ( "vagar \ n"); Wander (y forwardSpeed, y
turnSpeed); } Else {

// moverse hacia el elemento printf ( "mover


el punto \ n");
MoveToItem (y forwardSpeed, y turnSpeed, blobProxy); }

si (laserProxy [90] <0,25) {

int destroyThis;

destroyThis = FindItem (elementoLista, 8, simProxy); // coloca fuera de la


simulación printf ( "recoger elemento \ n");

simProxy.SetPose2d (elementoLista [destroyThis] .name, -10, -10, 0); RefreshItemList


(elementoLista, simProxy); }

// evitar obstáculos
AvoidObstacles (y forwardSpeed, y turnSpeed, sonarProxy);

// set motores
p2dProxy.SetSpeed ​(forwardSpeed, DTOR (turnSpeed)); sueño (1); }}

70

S-ar putea să vă placă și