You are on page 1of 107

La gua definitiva para

Construccin de
Robots con J ava










Scott Preston

SOBRE EL AUTOR
Scott Preston trabaja como arquitecto J ava en Columbus, Ohio, donde reside
con su esposa, Emily, y el perro, Castle. Scott tiene ms de 20 aos de
programador software y experiencia elctrica, incluyendo posiciones con la
Marina de los EE.UU., el Banco Uno, CompuServe, UUNET, Inc. y
Covansys, adems de dirigir su propia compania de robtica, Preston Research
LLC. Scott tambin da conferencias sobre robtica en COSI (Centro de
Ciencia e Industria) y manufacturas pequeos robotscon J ava llamados
CubeBots . Scott es un miembro de la Comunidad J ava Comunidad de
procesos y un ex alumno de la Universidad Estatal de Ohio.


Sobre el Revisor Tcnico

SIMON RITTER es un evangelista de la tecnologa Java de Sun Microsystems.
Simon ha estado en el negocio de TI desde 1984 y cuenta con una
licenciatura en ciencias en fsica de la Universidad de Brunel enel Reino
Unido. Originalmente trabajando en el rea de desarrollo de UNIX de AT & T
UNIX System Labs y Novell, Simon se traslad a Sun en 1996. En ese
momento, comenz a trabajar con la tecnologa Java y desde entonces ha
dividido su tiempo entre el desarrollo de la tecnologa Java y consultora. l
ahora se especializa en tecnologas emergentes, como la computacin grid,
RFID, robtica y redes de sensores inteligentes. Simn y sus rendimiento con
motor Java robots LEGO han comparecido ante audiencias de todo el mundo.

Agradecimientos

Me gustara dar las gracias especialmente a mi querida esposa, Emily, por aguantarme a m
mientras escriba este libro y por todas las horas que pas en el PC y abajo con los robots
cuando podra haber estado pasando con ella. En segundo lugar, me gustara dar las gracias
a Steve Anglin, Ritter Simon, Marchant Sofa, McGee Michael, y Stence Katie por
ayudarme a escribir este libro, y para los lectores y otros en Apress que ha sido un placer
trabajar con ella. En tercer lugar, me gustara dar las gracias a Ken Gracey de Parallax, Inc.,
y J im Frye de Lynxmotion, Inc., por el suministro hacia mi con varias partes, componentes
y asesoramiento durante la escritura de este libro. En cuarto lugar, me gustara dar las
gracias a mi madre para transmitir su sentido comn y comprarme un Atari 400 en 1980, y
mi padre por la transmisin de su ingenio y de ingeniera para ayudar a construir el original
Feynman en 2002. En quinto lugar, me gustara dar las gracias a mi familia poltica, y
Frikkie Roets Karen, por su hospitalidad ltima Navidad (y siempre), y para el uso de su
cargo para contactar Apress de escribir este libro. En sexto lugar, me gustara agradecer a
mi profesor de secundaria la ciencia, J an Greissinger, por inspirarme a amar la ciencia tanto
como lo hacemos hoy, y tambin Guy Kawasaki por sus libros y los e-mails, que me
inspir a escribir este libro. Por ltimo, no podra terminar sin mencionar a mis amigos
Harry y Crissy, Ron y Sofa, Marcos y Mara, Bard y Ann, Mark y Tracy, y J ohn y Kristi.
Me quiere pasar ms tiempo con usted este verano, e incluso salir a visitar a los que estn
un poco ms que un coche. Planee que en 2006.


Introduccin

Notas sobre el estilo
Admito que era un programador de robots antes de empezar la construccin. As que mi perspectiva
puede ser un poco sesgada en la direccin de un programador. Sin embargo, yo tampoco quera que
este libro sea, desde una perspectiva puramente de ingeniera de software. Quera mantener el texto
equilibrado entre la robtica y la programacin y no demasiado lindo con cualquier disciplina,
aunque de vez en cuando, me temo que podra haberme consentido.
Quin debe leer este libro?
Si desea off-the-shelf componentes del robot, software libre y herramientas de desarrollo, este es el
libro para usted. Puede descargar todo el software es GPL (General Public License) o Apache
License, y usted puede comprar los componentes de su proveedor robot favorito y / o tienda de
hobby. En las secciones siguientes se describen la experiencia que debe tener que sacar el mximo
provecho del libro.
Su Programacin / J ava Experiencia
Yo podra decir que usted debe tener un buen conocimiento de tcnicas orientadas a objetos y J ava
antes de empezar con este libro, pero si eres como la mayora de los expertos en robtica, es
probable que aprender sobre la marcha, y siguiendo los diversos ejemplos I 'hemos incluido en estas
pginas. Por supuesto, si usted no tiene experiencia en J ava, sin duda, va a experimentar una curva
de aprendizaje antes de que las cosas comienzan a hacer clic. Si usted comienza a perderse debido
al vocabulario o la complejidad de los ejemplos, slo comprar uno de los libros a partir de J ava
desde Apress. Son excelentes. Si las cosas siguen sin tener sentido, envame un e-mail o visitar mi
sitio web y publicar una pregunta.
Su experiencia en la construccin del robot
Para aquellos recoger este libro, esperemos que sea un robot constructor intermedio ya, estar
familiarizado con los conceptos de microcontroladores, controladores de servos, controles
electrnicos de velocidad y sensores, y bien han construido un robot desde cero o desde un kit. Se lo
recomiendo a pocos robots de Lynxmotion, Inc., o si usted quiere construir uno desde cero, echar un
vistazo a algunos de los libros escritos por Apress David Cook.




Cmo est estructurado este manual?

He estructurado este libro como si estuviera sentado a construir un robot J ava. Empiezo por la
revisin de los conceptos bsicos de la comunicacin, y luego discutir cmo conseguir que el robot
se mueva, or, ver y navegar, antes de explorar cmo optimizar el cdigo y crear accesos directos.
He dividido cada captulo en subtemas que el progreso de fcil a difcil. Cada sub-tema incluye lo
siguiente:
Una introduccin al tema
Una discusin detallada del ejemplo de cdigo
Un cdigo de ejemplo que demuestra el tema
Una seccin o captulo resumen, si es necesario
Lo que necesita
Aunque se puede usar este libro con bastante eficacia sin que cada elemento con nombre en el
cuadro siguiente, los elementos obligatorios y opcionales que se muestran le ayudar a facilitar los
ejemplos en este libro. Tambin ofrezco una lista de lo que necesita en la introduccin de cada
captulo.
Tabla 1 Ejemplos necesarios para los ejemplos del Libro
REQUISITO OPCIONAL
Java 1.4 SDK DLink DBT-120 u otro adaptador Bluetooth
Java API (comm, avanzado de imagenes, etc) EB500 Bluetooth Transceiver from Parallax
Parallax Javelin or Basic Stamp Pan and Tilt Camera Kit from Lynxmotion
Mini SSC Controladores Servo Lynxmotion SSC-32 Servo controller
Parallax Junta de Educacin (BOE) u otro
board
Lynxmotion Extreme Hexapod 2
Cmara Web
Tarjeta de Audio y micrfono
Pequeo robot movil
Miselaneos (sonar, infrarrojo, etc)

Plataforma y versin de Notes
He desarrollado este libro y sus ejemplos con el Sun Java Standard Edition 1.4.2 SDK, utilizando el
Eclipse IDE 3.02 se ejecuta en Microsoft Windows XP. Sin embargo, si usted no tiene un sistema
operativo de Microsoft, usted puede fcilmente trasladar los ejemplos de este libro para Linux,
Macintosh, o cualquier sistema operativo ejecutando una J VM.
Puede descargar la ltima versin del SDK de http://java.sun.com/j2se/1.4. / download.html y la
ltima versin de Eclipse en www.eclipse.org / downloads / index.php. Mientras que usted puede
utilizar J 2SE 5.0 o Eclipse 3.1, ambos no estaban listos en el momento de escribir este libro, por lo
que los programas no se han probado con esas versiones.
Ruta del Libro
Los captulos de este libro se desarrollan unos sobre otros, con el objetivo principal es la
navegacin de robots, que abordamos en el captulo 7. Sin embargo, usted realmente puede ampliar
la capacidad de su robot mediante el uso del habla como se analiza en el captulo 5, o mediante el
uso de algunos de los puntos tratados en el Captulo 9. Me baso en los temas de todos los captulos
anteriores en el captulo 9, al mismo tiempo que la introduccin de algunos programas divertidos y
de gran alcance. Vea la figura 1.

Figura 1 Mapa del Libro





Actualizaciones y Software
Constantemente estaremos actualizando mi sitio en www.scottsbots.com / definitiveguide. Por favor
pase a visitar, descargar el cdigo fuente nueva y ejemplos, y obtener enlaces a recursos de Internet.
Tambin he incluido una seccin especial para los robots de compra o partes necesarias para este
libro.

CAPTULO 1
EL PRINCIPIO


"Todo debe hacerse lo ms simple posible, pero no ms sencillo".
-Albert Einstein

1. INTRODUCCIN
Antes de empezar a programar su robot con J ava, debe tener en cuenta algunas cosas que
harn la experiencia con su robot J ava mucho ms agradable. Estos incluyen los siguientes:

Un equipo configurado para uso personal y distintos programas informticos *
Un enlace serie
Un microcontrolador
Un robot

Nota: Asegrese de que su PC tenga la conexin a Internet ms rpida, que con frecuencia se
refieren a los enlaces de Internet para descarga o de referencia.

Para empezar, voy a caminar a travs de una configuracin similar a la ma. Perdname los que no
son usuarios de Windows, todas las capturas de pantalla corresponden a Windows XP. Cuando se
presente la ocasin, voy a hablar de una forma alternativa de conseguir lo mismo con un sistema
operativo basado en UNIX.

Configuracin de la Computadora Personal

Para facilitar el uso de su computadora personal para este libro, usted debe hacer lo siguiente.
Descargue e instale J ava Standard Edition 1.4.2 de:
http://java.sun.com/j2se/1.4.2/download.html
Descargue e instale Eclipse 3.02 de:
http://download.eclipse.org/eclipse/downloads/index.php



Si usted tiene cualquier otro J ava Runtimes instalado en su computador, asegurese de establecer
este parche en las Preferencias de Eclipse, como se muestra en la Figura 1-1.

Ilustracin1-Error! No hay texto con el estilo especificado en el documento.-1 Configuracin del JRE THE ECLIPSE

Descargar el ltimo cdigo fuente de este libro en:
www.scottsbots.com/definitiveguide
Usted puede agregar los archivos J AR de su proyecto. De esta manera usted debera ser capaz de
llamar a las clases de su propio proyecto con sus propios programas.





Configuracin de Conexin Serie
Si usted no tiene un puerto serie (algunos equipos nuevos slo vienen con conectores USB),
le recomiendo obtener un adaptador serie - USB de nueve pines, como se muestra a
continuacin en la Ilustracin1-2.


Ilustracin 1-2Adaptador Serie - USB (GUC232A)


Configuracin del Microcontrolador
Usted debe tener un microcontrolador que se pueda programar en PBASIC. He utilizado el BASIC
Stamp 2 para todos los ejemplos de este libro, ya que hace bien el trabajo. Fue mi primera
microcontrolador, y que cuesta menos.
El BASIC Stamp 2 (que se muestra en la Ilustracin 1-3) funciona a 20 MHz y puede ejecutar
aproximadamente 4.000 instrucciones por segundo. Tiene 16 pines I / O, ms dos pines dedicados a
comunicacin serie, una para transmitir y otra para recibir.




Ilustracin 1-Error! No hay texto con el estilo especificado en el documento.-3 El Parallax BASIC Stamp 2
Usted puede comprar uno en www.parallax.com por $ 49.
Configuracin del Programador de Microcontroladores
Todos los ejemplos de este libro estn en PBASIC, porque es el idioma ms popular para el
microcontrolador en este momento. Tambin puede encontrar muchos ejemplos y cdigo de
ejemplo en Internet y en el sitio de Parallax. Al final del libro, he incluido una referencia rpida
para PBASIC, as como una versin J avelin Stamp de los ejemplos.
Puede descargar la ltima versin del programador en www.parallax.com.La Figura 1-4
muestra una imagen de un programa de muestra cargada en el editor del BASIC Stamp Windows.

Ilustracin 1-Error! No hay texto con el estilo especificado en el documento.-4 El Editor de Windows de BASIC Stamp
Configuracin del Robot
Si usted no tiene un robot y le gustara uno en un kit, varios especmenes finos se pueden encontrar
en www.lynxmotion.com, www.parallax.com o www.prestonresearch.com. Para la mayora de los
ejemplos de este libro, se utiliz una unidad diferencial robot o CubeBot (como se muestra en la
Figura 1-5).

Ilustracin 1-Error! No hay texto con el estilo especificado en el documento.-5 El CubeBot
Resumen
Esperemos que tengas todo lo que necesitas para empezar. Ahora voy a empezar por explicar el
proceso de pensamiento detrs de programacin de robtica (en otras palabras, obtener su robot
para hacer algunas cosas).
Entonces voy a hablar de algunos conceptos en J ava que se deben tener en cuenta antes de
embarcarse en un proyecto de robtica. Por ltimo, te voy a mostrar un ejemplo de cmo comenzar
a modelar su software de una manera que es a la vez fcil de usar y eficaz.
1.1 Organizando su Comportamiento
Que hace tu robot? Esta es la primera pregunta que se hacen las personas cuando tienen un robot.
Mi respuesta hace cinco aos sera algo as como: "Se mueve alrededor de una habitacin y evita
los muebles." Entonces la gente dira "Oh ...", y yo despus les hablar sobre la tecnologa o el
software, algo que nunca atrajo su atencin.
Por lo tanto, yo quera algo ms para que haga mi robot, adems de estas cosas bsicas. Yo quera
hacer algo que fuera genial, algo as como una tarea de usuario simple, algo que pudiera decirle a la
gente y no conseguir miradas en blanco a cambio. Por lo tanto, tom la tarea de conseguir una
bebida de la nevera.
Pens que el paso a la nevera no sera tan difcil, pero cuando empec a compilar una lista de tareas
y, a continuacin subtareas, y luego los pasos detallados, me di cuenta de que era mejor empezar
por organizar mis pensamientos en torno a lo que quera del programa (ver Figura 1-6). Cmo los
organizo (mis pensamientos), esto requiere una pequea explicacin, as que aqu est la definicin
de esos trminos:
Eventos: Estas son las cosas que hacen que un robot haga algo. Escuchar una palabra, ver
algo, o conseguir una solicitud de la red, o una tarea programada, o algo por el estilo.
Tareas: Estas son las cosas que desencadenan los acontecimientos. As que si el robot
recibe una solicitud para moverse a algn lugar, la tarea de nivel superior sera moverse. La
tarea de moverse tendra entonces que llamar a una subtarea u otra tarea de ayudar.
Las subtareas: Estas son las cosas que ayudan a la tarea. Por lo tanto, si la tarea consiste en
pasar de una posicin A a una Posicin B, un robot debe saber qu direccin est mirando o
consecuencia volverse hacia esa direccin. Las subtareas pueden llamar a otras subtareas o
enviar o recibir paquetes de datos a partir de los subsistemas del robot.
Los paquetes de datos: Son el ltimo nivel de granularidad en nuestra organizacin de
tareas. Un paquete de datos enva la informacin a un controlador de comando que controla
el motor del robot, o sensores, cuyo nico propsito es obtener y recibir datos de los
subsistemas del robot o perifricos.

Ilustracin 1-Error! No hay texto con el estilo especificado en el documento.-6 Un modelo de comportamiento de los
eventos, tareas, subtareas, mientras que los paquetes de datos.


Person 1 =Persona 1
Event: Speak =Evento: Hablar
Task: Move =Tarea: Moverse
SubTask: Change Heading Subtarea =Cambio de Rumbo
SubTask: Rotate Left =Subtarea =Giro hacia la Izquierda
Data Packet: Byte[ ] =Paquete de Datos: Byte[ ]
En la Tabla 1-1, que se muestra a continuacin, he enumerado algunos ejemplos de cada uno.
Tabla 1-Error! No hay texto con el estilo especificado en el documento.-1 Ejemplo de eventos, tareas, subtareas y
paquetes de datos
EVENTO TAREA SUBTAREA PAQUETE DE
DATOS
Comando Verbal Diagnostico Cambio de rumbo RGB Secuencia de
imgenes
Visin (movimiento) Movimiento Calcular la posicin
inicial
Byte[] Salida Serial
Visin (deteccin de
puntos de referencia)
Siga Objeto Calcular ruta ms
corta
Byte[] Entrada Serial
Comando de Control
Remoto
Determinar la
ubicacin del objeto
Crear el vector de
movimiento
Sin
Batera Baja Calcular la
transformada de
Hough
Sintaxis de voz en los
altavoces
Evento Programado Dormir

Podra haber an ms tareas o subtareas. La cantidad a aadir depender del ruido en su entorno.
Una vez que usted es capaz de llegar a la tarea y subtarea que define lo que usted quiere hacer con
su robot, ya est listo para empezar a manejar algunos de los problemas tcnicos relacionados con la
robtica, como el movimiento y la percepcin.
Movimiento
Cmo hacer que tu robot se mueva depender de las respuestas a las siguientes preguntas:
Cunto dinero tienes para gastar?
Qu tan rpido quieres que tu robot se mueva?
Qu superficie tendr su robot para seguir adelante?
Cul ser el peso de tu robot?
Cunto tiempo durar la fuente de alimentacin al final?
Digamos que usted tiene un presupuesto de $ 200, usted no desea que su robot se mueva
especialmente rpida, se mover en concreto o alguna otra superficie lisa, pesar cerca de 150 libras
y la necesidad de seguir con vida cerca de dos horas antes de volver a cargarla. Si este es el caso,
sus opciones son limitadas. Si cambiamos el terreno a desierto o el presupuesto aumenta a $ 2.000,
la lista de posibles soluciones tcnicas cambiar drsticamente. Sin embargo, slo tener un sistema
de accionamiento no va a permitir que usted pueda lograr el objetivo principal de conseguir un
robot para ir a la nevera. Para ello, el robot tendr que percibir.
Percepcin
Para ilustrar lo que el mundo de la percepcin del robot es, voy a pedirte que hagas algunos
experimentos.
Usted realmente tendr que hacer estos experimentos para entender completamente el problema.
Para empezar, vaya a la sala de estar y cierre los ojos. Mantn las manos delante de ti y trata de
llegar a la cocina para que te encuentres frente al refrigerador. S cuando te golpees contra algo, eso
est bien, es su sensor bache. Por lo tanto, has una copia de seguridad, sigue la pared, o hay lo que
hay que hacer para navegar hasta que est delante de la nevera y en un lugar donde se puede
levantar el brazo y abrir la puerta.
Ahora usted se engaa en este ejemplo porque se sabe a qu direccin se enfrentaba cuando
comenz. As que ir de nuevo a la sala de estar, gira alrededor de una decena de veces (no caen
hacia abajo) y luego repetir este experimento.
Uy, se estaban engaando de nuevo ya que tena un mapa de la habitacin de la memoria y que
saba dnde estaban empezando. As que ahora tengo a alguien que girar, o que le lleve a una nueva
habitacin, y luego repetir el experimento.
Empieza a comprender la dificultad? Tal vez usted podra ser capaz de hacerlo mejor si tuviera una
brjula o alguien que le diga la direccin a la que se enfrenta. Usted puede hacerlo mejor si lleva la
cuenta de la cantidad de pasos que tom y que saba hasta qu punto era cada paso.
El objetivo de este experimento es que despus de varios intentos de llegar a la nevera con los
sensores que se pueden adquirir para el robot, vas a entender lo difcil que es la percepcin del
robot.
Navegacin
Desde el ltimo experimento usted sabe lo difcil que es con un cerebro humano moverse en un
entorno simple, incluso cuando se tiene un mapa, una serie de sensores y una buena memoria.
Sin embargo, si alguna vez ha llegado tarde a una cita o se ha perdido en el camino hacia una nueva
direccin, ya sabe que a veces incluso la vista y el cerebro de una no es suficiente, porque hay
tantos obstculos imprevistos o la informacin con la que usted tiene que trabajar no es "perfecto".
Actualmente uno de los santos griales de la robtica y la inteligencia artificial es la navegacin
consistente y precisa. Uno pensara que esto sera ms fcil con un GPS y complejos sistemas de
navegacin militar, sin embargo, sigue siendo un objetivo difcil de alcanzar y el gobierno de
EE.UU. est dispuesto a pagar dos millones de dlares para el primer grupo que viene con un
vehculo que puede navegar a travs del desierto 175 millas en un plazo de 12 horas. Puede
encontrar ms informacin de este desafo en www.darpa.mil/grandchallenge/.
1.2 Conceptos J ava
J ava es un lenguaje de programacin orientado a objetos desarrollado por Sun Microsystems en
1991. En esta seccin, voy a describir algunos conceptos importantes que ver en este libro que no
sea evidente para un principiante (vase la Tabla 1-2).
Tabla 1-Error! No hay texto con el estilo especificado en el documento.-2 Conceptos Importantes de Java
CONCEPTO DESCRIPCIN
Eventos Usualmente se realiza para las interfaces
grficas de usuario, los eventos son formas de
enviar una clase de notificacin de un cambio
de estado. Por ejemplo, cuando recibe datos en
un puerto serial, se lanzar un evento,
informando a la clase que hay datos en un bfer
que debe ser ledo.
Interfaces Voy a mantener el uso de interfaces simples.
Van a definir las pautas de comportamiento de
las clases similares.
Super Clases Voy a crear superclases para todas las clases
que tienen un "tipo de" relacin. Por ejemplo,
un sello Parallax, un Edwards Scott, y un servo
controlador MiniSSC-II son los tipos de
controladores que se comunican con un puerto
serie. Me gustara crear un super clase para
manejar los tipos comunes de funcionalidad.
Delegado de Clase Un delegado es una clase que comparte algunas
funciones comunes, pero no comparte "un tipo
de" relacin. Por ejemplo, un controlador no es
un tipo de sensor, pero puede haber una
funcionalidad comn que quiero aadir a los
dos. Entonces sera crear una clase de delegado
para controlar la funcionalidad de manera
similar para ambas clases.
Clase Proxy Esta es una clase que tiene la funcionalidad de
muchas clases o componentes que se combinan
para actuar como una sola clase. Me gustara
utilizar dos tipos de clases de proxy: un servidor
proxy fsico que representa un dispositivo
robtico como un sensor y un proxy abstracta
que representa una conducta como la
navegacin.
Servidor Un programa de J ava que no va a interactuar
con un usuario de lnea de comandos de la
interfaz.
Cliente Un programa Java que va a interactuar con una
interfaz de usuario o la lnea de comandos y un
servidor.
Hilos Si quieres hacer ms de una cosa a la vez, debe
utilizar varios subprocesos.
Hilo de Seguridad de Acceso Concurrente Digamos que usted tiene mltiples hilos que
intentan acceder a un nico puerto serie de un
PC. Usted necesita encontrar una manera de
limitar el acceso de un modo seguro para
subprocesos para que no creen condiciones de
interbloqueo.

Haciendo una Pausa en Nuestro Programa
Yo estaba en una conferencia cuando escuch una charla sobre las mquinas de estado y pens que
sera una buena manera de introducir temporizacin y sincronizacin. Una mquina de estados es
un modelo compuesto por tres cosas: estados, transiciones y acciones. Para ilustrar un ejemplo de
una mquina de estados, voy a utilizar un bolgrafo retrctil. Es una mquina de estados muy
simple. La pluma es bien extendida y esta lista para escribir, o es retirada por lo que puede poner en
el bolsillo. Para cambiar su estado, se hace clic en su parte superior, o se la retuerce si es una pluma
de lujo.
Vamos a definir algunos trminos tales como: un estado es un poco de informacin sobre el
modelo. Una transicin es un indicador de un cambio en el estado causado por alguna accin. La
mquina de estado simple que se muestra en la Ilustracin 1-7 , aqu muestra cmo se extrae
tpicamente. Comenzando en el crculo superior (llamado el estado inicial) de la punta de la pluma
est retrada. Haga clic en la parte superior de la pluma y est en un estado nuevo, ampliado y listo
para escribir, que ahora est representado por el crculo inferior. Haga clic de nuevo, y ya est en su
estado original. Bastante simple, no?

Ilustracin 1-Error! No hay texto con el estilo especificado en el documento.-7 Una Simple Mquina de Estados
As que cuando usted tiene un conjunto de subtareas que se deben efectuar para obtener movimiento
de su robot, usted debe tener un diagrama de estados que indique las transiciones de su robot de un
estado o subtarea a otro estado o subtarea.
Sin embargo, hacer esto mediante programacin en J ava con robots es un poco ms difcil de tratar
con la teora o la imagen que acabamos de discutir, pero la idea de una mquina de estados le ayuda
en la organizacin de lo que usted quiere que su robot haga, cmo quiere que su robot lo haga, y lo
ms importante: cuando usted quiere que su robot lo haga. Por ltimo, para que su programa pase a
la transicin correctamente, cuando est listo tendr que ser capaz de "pausa" de su programa para
permitir que estos nuevos estados a materializarse.
Para poner en pausa el programa con J ava, utilice las siguientes cuatro formas definidas en la Tabla
1-3.
Tabla 1-Error! No hay texto con el estilo especificado en el documento.-3 Pasos para Pausar un Programa en Java
Mtodo Pause Descripcin
Thread_Sleep(ms) / Hilo de Sueno(ms) Este es un mtodo esttico y le har al hilo
actual de J ava dormir durante un cierto nmero
de milisegundos. Tenga en cuenta que esto se
har en todos los programas J ava que utilizan
este hilo para dormir, as que si usted est
haciendo varias cosas como la espera de un
acontecimiento de serie y control de una lectura
de puerto paralelo, tendr que crear un nuevo
hilo.
Timer Task / Tiempo de Temporizado Otra forma de obtener algo nuevo que se
produce en un intervalo determinado es crear
una tarea de temporizador que se produce en un
momento fijo en milisegundos desde el
momento en que fue invocado.
Loop Until Finished / Bucle hasta que
termine
Si usted no sabe cunto tiempo tardar algo en
completarse, pero no quiere hacer nada hasta
que est terminado, usted puede poner un
programa en un bucle. Asegrese de insertar
una Thread.sleep (1), en el circuito de modo que
su PC no tenga el 100 por ciento de utilizacin
de la CPU mientras espera. Se podra evitar lo
que est esperando (como una captura de
imagen, comandos de voz, etc) de conseguir
ciclos suficientes para hacer cualquier cosa.
Wait() and notify() / Espera y notifica Si dispone de dos hilos cooperantes, un hilo
para un puerto serie y otro leyendo una imagen
de la webcam se puede utilizar el wait () en el
puerto serie y luego notificar () en la clase
webcam. El mtodo wait () har que el hilo
actual del puerto serial espere hasta que el hilo
que invoca a la cmara web notify () o notify ()
mtodo.

Ahora que hemos terminado con algunos de los conceptos importantes en J ava y sabemos cmo
detener nuestros programas, nuestro ltimo paso es organizar nuestro hardware de una manera que
hace que modelar nuestra conducta sea fcil.
1.3 Organizando nuestro Hardware
Los PC y microcontroladores tienen su lugar en la robtica. Cada uno es bueno en algunas cosas y
pobres en otros, pero con tanto usted obtiene ms de lo que sera el uso de cada uno por separado.
Los microcontroladores son muy buenos para comunicarse con los pequeos aparatos electrnicos.
As que si tienes sensores, servos, o controladores de motor, se debe utilizar un microcontrolador
para esto. Por lo general, tienen muchos puertos de E / S, en cualquier lugar 8 a 40 pines
dependiendo del tipo de microcontrolador que se utiliza, donde los PC se limitan a sus puertos de
comunicacin. Usted descubrir ms adelante cmo se puede utilizar un puerto paralelo de la PC
para hacer algo bsico digital de E / S, pero cuando empiece a hacer por ancho de pulso (PWM) con
un puerto paralelo de la PC, usted se encontrar corriendo a limitaciones.
Las PCs son muy buenas en el control de las decisiones, el almacenamiento de datos, la
interconexin con la gente, y el uso de multimedia. Aunque hay algunos ficheros por ah que
pueden hacer la sntesis de voz, y que las cmaras estn disponibles para que puedan manejar un
poco de color bsico y reconocimiento de objetos, vers que tienen una capacidad limitada.
Adems, la capacidad del microcontrolador para interactuar con la gente, almacenar datos y tomar
decisiones puede dejar mucho que desear.
Organizando nuestros Componentes
Lo primero que hice fue el modelo de las conexiones fsicas entre mi PC y mi robot. Me encontr
con que tiene tres capas simplificado la agrupacin. Se puede elegir otro arreglo para su robot, pero
esto es lo que funcion para m. Un esquema de la disposicin en capas se muestran en la Tabla 1-4.
Tabla 1-Error! No hay texto con el estilo especificado en el documento.-4 Capas en Programacin Robtica
CAPA DE PC CAPA DE CONTROL CAPA DE DISPOSITIVO
Esta es la capa con la que estn
ms familiarizados. El plan
incluir las interfaces a los
perifricos como el puerto
serial, puerto paralelo,
webcam, salida de sonido o
dispositivos de entrada, etc
Esta capa representa los
controladores de otros
fabricantes. Estos
controladores le permiten
comunicarse en la lengua de un
robot y el lenguaje de un
ordenador.
Esta es la capa que representa
los dispositivos de hardware
que se ha conectado.
Puerto Serial
Cmara Web
Tarjeta de Audio
Base de Datos
Parallax Stamp
Controlador Servo MiniSSC II
Microcontrolador
Brazo Robot
Sonar
Pierna Robot
Brjula

Modelando el Hardware y el Comportamiento
Una vez que se organiza los componentes que tienen que trabajar, es el momento de crear unas
"suaves" componentes de hardware.
Escoja un nombre (por ejemplo, PanTiltCamera).
Modele lo que usted quisiera que hiciera (mover arriba / abajo, mover hacia la izquierda / derecha,
tomar una foto, y as sucesivamente).
Apague su clase.
Planee lo que puede salir mal y cmo quiere tratar con ese problema.
Despus de haber modelado el hardware y el comportamiento, usted debe estar listo para el clculo
de la sincronizacin entre los dos.
Sincronizacin
La sincronizacin en la vida es importante; la sincronizacin en robtica es obligatoria. Si usted
tiene un microcontrolador ms grande, se recomienda usar control de flujo (por ejemplo, tener su
PC y el microcontrolador negociando cuando cada uno est listo para hablar). Pero ya que slo tiene
16 puertos E / S con mi BASIC Stamp 2, voy a sincronizar manualmente la comunicacin serial.
Usted debe ser consciente de cmo las cosas toman sin embargo mucho tiempo
Por ejemplo, una velocidad de comunicacin de 9600 baudios con su microcontrolador tarda unos 3
pies por carcter. Si tiene tres caracteres para transmitir, como el porte de su brjula, podra tomar
menos tiempo para ejecutar la orden de lo que costara recuperar los datos de su conexin en serie.
Pero el tiempo no es slo importante para la sincronizacin. Tambin define la resolucin a la que
el robot puede obtener datos de su entorno. Por ejemplo, si usted tiene un sensor que lee un sonar
cada 200 milisegundos, entonces usted tiene un nmero mximo de 5 lecturas por segundo.
Si el robot se desplaza 1 metro por segundo (un ritmo de marcha lenta), la resolucin de su robot
ser de 7 pulgadas.
Resumen
A estas alturas, usted debe estar listo para empezar a usar J ava con la robtica. Su PC debe tener
instalado el software y usted debe tener una conexin serial y el microcontrolador. Mientras que no
se necesita un robot para el siguiente captulo, asegrese de hacer un poco para que est listo para el
Captulo 3, se puede conectar el robot y ponerlo en marcha con algunos de sus propios programas
J ava.
Esperemos que sus programas hagan algo ms que evitar el sof o se mueven en crculos. As que
tome un poco de tiempo para averiguar lo que usted quiere que su robot realice. Luego, para que sea
ms fcil seguir estos pasos: En primer lugar, debe organizar lo que usted quiere que su robot
realice. En segundo lugar, elegir los eventos que determinan la intervencin.
En tercer lugar, crear tareas que organizan el comportamiento. En cuarto lugar, crear subtareas que
realizan los detalles.
Finalmente, el modelo de paquetes de datos que representan la informacin puedan moverse de su
hardware y PC.
Tambin podra ayudar a organizar sus programas crear un diagrama de transicin de estados como
la Ilustracin 1-2 que se muestra anteriormente de tal manera que se haga fcil cuando se pasa de
subtarea a subtarea o tarea a tarea. Yo no me preocupara demasiado por los conceptos de J ava en
este momento, pero cuando sea de volver a ellas si te quedas atascado en algn momento ms
adelante en el libro. Lo que no se encuentra listado aqu se pueden descubrir en los numerosos
libros Apress que hacen un excelente trabajo explicando estos conceptos.
Por ltimo, una vez que su modelo de comportamiento se define, se debe empezar a modelar su
hardware. As que a partir de su PC y mover asus perifricos, si es necesario crear modelos simples
del hardware que se asignan fcilmente a la conducta que usted desea que su robot realice. Por
ejemplo, si quiero que mi robot se mueva, me gustara asignar un puerto serie a un controlador
servo y eso sera todo. Pero si quiero que se enfrentan a una direccin especfica, me gustara tener
un puerto serial asignado a un controlador servo, as como un microcontrolador, que se asigna a una
brjula. Slo un consejo antes de continuar: comenzar con algo simple, y luego aumentar la
complejidad de su modelo slo despus de haber probado una versin simple de la misma. Usted se
encontrar con muchos problemas en el camino y no hay nada peor que la solucin que repetir todo
el cdigo.
CAPTULO II

Comunicacin Serial

"El problema con la comunicacin es la ilusin de que se ha logrado."
--George Bernand Shaw

2.0 Introduccin
En este libro, todas las comunicaciones que se utilizan con el microcontrolador son comunicaciones
RS-232 serie a 9600 baudios, ocho bits de datos, un bit de parada y sin control de flujo. Hay otros
mtodos de comunicacin con los microcontroladores, especialmente I2C (Inter-Integrated
Communication), comunicaciones paralelas, Ethernet, WiFi y Bluetooth slo para nombrar unos
pocos. Pero he optado por utilizar comunicaciones serie por su popularidad y su extensibilidad con
otro software y dispositivos.
Voy a mostrar y describir las 12 clases de J ava y los programas de BASIC Stamp 2. Todas las
clases estn en el paquete com.scottpreston.javarobot.chapter2. Todos los programas sellados se
encuentran en la carpeta / BasicStamp/chapter2.
En este captulo, voy a presentarles a la API J ava Communications, explicando algunas de sus
clases ms importantes, y luego probar su uso de algunos programas sencillos. Ms tarde, voy a
simplificar su uso con la robtica y ampliar las comunicaciones serie a travs de una red utilizando
J ava Server Pages y un cliente web.
Una vez que he discutido y simplificado las comunicaciones en serie, voy a modelar un programa
de microcontrolador en una clase J ava. Modelando el programa del microcontrolador en J ava, se
debe simplificar la programacin de su robot.
El captulo concluye con un ejemplo que utiliza un adaptador Bluetooth de serie en combinacin
con un BASIC Stamp para demostrar comunicaciones serie inalmbricos.
Configuracin del Puerto Serie
Una vez ms, vamos a configurar el puerto serie a lo siguiente: 9600 baudios, ocho bits de datos,
sin paridad, un bit de parada y sin control de flujo. Para configurar esto para Windows, abra el
Panel de control, seleccione Sistema Hardware Administrador de dispositivos y, a
continuacin, haga clic en Puertos. Asegrese de anotar el nmero de puerto (COMx).
Usted puede ver las ventanas de estos en las figuras 2-1 y 2-2 se muestran a continuacin.
Nota: Los usuarios de UNIX, los puertos estn numerados de esta forma ttyS0, ttyS1, y as
sucesivamente. Sustituir todas las referencias de COMx a ttySx.

Ilustracin 2-1 Ventana de Administrador de Dispositivos

Ilustracin 2-2 Ventana de Propiedades de Comunicacin de Puertos



El API de Comunicaciones J ava
Voy a utilizar las siguientes clases de la API J ava Communications para acceso al puerto.
Tabla 2-1 Clases Importantes del API de Java Communications
CLASES JAVA DESCRIPCIN
javax.comm.CommPortIdentifer Esta es la clase principal para controlar el
acceso a los puertos de comunicaciones.
Proporciona una lista de los puertos de
comunicacin puestos a disposicin por el
conductor, asiste a la apertura de los puertos de
comunicaciones, y ayuda con la propiedad del
puerto.
javax.comm.SerialPort Este es el estndar RS-232 del Puerto de
comunicaciones provisto por el comm.jar. Por
la documentacin de J ava, esta clase define la
funcionalidad mnima necesaria para
puertos de comunicaciones serie.

Objetivos del Cdigo
El objetivo de este ejemplo es la lista de todos los puertos de comunicacin disponibles.
Sugerencia: Hacer que el primer programa se ejecuta, ya que pondr a prueba la instalacin
de la API J ava Communications.
Discusin del Cdigo
Los campos de esta clase son ComPortIdentifer, portId y una enumeracin de todos los puertos
llamados portsList. A continuacin, voy a crear un constructor vaco donde puedo inicializar la
enumeracin de los puertos. Esta ser la lista de todos los puertos identificados por el conductor.
El segundo mtodo en la clase es el mtodo list (). La primera lnea en el mtodo es un bucle while
que itera a travs de la enumeracin de los puertos. Al llegar al siguiente elemento de la
enumeracin, recibe el portType (serie o paralelo), y luego imprime el nombre del puerto.
Tras la salida del nombre de la consola, voy a hacer un intento de abrir el puerto, hacer una pausa de
250 milisegundos, a continuacin, cerrar el puerto. Esto se repite hasta que la enumeracin no tiene
ms elementos.
Esta clase lanza dos tipos de excepciones. LA primera es el InterruptedException, producida por el
Thread.sleep() mtodo esttico, mientras que el PortInUseException producida por el mtodo
portId.open (). (Vase el Ejemplo 2-1.)


Ejemplo 2-Error! No hay texto con el estilo especificado en el documento.-1 ListOpenPorts.java
Para las clases posteriores, ser til no usar el mtodo Thread.sleep(), pero en vez de aadir un solo
mtodo esttico que se puede llamar, y que se encarga de la InterruptedException. Para ello, voy a
crear una clase de Utilidades para almacenar estos mtodos de utilidad estticos. (Vase el Ejemplo
2-2.)

Ejemplo 2-Error! No hay texto con el estilo especificado en el documento.-2 El mtodo Utils.pause()
Resumen de la seccin
Todas las comunicaciones que se utilizan en este libro con el microcontrolador emplear
comunicacin serie RS-232 a 9600 baudios, ocho bits de datos, un bit de parada y sin control de
flujo. Una vez que se ha configurado en su PC mediante una combinacin de clases y
CommPortIdentifier SerialPort de la API J ava Communications para la comunicacin serial, usted
debera ser capaz de obtener el acceso que permiten la lectura y escritura desde y hacia el puerto
serial de su PC con J ava.
Las clases que he creado en esta seccin fueron:
ListOpenPorts.java: Esta clase muestra cmo iterar a travs de la enumeracin prevista por la clase
CommPortIdentifier del J ava API para seleccionar un puerto serie.
Utils.pause (): Esta clase va a ser slo una clase de utilidad que en la actualidad cuenta con una
mtodo pausa que har que el subproceso actual entre a dormir y atrapar su excepcin. Mientras que
usted puede utilizar la API directamente, he encontrado ms til escribir una clase contenedora que
simplifica el acceso. Esto es lo que voy a hablar en la prxima seccin.
2.1 Un puerto serial simple
En la clase ListOpenPorts, hemos sido capaces de acceder y abrir los puertos serie, pero el uso de
esta tcnica presenta tres problemas. En primer lugar, es complicado de crear y utilizar el puerto
serie iterando a travs de todos los que estn disponibles, y luego, cuando el que est disponible
coincide con la que usted desea, usted puede utilizarlo. En segundo lugar, utilizando los flujos de
entrada y flujos de salida desde el puerto serial es difcil si usted desea enviar y recibir paquetes de
datos tal como se define en el Captulo 1.En tercer lugar, el uso de este puerto no es lo
suficientemente genrico.
Objetivos del Cdigo
Para compensar estas deficiencias voy a crear lo siguiente:
Una interfaz de puerto serie para que pueda crear varias clases de serie implantacin del
puerto, pero no tendr que modificar el cdigo a travs de la interfaz.
Un constructor sencillo para que pueda especificar un puerto serie con transmisin e
identificador.
Mtodos que funcionan bien para enviar y recibir paquetes de datos hacia y desde el
microcontrolador.
Discusin del Cdigo
El primer elemento a crear es una interfaz de puerto serie. La interfaz J ava es un medio para ocultar
diferentes implementaciones con el mismo comportamiento. Por ahora voy a crear el acceso al
puerto serie a un puerto local, pero ms tarde quiero dar el mismo comportamiento en la red. Lo
primero que se nota desde la interfaz es que no contiene ninguna lgica, slo apndices de mtodo.
Esto se debe a que una sola interfaz est all para definir el comportamiento, para no poner en
prctica cualquiera de la conducta. El trabajo real se llevar a cabo por otra clase que implementa
esta interfaz.
La segunda cosa que usted nota son los nombres de los mtodos. Por ejemplo, el mtodo read ()
devuelve una matriz de bytes. El mtodo readString() devuelve un String. El mtodo de escritura no
devolver nada y tendr una matriz de bytes, ya que es slo un parmetro de entrada. Tambin hay
un mtodo close() para liberar recursos y volver a enviar la propiedad para que otras clases o
programas pueden tener acceso al objeto de aplicacin.
He aadido dos mtodos de descriptor de acceso de puerto serie: setDTR para su uso con las placas
portadoras de sellos Parallax, y setTimeout como un medio de ayuda en la sincronizacin de los
paquetes de datos con el microcontrolador conectado.
Las tres cadenas estticas son para uso con el WebSerialClient que se definen ms adelante en este
captulo. El read() y readString() tienen mtodos con parmetros de entrada porque (segn el valor
de tiempo de espera), a veces es mejor esperar a la respuesta de la clase de puerto serie en lugar de
llamar al Thread.sleep() externamente y luego llamar a dos mtodos separados write() y read().
(Vase el Ejemplo 2-3.)

Ejemplo 2-3 JSerialPort.java
Ahora que he creado la interfaz genrica para todos los puertos serie que voy a utilizar en este libro,
es el momento de escribir nuestra primera clase de implementacin, StandardSerialPort. La
Ilustracin 2-3 muestra el diagrama de clases para J SerialPort y StandardSerialPort.

Ilustracin 2-3 Diagrama de clases de JSerialPort y StandardSerialPort
Para empezar vamos a ver las variables de nivel de clase. La lista de puertos estn enumerados en
una lista que se obtiene de los puertos por parte del conductor. El ComPortIdentifier, portId, es el
puerto real que estamos interesados en trabajar, mientras que SerialPort es la java.comm.SerialPort
real que vamos a utilizar para leer y escribir paquetes de datos con nuestro microcontrolador.
InputStream y OutputStream, con los nombres de variables con el mismo nombre, son las corrientes
de trabajo para regresar de nuestra SerialPort.
El byte[] readBuffer ser un bfer temporal utilizado durante la lectura de corriente de nuestro
puerto serial de entrada. La Boolean, DATAIN, es un indicador que permite marcar la clase est
sabe cunto tiempo toma para leer la secuencia de entrada en el readBuffer. Finalmente, las dos
ltimas variables currentWrite e i se utilizan en conjuncin con lectura-escritura del
comportamiento implementado en el WebSerialClient.
Pasando a los constructores de clase, he creado dos constructores para esta clase que simplifican la
creacin de parmetros de entrada a los baudios justos e id. Porque yo slo estoy comprobando para
ver si el puerto termina con un nmero especfico (por ejemplo, 1,2,3, ..., n), esta clase va a
funcionar ya sea con Windows o UNIX basados en puertos serie. En el caso de que la transmisin
no se ha establecido, me decid por una tasa de morosidad de 9600. Cada constructor tambin llama
a un mtodo init comn. Dentro de este mtodo se encuentra el Ejemplo 2-1 con la misma lgica
utilizada en el, ListOpenPorts. Una vez que se crea una enumeracin, yo itero a travs de esta
enumeracin hasta que encuentre a los puertos serie (en concreto, el que termina con el int se pasa
como un parmetro de entrada). Luego habr una instancia con nombre de este puerto y establecer
los parmetros por defecto que son de ocho bits de datos, un bit de parada, sin paridad y sin control
de flujo. A continuacin, establezca el flujo de entrada y flujo de salida del puerto para ser igual a
dos variables de clase del mismo nombre, seguido de la adicin del detector de eventos y una
bandera notifyOnDataAvailable.
Nota: Los dos mtodos de pausa tienen que esperar al controlador para ajustar los valores
de los puertos. He encontrado en mi mquina de Windows XP que si no me detengo un
poco, los conductores a veces se vuelven excepciones. Puede eliminar estos en el equipo si
lo desea, slo asegrese de hacer hincapi en ellos al tratar de probar muchos aperturas y
cierres de puerto en un bucle.
A continuacin, voy a hablar de las clases de implementacin de la interfaz J SerialPort. (Vase el
Ejemplo 2-4.) el mtodo read () es realmente un mtodo que duerme hasta que el buffer de entrada
est vaco. Una vez vaco, se devuelve el contenido de la readBuffer. El mtodo readString()
simplemente llama al mtodo read() y luego convierte los bytes en una lista delimitada por la tilde
como un String. Dado que todos los datos que vienen del microcontrolador sern un flujo de bytes,
quera una manera de leer bytes individuales sin tener que preocuparse de ellos pero se transform
en un caracter que no puede ser fcilmente convertido de nuevo a un int.
El mtodo write() es un paso a travs de la secuencia de salida con la excepcin de aadir el
contenido a la currentWrite byte []. Guardo esto porque quiero pasar por alto si el microcontrolador
hace eco de nuevo al momento de leer la secuencia de entrada.
El mtodo close() cierra el SerialPort.
Los otros dos mtodos read() y readString () con parmetros de entrada- no se utilizan pero que una
vez ms no porque la interfaz jSerialPort los requiere.
El nico que me importa es el evento DATA_AVAILABLE. Cuando este evento se dispara, voy a
iniciar una serie de 32 bytes, a continuacin, mientras que la inputStream est disponible, voy a leer
el flujo de entrada en el readBuffer. Luego realizar alguna lgica para asegurarse de que los datos
devueltos no sean igual a los datos que se envan, y si ese es el caso, me ponga el DATAIN
booleana en true. De los ltimos tres mtodos, setTimeout() no se utiliza, y setDTR() y getName()
estn ah para proporcionar un acceso limitado a sus variables SerialPort correspondientes.
Un ejemplo de secuencia de eventos de una tpica escritura / pausa / lectura accin sera la
siguiente:
1. byte [] se escribe en un puerto serie.
2. El microcontrolador lee byte [].
3. El programa externo llama a pausa (x).
4. El tiempo pasa.
5. El tiempo se acab.
6. El microcontrolador retorna byte [].
7. La norma DATA_AVAILABLE el evento del puerto serial est activado.
8. El programa externo llama a read().
9. Todos los datos se leen; DATAIN se establece en true.
10. El read() retorna el byte [] de datos de microcontrolador.
Ejemplo 2-4 StandardSerialPort.java
package com.scottpreston.javarobot.chapter2;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import javax.comm.CommPortIdentifier;
import javax.comm.SerialPort;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;
public class StandardSerialPort implements SerialPortEventListener,
J SerialPort {
private Enumeration portList;
private CommPortIdentifier portId;
private SerialPort serialPort;
private OutputStream outputStream;
private InputStream inputStream;
private byte[] readBuffer;
private boolean dataIn =false;
private byte[] currentWrite;
private int i =0;
public StandardSerialPort(int id) throws Exception {
init(id, 9600);
}
public StandardSerialPort(int id, int baud) throws Exception {
init(id, baud);
}
private void init(int comID, int baud) {
String comIdAsString =new Integer(comID).toString();
try {
portList =CommPortIdentifier.getPortIdentifiers();
while (portList.hasMoreElements()) {
portId =(CommPortIdentifier) portList.nextElement();
if (portId.getPortType() ==CommPortIdentifier.PORT_SERIAL) {
if (portId.getName().endsWith(comIdAsString)) {
// Creando el Puerto Serie
serialPort =(SerialPort) portId.open(
"StandardSerialPort", 3000);
// Estableciendo los parmetros de Configuracin
serialPort.setSerialPortParams(baud,
SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
serialPort
.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
Utils.pause(50);
// Configurando la corriente de Salida
outputStream =serialPort.getOutputStream();
// Configurando la Corriente de Entrada
inputStream =serialPort.getInputStream();
// Agregando Detector de Eventos
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
Thread.sleep(50); // waits till ports change state.
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public byte[] read() {
while (!dataIn) {
try {
Thread.sleep(1);
} catch (Exception e) {
}
}
dataIn =false;
return readBuffer;
}
public String readString() {
byte[] b =read();
StringBuffer s =new StringBuffer();
for (int i =0; i <b.length; i++) {
if (b[i] !=0) {
int in =(int) b[i];
if (in <0) {
in =in +256;
}
s.append(in);
s.append("~");
}
}
s.deleteCharAt(s.length() - 1);
return s.toString();
}
public void write(byte[] b) throws Exception {
currentWrite =b;
outputStream.write(b);
}
public void close() {
serialPort.close();
}
public byte[] read(byte[] b) throws Exception {
// No Usado
return null;
}
public String readString(byte[] b) throws Exception {
// No Usado
return null;
}
public void serialEvent(SerialPortEvent event) {
if (event.getEventType() ==SerialPortEvent.DATA_AVAILABLE) {
readBuffer =new byte[32];
i =0;
try {
while (inputStream.available() >0) {
int numBytes =inputStream.read(readBuffer);
}
int byteCount =0;
for (int i =0; i <currentWrite.length; i++) {
if (currentWrite[i] ==readBuffer[i]) {
byteCount++;
}
}
if (byteCount !=currentWrite.length) {
dataIn =true;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void setTimeout(int timeout) {
// No Usado
}
public void setDTR(boolean dtr) {
serialPort.setDTR(dtr);
}
public String getName() {
return serialPort.getName();
}
}
Resumen de la Seccin
Para esta seccin, he creado un simple uso del puerto serial. Hice esto mediante la simplificacin de
la construccin del puerto para tomar solo los parmetros del identificador de puerto serie (1,2,3, ...,
n) y una velocidad de transmisin como un int. En segundo lugar, he modificado los flujos de
entrada y salida para tomar parmetros y devolver datos tiles para la robtica: byte [] y cuerdas.
Por ltimo, cre una interfaz para el puerto serie llamado el J SerialPort, que puede ser utilizado en
las secciones posteriores para forzar el mismo comportamiento para varias implementaciones del
puerto serie.
La interfaz y las clases que he creado en esta seccin fueron:
J SerialPort.java: Esta es la interfaz que va a especificar el comportamiento de todos los
puertos serie.
StandardSerialPort.java: esta clase es la versin ms simple de la SerialPort J ava API.
La nica cosa que el StandardSerialPort no hace es manejar el uso simultneo del puerto serie. Ese
ser el tema de la siguiente seccin.
2.2 Uso Simultneo Del Puerto Serie
Si conectamos ms de una cosa a un puerto serie, se encontrar con muchos PortInUseExceptions.
Queremos evitar esto, de lo contrario nuestros programas estarn saliendo cuando no queremos que
lo hagan. (Ver Tabla 2-2.)
Tabla 2-2 Pro y Contra del Uso Simultneo
SOLUCIN PRO CONTRA
Cree el puerto serial en el
interior de cada objeto
dependiente.
Cada clase es independiente. El uso concurrente de;
throwPortInUseException ms,
la aplicacin lo har. Eierre del
puerto serial se tiene que hacer
a travs de llamada a un
mtodo para invocar objeto.
Crear puerto serie fuera de
los objetos de consumo.
El uso concurrente limita a
subproceso actual. Cierre del
puerto serial se puede hacer
fuera de los objetos
individuales.
Cada clase requiere SerialPort
que se enviar en el
constructor. No es seguro para
subprocesos.
Crear una clase nica que
tiene el control de todas las
acciones necesarias de puerto
serie.
Auto-contenida. Ejecucin de
subprocesos. Clausura del
puerto gestionado dentro de la
clase.
Pobre reutilizacin
Utilice un singleton de puerto
serie en el interior de cada
objeto dependiente.
La clase es autnoma. El uso
concurrente se limita a J VM y
se rosca safe.Closing de los
objetos se realiza fuera de los
objetos individuales.
Limitado a un solo puerto
serial independientemente de
ID COM.
Utilice un producto nico de
los puertos serie dentro de un
grupo de recursos de todos
los puertos serie disponibles.
La clase es autnoma. El uso
concurrente se limita a J VM y
es seguro para subprocesos. El
cierre de los objetos se puede
hacer fuera de los objetos
individuales. Puede solicitar
cualquier sistema disponible
que puede encontrar el puerto
serie.
Ninguno

Objetivo del Cdigo
El objetivo de este ejemplo es mostrar cmo crear un fondo de recursos de los puertos serie sin
tener conflictos si varios objetos desea acceder a ellos a la vez.
Discusin de Cdigo
El nico campo en la clase SingleSerialPort es un vector: portsInUse. Este vector es una
recopilacin de los Serialports actualmente inicializados. Debido a que un vector se sincroniza, esto
asegura que los puertos son accesibles de una manera segura para los subprocesos. He creado un
constructor privado para evitar la inicializacin. Todos los StandardSerialPorts sern devueltos a
travs de los getInstanceMethods. El mtodo getInstance utiliza el nombre de la SerialPort (COM1
o stty1) para identificarse y, o bien crear uno nuevo o volver al puerto fuente. Por ltimo, el mtodo
close() elimina los puertos de la piscina y los cierra. (Ver Ejemplo 2-5.)
Ejemplo 2-5 SingleSerialPort.java
package com.scottpreston.javarobot.chapter2;
import java.util.Vector;
private static Vector portsInUse =new Vector();
private SingleSerialPort() {
// Inicializando Preventos
}

public static StandardSerialPort getInstance(int comid) throws Exception {
return getInstance(comid,9600);
}
public static StandardSerialPort getInstance(int comid, int baud)
throws Exception {
StandardSerialPort instance =null;
String tmpComID =new Integer(comid).toString();
// Regresa a un puerto si existe y si esta en uso.
for (int i=0; i<portsInUse.size(); i++) {
StandardSerialPort aPort =(StandardSerialPort)portsInUse.get(i);
if (aPort.getName().endsWith(tmpComID)) {
return aPort;
}
}
// otherwise create the port if its in the list
if (instance ==null) {
instance =new StandardSerialPort(comid,baud);
portsInUse.add(instance);
}
return instance;
}
public static void close(int comid) {
String tmpComID =new Integer(comid).toString();
// return a port in use if it exist.
for (int i=0; i<portsInUse.size(); i++) {
StandardSerialPort aPort =(StandardSerialPort)portsInUse.get(i);
if (aPort.getName().endsWith(tmpComID)) {
aPort.close();
portsInUse.remove(i);
}
}
}
public static void closeAll() {
// Ciclo de todo y cierre
for (int i=0; i<portsInUse.size(); i++) {
StandardSerialPort aPort =(StandardSerialPort)portsInUse.get(i);
aPort.close();
portsInUse.remove(i);
}
}
}
Resumen de la seccin
En esta seccin, se discuten y comparan cinco formas diferentes de manejar la concurrencia en el
puerto serie. Mediante la colocacin de un puerto serie en un grupo de recursos que es thread-safe,
me aseguro de que el puerto serie se puede acceder de manera sincronizada y nunca voy a conseguir
un PortInUseException al acceder al puerto serie al programar mi robot.
La clase que fue creada en esta seccin fue:
SingleSerialPort.java: Esta clase muestra cmo crear un fondo de recursos de los puertos
serie que facilitan el acceso concurrente de varios subprocesos.
2.3 Creacin de un puerto serie Web
He descubierto que trabajar con el puerto serial en mi PC de escritorio est muy bien, pero tan
pronto como empiezo a depurar el cdigo con mi robot, me parece que trabajar en un equipo remoto
a travs de Servicios de Terminal Server es mucho ms lento. Por lo tanto, necesito otra opcin.
Quiero trabajar desde el IDE de Eclipse en mi PC de escritorio, pero tambin quiero hacer la
comunicacin serial con un microcontrolador conectado al puerto serie de mi robot. Yo tambin
quiero una manera fcil de probar esto de forma remota y no quiero escribir software para el manejo
de mltiples conexiones o la gestin de paquetes de datos de secuencias o imgenes que puedan ir y
venir entre la PC de escritorio y el robot. Para solucionar estos problemas, voy a crear un puerto
serial web. Este es un puerto serial que puede acceder a travs de Internet, enviar comandos,
obtener datos y, a continuacin, utilizar sucesivamente los clientes web para hacer el control remoto
para el diagnstico.
Nota: ms sobre la configuracin de Tomcat se puede encontrar en el Captulo 8: Temas
avanzados.
Configuracin
La configuracin siguiente representa mi PC con mi J ava IDE (Eclipse). Tengo una conexin
inalmbrica con el motor de servlets Tomcat que se ejecuta en el ordenador de mi robot. (Ver
Ilustracin 2-4).

Ilustracin 2-4 Configuracin Inalmbrica de WebSerialPort
Objetivo del Cdigo
El objetivo clave es ampliar el puerto serie para que pueda conectarse a ella a travs de la conexin
inalmbrica de mi casa a travs de HTTP.
Discusin del Cdigo
El ejemplo siguiente ser utilizado en un J ava Server Page que reside en el servidor web. La cadena,
CMD_ACK, ser de reconocer la cadena devuelta desde el webcom.jsp si todo va segn lo previsto
y que no hay errores. La cadena, COMM_J SP, es el nombre de la J SP que toman la entrada y salida
de solicitud desde el cliente.
Las variables READ_ONLY y DEFAULT_TIMEOUT se utilizan para calcular mejor si el cliente
debe esperar a que el servidor web responda con salida desde el puerto serie o hacer una solicitud
por separado para la salida.
Debido a que Tomcat es un servidor web multiproceso, cualquier par de llamadas de un navegador
web o cliente Web que podra suceder en diferentes hilos. Esto no es un efecto deseado, por lo que
para evitar la PortInUseException voy a utilizar el SingleSerialPort.getIntance() en el constructor de
la WebSerialPort.
El nico otro mtodo pblico de esta clase es execute(), que toma los parmetros y acciones que
corresponden a leer, escribir, leer o escribir. La cadena, cmds, ser una cadena delimitada por
comas de bytes, mientras que la cadena, tiempo de espera, le dir a la clase que debe esperar por el
resultado. En este mtodo, tambin se producen excepciones si alguno de los elementos
constructores son nulos. Los otros mtodos que se llama dependen de la accin. El private read()
devuelve el valor de com.readString (). Esta ser una lista delimitada de nmeros. El mtodo write()
convierte la cadena delimitada por comas de un byte [] y lo enva al flujo de salida del puerto serie.
Finalmente, el mtodo read() con parmetros de entrada llamar al mtodo write(), y espera un
tiempo, y luego llamar al mtodo read(). (Vase la Ilustracin 2-6.).
Ejemplo 2-6 WebSerialPort.java
package com.scottpreston.javarobot.chapter2;
public class WebSerialPort{
J SerialPort com;
public static final String CMD_ACK ="ok";
public static final String COMM_J SP ="webcom.jsp";
public static final byte[] READ_ONLY =new byte[] { (byte) 0 };
public static final int DEFAULT_TIMEOUT =0;
private int timeout;
public WebSerialPort(String comId) throws Exception {
int pId =new Integer(comId).intValue();
com =SingleSerialPort.getInstance(pId);
}
public String execute(String action, String cmds, String timeout,String dtr)
throws Exception{
if (action ==null) {
throw new Exception("Action is null");
}
if (cmds ==null) {
throw new Exception("Commands are null");
}
if (timeout ==null) {
throw new Exception("Timeout is null");
}
if (dtr ==null) {
throw new Exception("DTR is null");
}
int tOut =new Integer(timeout).intValue();
this.timeout =tOut;
//if (tOut !=0) {
// com.setTimeout(tOut);
//}
if (dtr.equalsIgnoreCase("true")) {
com.setDTR(true);
}
if (dtr.equalsIgnoreCase("false")) {
com.setDTR(false);
}
if (action.equalsIgnoreCase(J SerialPort.READ_COMMAND)) {
return read();
} else if (action.equalsIgnoreCase(J SerialPort.WRITE_READ_COMMAND)) {
return read(cmds);
} else if (action.equalsIgnoreCase(J SerialPort.WRITE_COMMAND)) {
return write(cmds);
} else {
return null;
}
}
/**
*
* @param cmd
* this will be comma delimited seq of cmds
*/
private String write(String cmd) throws Exception {
com.write(urlCmdsToBytes(cmd));
return CMD_ACK;
}
private String read(String cmd) throws Exception {
write(cmd);
Utils.pause(timeout);
return read();
}
private String read() {
return com.readString();
}
public void close() {
com.close();
}
private byte[] urlCmdsToBytes(String command) {
String[] commands =command.split(",");
byte[] cmds =new byte[commands.length];
for (int x =0; x <commands.length; x++) {
int i =new Integer(commands[x]).intValue();
cmds[x] =(byte) i;
}
return cmds;
}
}
La siguiente parte de nuestra amplicacin del puerto serie para la web es webcom.jsp. Este J SP
importa las clases del Captulo 2, y luego analiza los parmetros en la URL, luego realiza el envo
de esas cadenas al constructor de la clase anterior, WebSerialPort. Debido a que el constructor lanza
una excepcin, voy a envolver el constructor y ejecutar mtodos en un bloque try-catch con un
ejemplo de cmo utilizar la J SP. Fuera de la construccin, e invocando el mtodo de ejecucin, toda
la funcionalidad y la lgica para el webcom.jsp se encuentra en la clase WebSerialPort. (Vase el
Ejemplo 2-7.)
Ejemplo 2-7 webcom.jsp
<%@ page import="com.scottpreston.javarobot.chapter2.*" %><%
// WebClient class will throw exception if these are not set
String portId =request.getParameter("portid");
String action =request.getParameter("action");
String cmdInput =request.getParameter("commands");
String timeout =request.getParameter("timeout");
String dtr =request.getParameter("dtr");
try {
WebSerialPort com =new WebSerialPort(portId);
out.println(com.execute(action,cmdInput,timeout,dtr));
} catch (Exception e) {
out.println(e);
int term ='!';
%>
usage: /webcom.jsp?portid=[1,2,..]&action=[r,w,wr]
&commands=[100,120,222,..]&timeout=[0,50,..]&dtr=true
<p>sample:
<a href="/webcom.jsp?portid=1&action=wr&commands=100,<%=term%>
&timeout=0&dtr=true">sample 1</a>
<% }%>

Si no te diste cuenta, el WebSerialPort no implementa la interfaz J SerialPort. Por qu es eso?, por
dos razones. Uno, que no necesitaba ya que el comportamiento es ligeramente diferente que el
puerto serie estndar, y dos, todas nuestras clases de aplicacin no volvera a usar este puerto En su
lugar, tendr que utilizar el conector a la WebSerialPort: el WebSerialClient. La clase
WebSerialClient implementa la interfaz J SerialPort, por lo que ahora cualquier cosa que escribo
slo puede utilizar esta interfaz y puedo intercambiar el WebSerialClient, el StandardSerialPort, o
mi propia aplicacin y no voy a tener que modificar nada del cdigo que los utiliza. bastante
mancha, eh?
El primer campo de esta clase es un objeto formateador. Yo lo uso para la depuracin de los
milisegundos de una operacin. Usted tendr que depurar y experimentar con diferentes valores de
tiempo de espera para los elementos conectado al microcontrolador. Demasiado tiempo y usted
estar perdiendo rendimiento, demasiado pequeo y obtendr nada a cambio o slo basura. Voy a
hablar ms de esto en el captulo 4, pero es probablemente mejor tomar nota de ello por ahora. La
direccin URL de cadena y el objeto URL se utiliza para conectar con el webcom.jsp en mi robot.
La variable DTR est establecido en false si me estoy conectando a una tarjeta portadora BASIC
Stamp. El tiempo de espera y max_delay son enteros que van a determinar si el cliente debe esperar
un retorno de webcom.jsp, o si slo debe hacer dos llamadas: una escritura y una lectura. He
encontrado que dependiendo de su conexin Wi-Fi, es posible que desee aumentar o disminuir este
valor. A continuacin, la construccin de este cliente tendr en el servidor de cadena que representa
el servidor nombre o la direccin IP del servidor web que aloja el webcom.jsp. La cadena, tcpport,
representa el puerto donde el servidor web que aloja el webcom.jsp est escuchando. (Vase el
Ejemplo 2-8.)
Ejemplo 2-8 WebSerialClient.java
package com.scottpreston.javarobot.chapter2;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
public class WebSerialClient implements J SerialPort {
private SimpleDateFormat formatter =new SimpleDateFormat(
"MM/dd/yy - HH:mm:ss.SSS");
private String url;
private URL myUrl;
private boolean dtr =false;
private int timeout =0;
public static final int MAX_DELAY =500;
public WebSerialClient(String server, String tcpPort, String portId) {
this.url ="http://" +server +":" +tcpPort
+"/" +WebSerialPort.COMM_J SP +"?portid=" +portId;
}
public byte[] read() {
return readString().getBytes();
}
public String readString() {
return request(WebSerialPort.READ_ONLY, J SerialPort.READ_COMMAND);
}
public void write(byte[] b) throws Exception {
String out =request(b, J SerialPort.WRITE_COMMAND);
if (out.equalsIgnoreCase(WebSerialPort.CMD_ACK) ==false) {
throw new Exception("WebClient Write Failure: " +out);
}
}
// aadido en caso de que usuario desea leer despus de enviar comandos
// Esto es especfico para el webcom.jsp
public byte[] read(byte[] b) {
return readString(b).getBytes();
}
public String readString(byte[] b) {
return request(b, J SerialPort.WRITE_READ_COMMAND);
}
public void close() {
// no hace nada, ya que tiene ms de un puerto
}
public void setDTR(boolean dtr) {
this.dtr =dtr;
}
private String request(byte[] commands, String cmdType) {
// convertir el byte a cadena
String cmdString =byteArrayToString(commands);
log("WebClient: cmds=" +cmdString +", cmdType=" +cmdType
+", timeout=" +timeout);
String out =null;
try {
String urlString =url
+"&action=" +cmdType
+"&commands=" +cmdString
+"&timeout=" +timeout
+"&dtr=" +dtr;
URL myurl =new URL(urlString);
log(urlString);
BufferedReader in =new BufferedReader(new InputStreamReader(
myurl.openStream()));
String str =null;
while ((str =in.readLine()) !=null) {
// str es una lnea de texto; readLine () elimina el salto de lnea
if (str !=null) {
out =str;
}
}
in.close();
} catch (Exception e) {
e.printStackTrace();
}
out =out.trim();
log("WebClient: out=" +out);
return out;
}
private String byteArrayToString(byte[] b) {
String s ="";
for (int x =0; x <b.length; x++) {
s =s +b[x] +",";
}
s =s.substring(0, s.length() - 1);
return s;
}
private void log(String s) {
Date d =new Date();
String dt =formatter.format(d);
System.out.println(dt +" *** " +s);
}
public int getTimeout() {
return timeout;
}
public void setTimeout(int timeout) {
this.timeout =timeout;
}
public static void main(String[] args) {
}
}
Resumen de la seccin
Ahora debera ser capaz de conectarse al puerto serie del robot desde cualquier lugar del mundo.
Usted puede escribir sus programas en su PC y el tiempo que tiene conectividad de red al puerto
serie del robot, todos los programas se pueden ejecutar desde el PC. Las clases y J SP que se
introdujo en este apartado fueron:
WebSerialPort: La clase que tiene acceso al puerto serie del servidor web de la J SP.
Webcom.jsp: La pgina de servidor J ava que proporciona acceso desde el WebSerialPort al
WebSerialClient, o el acceso directo a travs del navegador.
WebSerialClient: La clase que implementa la interfaz J SerialPort que permite el acceso a un
puerto serie de un servidor web de la misma manera se puede acceder a un puerto serie de su
mquina local.
Dependiendo de su configuracin, usted est listo para empezar a acceder a su microcontrolador a
travs de su puerto serie.

2.4 Comunicaciones En Serie Con Un Microcontrolador
Una vez que haya probado y utilizado algunas de las clases de acceso a puerto serie de su PC, usted
est listo para enviar y recibir algunos datos de la misma. Para ello, conecte el cable serial de su PC
a su J unta de Educacin Parallax. Se puede ver en la Ilustracin 2-5 que el BOE tiene un lugar, ya
sea para el BASIC Stamp o Stamp, conectores para un cable de serie de la batera, y tel board para
su uso en la experimentacin.

Ilustracin 2-5 La Parallax Board
Nota: Si ests empezando con la robtica, es genial tener este board para aadir sensores o
la creacin de circuitos.
Una vez que su tarjeta est conectada y se puede ver el microcontrolador que ha conectado, usted
est listo para programar. Su primer objetivo ser enviar slo algunos datos al microcontrolador y
obtener algunos datos a cambio.
Objetivo del Cdigo
Los objetivos de este ejemplo son los siguientes:
Enviar 2 bytes de datos a un microcontrolador.
Recibir una copia byte especfico que confirma el byte enviado a ella.
Discusin del Cdigo
El programa Stamp tiene una matriz de bytes de tamao 3 llamado serialIn. Esta matriz de bytes se
rellenar desde el smbolo del SERIN cuando est llena o cuando se recibe una orden de
terminacin de "!". Luego, basndose en el primer byte recibido desde el PC, el programa saltar a
SEROUT con una "a" o "b". (Vase el Ejemplo 2-9.)
Nota: Ajustar el tiempo de espera del puerto serie o el tiempo entre la escritura y la demora.
A continuacin, ajuste el tiempo de pausa en el cdigo Stamp y ver cmo varan los
resultados.
Ejemplo 2-9 StampSerialTest.java
'{$STAMP BS2}
'{$PORT COM1}
serialIn VAR Byte(3)
foo VAR Byte
main:
foo =255
serialIn(0) =0
serialIn(1) =0
serialIn(2) =0
SERIN 16,16468,1000,main,[STR serialIn\3\"!"]
PAUSE 100
LOOKDOWN serialIn(0),[100,101,102],foo
BRANCH foo,[test1, test2, getCompass]
PAUSE 5
GOTO main
test1:
SEROUT 16,16468,["a"]
GOTO main
test2:
SEROUT 16,16468,["b"]
GOTO main
getCompass:
SEROUT 16,16468,["180"]
GOTO main

Resumen de la seccin
El programa Stamp y la clase J ava creado en esta seccin son:
SerialEcho.bs2: Este programa se encuentra en el microcontrolador y se hacen eco de una "a" y
"b" en funcin de los comandos enviados al controlador.
StampSerialTest.java: Esta clase est diseada para enviar y recibir informacin especfica para el
microcontrolador en coordinacin con SerialEcho.bs2.
Una vez que han probado el acceso bsico a su microcontrolador, ahora es el momento de extender
en este concepto un poco adems del modelo de su microcontrolador, primero mediante la creacin
de uno genrico que puede ser utilizado para cualquier tipo de microcontrolador, a continuacin,
mediante la creacin de una versin que corresponde precisamente a su programa de Stamp.


2.5 Modelado de un microcontrolador con J ava
Mientras que podra utilizar la StandardSerialPort para enviar y recibir datos hacia y desde un robot,
esto hace que sea ms difcil en el futuro a medida que aumenta la capacidad del robot. As que,
para empezar se necesita un microcontrolador. Elijo el BASIC Stamp de Parallax, porque es fcil de
programar y hay un montn de ejemplos y apoyo disponible para este modelo.
El primer Stamp Parallax BASIC viene en nueve versiones diferentes, sin incluir las versiones
OEM. Vienen con 8, 16, y 32 pines E / S que operan a partir de 4 MHz a 50 MHz y se puede
programar con hasta 12.000 instrucciones. Son muy verstiles y hay un montn de ejemplos de
software a travs de Internet, as como los prestados en el sitio web del fabricante en
www.parallax.com.
Los dos se muestran en la Figura 2-6 y la Figura 2-7 son el BASIC Stamp 2 y el J avalin Stamp. El
J avelin Stamp es la versin de J ava. Usted puede encontrar todos los ejemplos de programas en este
libro para el J avalin Stamp en el Apndice 2. Todos los otros ejemplos sern para el BASIC Stamp
2, ya que es el ms popular y, como he dicho antes, hay ms ejemplos de este microcontrolador en
la actualidad.

Ilustracin 2-6 El Parallax BASIC Stamp

Ilustracin 2-7 El Paralllax Javalin Stamp
Al utilizar los Stamp con los programas J ava, he encontrado que es tedioso para llevar a cabo el
mismo puerto serial y la gestin de byte para cada clase que tenga acceso al Stamp. Para resolver
este problema, voy a crear una clase que maneja toda la comunicacin con el controlador. Pero al
igual que el puerto serie, puede que tenga diferentes implementaciones de acceso, por lo que
primero quiero crear una interfaz para todos los controladores, y luego quiero escribir una clase de
implementacin especficamente para mi sello.
Objetivo del Cdigo
El objetivo de este ejemplo es para simplificar la comunicacin para mi robot mediante el modelado
de un programa de Stamp en J ava.
Discusin del Cdigo
La primera interfaz que voy a crear se llamar J Controller. Esta interfaz tiene tres mtodos
execute() y un mtodo close(). La nica diferencia entre los dos mtodos Execute ser el tipo de
retorno. En execute(), el tipo de cambio ser una cadena. Esto llamar la readString() de la
J SerialPort. En execute2(), el tipo de retorno ser un byte []. Esto llamar al mtodo read() de la
J SerialPort. (Vase el Ejemplo 2-11.)
Ejemplo 2-11 StampSerialTest.java
package com.scottpreston.javarobot.chapter2;
public interface J Controller {
public String execute(byte[] cmd, int delay) throws Exception;
public byte[] execute2(byte[] cmd, int delay) throws Exception;
public void close();
}

A continuacin, voy a escribir la implementacin de la interfaz definida en el ejemplo anterior. Al
empezar a escribir clases de implementacin para el J avalin Stamp, y seis versiones del BASIC
Stamp, me encontr a m mismo repitiendo muchas de las mismas llamadas a los mtodos Execute.
As, en lugar de escribirlos en siete ocasiones, he decidido crear un controlador maestro que
implementara la funcionalidad de todos ellos. Tambin ser capaz de manejar todos los
controladores nuevos que puedan surgir en captulos posteriores. Voy a llamar a este controlador de
clase, y para que las clases de implementacin reales se crean, voy a hacer lo genrico. Esta clase
tiene un solo campo, es de tipo SerialPort J SerialPort. El constructor de esta clase toma la interfaz
J SerialPort para que pueda utilizar el WebSerialClient o el StandardSerialPort. Tambin establece la
DTR en false ya que ninguno de los controladores que uso va a utilizar esto, y por los consejos de
Stamp vehculo que tiene este conjunto en true pondr el Stamp en el modo de programa. El primer
mtodo, execute(), devolver una cadena. Lo primero que se comprueba es la instancia de la
J SerialPort. Si se trata de tipo WebSerialClient, entonces quiero poner el retraso en el puerto serie
en el servidor web. Esto es debido a un retraso de tiempo entre la mquina y la ejecucin de
conexin con el servidor web. Puse el mximo retraso en la clase WebSerialClient y si el retraso es
inferior o igual a este nmero, el retardo se establece en la WebSerialClient, de lo contrario, lo har
llamar Utils.pause() y hacer dos llamadas al cliente. Adems, en ambos casos, tengo que comprobar
para ver si el retraso es cero. Si ese es el caso, yo no quiero nada preparado, yo slo quiero escribir.
(Ver Ejemplo 2-12.)
Ejemplo 2-12 Controller.java
package com.scottpreston.javarobot.chapter2;
public abstract class Controller implements J Controller {
private J SerialPort serialPort;
public Controller(J SerialPort sPort) throws Exception {
serialPort =sPort;
serialPort.setDTR(false);
}
public String execute(byte[] cmd, int delay) throws Exception {
String out =null;
if ((serialPort instanceof WebSerialClient)
&& delay <=WebSerialClient.MAX_DELAY) {
serialPort.setTimeout(delay);
if (delay ==0) {
serialPort.write(cmd);
} else {
out =serialPort.readString(cmd);
}
} else {
if (delay ==0) {
serialPort.write(cmd);
} else {
serialPort.write(cmd);
Utils.pause(delay);
out =serialPort.readString();
}
}
return out;
}
public byte[] execute2(byte[] cmd, int delay) throws Exception {
byte[] out =null;
if ((serialPort instanceof WebSerialClient)
&& delay <=WebSerialClient.MAX_DELAY) {
serialPort.setTimeout(delay);
if (delay ==0) {
serialPort.write(cmd);
} else {
out =serialPort.read(cmd);
}
} else {
if (delay ==0) {
serialPort.write(cmd);
} else {
serialPort.write(cmd);
Utils.pause(delay);
out =serialPort.read();
}
}
return out;
}
public void close() {
serialPort.close();
}
}
Para dar un ejemplo de cmo estas tres clases encajan -StandardSerialPort, J Controller y Controller
he proporcionado el diagrama de clases UML en la Figura 2-8. A principios de SimpleStamp, creo
tres constantes. Estas constantes se utilizan de dos formas. La primera es para que sea ms fcil
modificar las cadenas de comandos cuando se sincroniza el programa de Stamp. En segundo lugar,
porque los comandos reales enviados a la Stamp son bytes, puedo usar estas constantes como las
rdenes reales para el byte [] envi al mtodo write() del puerto serie. El constructor de esta clase
tendr una instancia de una clase SerialPort del SingleSerialPort.

Ilustracin 2-Error! No hay texto con el estilo especificado en el documento.-8 StandardSerialPort, JController,
Controller, and SimpleStamp
Los mtodos comando create byte [] con los comandos especificados a travs de las constantes de la
clase, y luego invocan el mtodo execute() de la matriz con un tiempo de retardo de 150
milisegundos para cada mtodo. (Vase el Ejemplo 2-13.)
Ejemplo 2-13 SimpleStamp.java
package com.scottpreston.javarobot.chapter2;
public class SimpleStamp extends Controller {
public static final int COMMAND_A ='d';
public static final int COMMAND_B ='e';
public static final int COMMAND_TERM ='!';
public SimpleStamp(int id) throws Exception {
super(SingleSerialPort.getInstance(id));
}
public String cmdA() throws Exception {
byte[] a =new byte[] { (byte) COMMAND_A, (byte) COMMAND_TERM };
return execute(a, 150);
}
public String cmdB() throws Exception {
byte[] b =new byte[] { (byte) COMMAND_B, (byte) COMMAND_TERM };
return execute(b, 150);
}
public static void main(String[] args) throws Exception {
SimpleStamp t =new SimpleStamp(1);
System.out.println(t.cmdA());
System.out.println(t.cmdB());
t.close();
}
}
Resumen de la seccin
En esta seccin, hemos creado una interfaz de controlador llamado J Controller que especifica el
comportamiento entre todos los controladores que utilizaremos en este libro. Tambin hemos
creado una clase abstracta que lleva consigo dos mtodos de aplicacin para ejecutar la
comunicacin. Con los dos diferentes mtodos de aplicacin slo leer, execute() devolver una
cadena, y execute2() devolver un byte []. Una vez que el controlador genrico se crea podemos
extender esta clase para nuestras implementaciones especficas del programa del BASIC Stamp,
mientras que slo se centra en los bytes que necesitan para enviar y el nombre del mtodo que
queremos crear te que corresponder a los comandos del programa de Cupones.
Las clases e interfaces creadas en esta seccin son:
J Controller.java: Esta es la interfaz que va a especificar el comportamiento de todos los
controladores.
Controller.java: Este es en resumen una super-clase que implementa execute() y execute2()
para todos los controladores en el futuro.
SimpleStamp.java: Esta es una clase de implementacin del programa SerialEcho.bs2
presentado en la seccin 2.3.
Lo nico que queda por crear es hacer que la comunicacin inalmbrica con la combinacin de
nuestra BASIC Stamp y el dispositivo Bluetooth.
2.6 Comunicaciones Bluetooth Serie
Esto es tan fcil una vez que el dispositivo Bluetooth est configurado. Todo lo que necesitas hacer
es cambiar el ID de puerto com. He utilizado el EB500 de Parallax. Esto conecta directamente a las
tablas que tienen otros y que es un gran valor de menos de $ 100 en comparacin con los
adaptadores Bluetooth de serie. Asegrese de que utiliza el puerto COM segn se especifica bajo el
puerto serie Bluetooth en la pestaa de aplicaciones de cliente. Puede encontrar las instrucciones
para configurar el microcontrolador y el adaptador EB500 en el sitio de Parallax o en el manual
bajo el ttulo "Conexin entre un PC con DBT-120 y un BOE." Las fotos de la EB500 y DBT-120
se muestran en las figuras 2-9 y 2-10.

Ilustracin 2-Error! No hay texto con el estilo especificado en el documento.-9 El mdulo Parallax Bluetooth EB 500

Ilustracin 2-Error! No hay texto con el estilo especificado en el documento.-10 Adaptador USB Bluetooth Inalmbrico
DLink DBT-120

Objetivos del Cdigo

Los objetivos de este cdigo son:

Demostrar una conexin serie inalmbrica
Demostrar que una conexin en serie es el mismo que una red cableada con el
software adecuado instalado en el Stamp
Discusin del Cdigo
La tarjeta Bluetooth conectado a nuestro BOE (Board of Education) se comunicar directamente a
nuestro PC a travs de una de sus conexiones en serie. Mientras que nuestro PC no notar ninguna
diferencia, hay algunos pequeos cambios que deben hacerse en el lado del Stamp. En primer lugar,
algunos comandos de inicializacin necesita ser enviado a la EB500, junto con la direccin de
nuestro adaptador Bluetooth USB en el PC. Una vez conectado, nuestro programa se parece mucho
a la original, con la excepcin del pasador SEROUT y SERIN el pin: pin 1 frente al pin 16. El
cdigo J ava es el mismo cdigo que el utilizado anteriormente en el Ejemplo 2-4. Slo cambia el
identificador de puerto para que coincida con el adaptador Bluetooth y ya est. (Vase el Ejemplo
2-14.)
Ejemplo 2-14 BluetoothStamp.bs2
' {$STAMP BS2}
serialin VAR Byte
INPUT 5
PAUSE 1000
SEROUT 1,84, ["con 00:11:95:4F:54:39",CR]
SERIN 0,84,[WAIT("ACK",CR)]
WaitForConnection:
IF IN5 =0 THEN WaitForConnection
main:
serialIn(0) =0
SERIN 0,84,1000,main,[STR serialIn\3\"!"]
PAUSE 100
LOOKDOWN serialIn(0),[100,101],serialIn
BRANCH serialIn,[test1, test2]
SEROUT 1,84,["none", CR]
PAUSE 5
GOTO main
test1:
SEROUT 1,84,["a"]
GOTO main
test2:
SEROUT 1,84,["b"]
GOTO main

Al copiar este cdigo en su BASIC Stamp, para tener acceso completo de su robot ahora sin cables,
todo lo que tiene que hacer es cambiar el ID de puerto serie.
2.7 Resumen Del Captulo
Mi objetivo en este captulo es presentarle a la utilizacin de la API J ava Communications para
hablar con su microcontrolador. Esperemos que, ahora sabe un poco ms de cmo hacer esto. En la
seccin 2.0, he creado ListOpenPorts.java. Esta clase le ense a iterar a travs de todos los puertos
de comunicacin para llegar a los puertos serie con una identificacin com especfico en el nombre
del puerto. Tambin he aadido una clase de Utilidades que me permita llamar a la funcin
Thread.sleep mientras se pone la excepcin.
En la seccin 2.1, he creado la interfaz J SerialPort y StandardSerialPort. La interfaz proporciona un
comportamiento uniforme para todos los puertos serie, incluyendo el WebSerialClient que se
discute en la seccin 2.3. La clase StandardSerialPort prev un acceso ms sencillo a la API COM
para nuestro uso de la robtica.
En la seccin 2.2, se cre un fondo de recursos de StandardSerialPorts para que estos puertos se
puede acceder al mismo tiempo de una manera multiproceso.
En la seccin 2.3, he creado una forma de acceder al puerto serie a travs de Internet con el
WebSerialPort, webcom.jsp y WebSerialClient.
En la seccin 2.4, he conectado al microcontrolador Basic Stamp.
En la seccin 2.5, he creado la interfaz J Controller y Contralor. La interfaz proporciona un
comportamiento estandarizado para todos los controladores y el controlador es una superclase
abstracta que proporciona funcionalidad para todos los controladores de Parallax que se utilizan en
este libro.
Por ltimo, en la seccin 2.6 te mostr un ejemplo de programa BASIC que permite el acceso
inalmbrico a Bluetooth con su microcontrolador de un puerto serie proporcionado por un
adaptador de Bluetooth.
En el siguiente captulo, nos basaremos en la comunicacin serie y modelos ms componentes del
robot para conseguir que el robot se mueva. Vamos a trabajar con robots con patas, robots con
ruedas, brazos robticos, y algunos otros tipos de controladores robticos.






















CAPTULO 3


Movimiento



"Cada objeto en un estado de movimiento uniforme tiende a permanecer en ese estado de
movimiento a menos que una fuerza externa se aplica a ella."
--Primera Ley de Newton

3.0 Introduccin
La fabricacin para que su robot se mueva es mucho ms fcil hoy en da con el advenimiento de
Controladores Servo serie (SSC) y controladores electrnicos de velocidad (ESC). Todos ellos
utilizan el mismo mecanismo para mover, un ancho de pulso (PWM) diseado para controlar la
posicin de un servo. Un servo es un pequeo motor que permite colocar la posicin de su
engranaje de salida con precisin por una seal PWM. La Figura 3-1 muestra una imagen del servo
estndar, que es lo principal, he usado para las unidades diferenciales, los brazos, las piernas y los
robots.

Ilustracin 3-1 Servo Standard Hitec HSS-422

En un SSC, se tienen entre 8 a 32 servos que usted puede controlar. Usted digitalmente puede
colocarlos con byte de precisin (0-255) donde 0 sera completamente en sentido horario (CW) y
255 sera completamente en sentido horario (hacia la izquierda). En un CES, los mismos intervalos
digitales (0-255) representan la velocidad de un motor de corriente continua hacia adelante o hacia
atrs. As, en funcin de cmo tenga los terminales conectados, 0 podra representar toda velocidad
hacia delante, hacia atrs 255 podra ser toda velocidad, y 127 podra significar detencin. Mientras
que usted puede controlar servos PWM mediante el envo de seales a travs de un
microcontrolador, est limitado en el nmero de servos que usted puede controlar a la vez, ya que
por lo general tendr que tomar lecturas de los sensores, tomar decisiones sobre qu camino tomar,
o qu medidas tomar a continuacin , y as sucesivamente. Si usted no tiene un controlador servo,
puede escribir un programa BASIC Stamp que simular un controlador servo, pero te recomiendo
que conseguir uno para el Captulo 7. En el Ejemplo 3-1, el programa realizar un bucle en
intervalos de 10-milisegundos si no se recibe de la serie en (SERIN) se mueve al antiguo. Debido a
que los valores anteriores no se han sobrescrito, el programa enva los antiguos valores de pulsout
para el antiguo pin y pos. Este ejemplo slo funciona para un pin a la vez.
Ejemplo 3-1 Servo.bs2
'{$STAMP BS2}
'{$PORT COM1}
pin VAR Byte
oldPin VAR Byte
pos VAR Byte
oldPos VAR Byte
pulse VAR Word
main:
SERIN 16,16468,old,10,[WAIT(255), pin, pos]
pulse =(pos/255)*750
pulsout pin,750+pulse
oldPin =pin
oldPos =pos
GOTO main
old:
pulse =(oldPos/255)*750
pulsout oldPin,750+pulse
GOTO main

Este captulo contiene 21 ejemplos de clases de J ava y el ejemplo anterior BASIC Stamp. El
primero de ellos se encargar del acceso a controladores de servo, seguido de ejemplos de robots
con ruedas, los brazos robot, y robots con patas.

Ilustracin 3-2 Un controlador servo y un servo con ruedas
Puede conectar el controlador servo para el puerto serie a travs del conector RJ -11 (conector de
telfono) o por el puente de la placa. No he mostrado la conexin de alimentacin a los servos. Esto
debera ser 3,8 a 6,0 voltios (a veces se puede ir tan alto como 7,2 voltios para servos de alta
calidad). Tambin hay un conector para una batera de 9 - a 12-voltios para la alimentacin del
circuito del controlador.
Nota: Consulte el Apndice B para obtener ms informacin sobre mas controladores.
Una vez que conecte el controlador servo al puerto serie de su PC, usted est listo para programar.
3.0 Controladores Servo
Los controladores servo simplifican en gran medida la capacidad de la PC para comunicarse con los
servos y los controles electrnicos de velocidad, al igual que un microcontrolador simplifica la
capacidad de la PC para comunicarse con los sensores.
Antes de empezar a programar en realidad nuestros controladores, me gustara hacer una nota sobre
la sincronizacin. Cuando se mueve un servo a una posicin entre 0 y 180 grados, hay un tiempo
mnimo que se necesita para mover el servo a esa posicin. Para su servo estndar, toma 480
milisegundos para mover 180 grados. Tambin, puesto que va a enviar esta solicitud a travs de un
puerto serie, el tiempo que se tarda en enviar un comando de 3 bytes a una velocidad de 9.600
baudios tarda unos 3 milisegundos por byte, para un total de 12 milisegundos. Para ayudar con la
discusin, he incluido un diagrama de clases (ver Ilustracin 3-3) de las tres clases principales, as
como sus homlogos del Captulo 2: J SerialPort para comunicaciones serie, J Controller para la
normalizacin del controlador y el Controlador, que se extiende en SSC.

Ilustracin 3-3 Diagrama de clases de la clases de la seccin 3-1
La Ilustracin 3-4 ofrece una foto de primer plano de la MiniSSC-II. Empec a trabajar con esta
SSC hace unos aos y me encanta. En la actualidad, hay controladores ms poderosos, pero este era
el original y tengo tres, uno para Feynman5, uno por un brazo de robot, y uno para un repuesto.


Ilustracin 3-4 Controlador Servo MiniSSC-II
Puede conectarse a l con 2400 o 9600 baudios y tiene una potencia de hasta 8 servos. Para obtener
ms informacin detallada, por favor referirse a cualquier de las siguientes pginas
www.lynxmotion.com o www.seetron.com / ssc.htm. Asegrese de consultar el manual para
finalizar las conexiones.
Objetivos del Cdigo
Los objetivos de este cdigo de ejemplo son los siguientes:
Utilice nuestro puerto serial para controlar el posicionamiento del servo (SerialSsc.java)
Crear una interfaz de protocolo estandarizado para el Stamp y otras implementaciones de la
clase (SSC.java).
Discusin del Cdigo
El primer ejemplo muestra cmo se puede obtener una SSC a trabajar slo por el uso de la
StandardSerialPort (aplicacin de un J SerialPort) del ltimo captulo.
La clase mover el servo completo de CW a completo CCW (0 a 255). Hice una pausa para el
servo de 100 milisegundos entre las posiciones para que podamos ver como para en cada posicin.
Una vez que este ciclo se ha completado, cierro el puerto serie. (Vase el Ejemplo 3-2.)
Ejemplo 3-2 Servo.bs2
package com.scottpreston.javarobot.chapter3;
import com.scottpreston.javarobot.chapter2.StandardSerialPort;
public class SerialSsc {
public static void main(String[] args) {
try {
// Crea el Puerto Serie
StandardSerialPort serialPort =new StandardSerialPort(1);
// Incrementa la posicion por 5 cada vez en el bucle.
for (int pos =0; pos <255; pos =pos +5) {
// Crea un arreglo de byte para los comandos del SSC
byte[] sscCmd =new byte[] { (byte) 255, 0, (byte) pos };
// Envia el arreglo de byte al puerto serie
serialPort.write(sscCmd);
// Pausa entre los comandos
Thread.sleep(100);
}
// Cierra el Puerto Serie
serialPort.close();
} catch (Exception e) {
// Imprime hasta encontrar la pila de salida
e.printStackTrace();
System.exit(1);
}
}
}

Mientras que la clase anterior, hace exactamente lo que yo quiero, yo pensaba que, dado todo el
trabajo en las siguientes secciones y captulos que sera una buena idea para estandarizar la
comunicacin al SSC, ya que su protocolo de comunicacin es fija. Para ello, he creado la interfaz
SSCProtocol.java. Tiene un nico mtodo definido, move (pin, pos). El mtodo tiene los siguientes
parmetros: pin-pin de la posicin que el servo est enchufado, y pos-la posicin del servo de 0 a
255. Tambin he aadido algunas constantes para simplificar clases usando este protocolo. (Vase
el Ejemplo 3-3.)
Ejemplo 3-3 SSCProtocol.java
package com.scottpreston.javarobot.chapter3;
public interface SSCProtocol {
// Mximo
public static final byte MAX =(byte) 255;
// Neutral
public static final byte NEUTRAL =(byte)127;
// Mnimo
public static final byte MIN =(byte) 0;
/**
* @param pin - connector on the MiniSSC 0-7
* @param pos - byte from 0-255
*/
public void move(int pin, int pos) throws Exception;
}

Ahora que tengo una interfaz definida para todas las comunicaciones SSC, estoy listo para crear la
clase base SSC. Al igual que Controller.java hice esta clase abstracta porque quiero escribir dos
implementaciones que la funcionalidad de reutilizacin (por ejemplo, el mtodo move ()). Esta
clase tiene un solo campo, maxPin, porque tambin quiero diferenciar cuntos pines de cada clase
hija de la SSC tiene. Dependiendo del controlador servo que tiene, asegrese de establecer esta
consecuencia.

El constructor toma el J SerialPort. En el mtodo de movimiento, agrego el manejo de errores para
los parmetros de entrada, lanzando una excepcin si los parmetros estn fuera de los lmites, y
luego crear un byte [] con los parmetros antes de llamar al mtodo execute de la clase principal
Controller. En el byte [] envi a travs del mtodo execute(), he aadido el byte de sincronizacin
de 255 cada vez, porque sabemos que tenemos que enviar como parte de la SSCProtocol. (Vase el
Ejemplo 3-4.)
Ejemplo 3-4SSC.java
package com.scottpreston.javarobot.chapter3;
import com.scottpreston.javarobot.chapter2.Controller;
import com.scottpreston.javarobot.chapter2.J SerialPort;
public abstract class Ssc extends Controller implements SSCProtocol{
//Mximo posible del LM32
private int maxPin =31;
// Toma el J SerialPort
public Ssc(J SerialPort serialPort )throws Exception {
super(serialPort);
}
// El movimiento enviar una seal al pin (0-7) and pos (0-255)
public void move(int pin, int pos) throws Exception{
// Mantiene en un rango vlido en POS
if (pos <0 || pos >255) {
throw new Exception("Position out of range, must be
between 0 and 255. Value was " +pos +".");
}
//Mantieneen un rango vlido el PIN
if (pin <0 || pin >maxPin) {
throw new Exception("Pin out of range, must be between 0 and "
+maxPin +". Value was " +pin +".");
}
// Crea byte[] para los comandos
byte [] b =new byte[] {(byte)255,(byte)pin,(byte)pos};
// Envia los bytes al Controlador
execute(b,0);
}
// Acceso
public int getMaxPin() {
return maxPin;
}
// setter
public void setMaxPin(int maxPin) {
this.maxPin =maxPin;
}
}

Ahora que en general la super-clase ha sido creada, es mommento de crear una clase especfica para
MiniSSC-II. Esta clase no tiene campos y simplemente llama al constructor padre y al mtodo
setMaxPin para limitar los siete pins en total. En el ejemplo programo en el main(), llamo a la
misma lgica que compone la clase SerialSSC en el Ejemplo 3-2. Muevo el servo a travs del rango
de movimiento en incrementos de 5-byte. Se habr dado cuenta de que su estructura de mando es
ms simple (no bytes para crear o lanzar), y usted tiene el control de errores construido adentro
(Vea el Ejemplo 3-5.).
Ejemplo 3-5 MiniSSC.java
package com.scottpreston.javarobot.chapter3;
import com.scottpreston.javarobot.chapter2.J SerialPort;
import com.scottpreston.javarobot.chapter2.SingleSerialPort;
import com.scottpreston.javarobot.chapter2.Utils;
public class MiniSsc extends Ssc implements SSCProtocol {
// calls super and sets max pin to 7
public MiniSsc(J SerialPort serialPort) throws Exception {
super(serialPort);
setMaxPin(7);
}
// Programa de Ejemplo
public static void main(String[] args) {
try {
// Obtener una sola instancia del Puerto Serie
J SerialPort sPort =(J SerialPort) SingleSerialPort.getInstance(1);
// Crea un nuevo MiniSSC
MiniSsc ssc =new MiniSsc(sPort);
// Muevo desde la posicin 0 a 255, 5 por 100 ms
for (int pos =0; pos <255; pos =pos +5) {
// Muevo
ssc.move(0, pos);
// Espera 100 milisegundos
Utils.pause(100);
}
// Cierro el Puerto Serie
sPort.close();
} catch (Exception e) {
// Imprime hasta encontrar la pila de salida
e.printStackTrace();
System.exit(1);
}
}
}

Resumen de la Seccin
En esta seccin, se mostr una manera difcil y una forma fcil de modelar un controlador servo.
Tambin se agrego una interfaz para asegurar la comunicacin para controladores diferentes y se
aadi una implementacin para el MiniSSC-II. Las clases tratados fueron los siguientes:
SerialSsc.java: Una versin de serie del control de servo (un ejemplo de una manera dura)
SSCProtocol.java: una interfaz diseada para estandarizar la comunicacin a un controlador
servo.
SSC.java: Super-clase utilizada por las clases MiniSSC y otro para la comunicacin servo
MiniSSC.java: Clase de Implementacin para el de Scott Edwards MiniSSC-II
Ahora que ya sabe cmo controlar servos con su PC, usted est listo para conseguir un robot para
moverlo .En la siguiente seccin, voy a hablar acerca de los robots de accionamiento diferenciales
(con dos ruedas) y va a utilizar la MiniSSC y puerto serial de su PC para que se mueva.
3.2 Movimiento de ruedas
El uso de un controlador servo conectado a un controlador electrnico de velocidad o un par de
"hackeado" o servos de rotacin continua es una manera excelente para facilitar el movimiento de
ruedas. La Ilustracin 3-5 muestra una imagen de la unidad diferencial, un CubeBot conectado a un
MiniSSC-II. Observe que los cables de servo son para la parte trasera de la plataforma. Esto
significa que los motores estn invertidos, as que voy a tener que dar cuenta de ello en las clases de
esta seccin.

Ilustracin 3-5 La unidad diferencial de una CubeBot
Tres clases y una interfaz se analizar en esta seccin. La Ilustracin 3-6 muestra un diagrama de
clases que resume las clases.


Ilustracin 3-6 Un diagrama de clase de las clases en la seccin 3.2
Objetivos del Cdigo
El objetivo de esta seccin es proporcionar a los movimientos bsicos: adelante, atrs, giro a la
derecha, giro a la izquierda, y se detendr.
Discusin del Cdigo
Voy a empezar esta seccin escribiendo una clase bsica de manejo diferencial, llamado
BasicDiffDrive. Los campos de esta clase tienen un campo de instancia nica, ssc, para la clase
MiniSSC, que controla los servos y proporciona su funcionalidad. Tambin tengo dos constantes
que representan las conexiones de hardware para las ruedas izquierda y derecha. Los campos
restantes se utilizan para mantener el estado de las posiciones de los servos para velocidades
constantes o variadas.
El constructor para esta clase toma un J SerialPort, que construye la MiniSSC. El mtodo
setMotors() establece los parmetros relativos a la posicin y el movimiento de la SSC. Este mtodo
es seguido por move(), que llama al mtodo MiniSSC del mismo nombre.
Los cuatro mtodos de direccin- forward(), reverse(), pivotLeft(), y pivotRight()-tienen dos
funciones: primero, para comprobar si los motores estn conectados en una forma invertida (como
el CubeBot), y luego a establecer los valores de los motores, y en segundo lugar, para llamar al
mtodo move. Aunque podra haber llamado a ssc.move (), lo que ms tarde me permite ampliar y
agregar un control de velocidad, no habra podido volver a utilizar el mtodo de las subclases
posteriores. Sin embargo, si no desea el control de velocidad, puede simplificar esto con slo
introducir las posiciones para que se muevan directamente en cada uno de los cuatro mtodos de
direccin.
Los emisores y los mtodos de descriptor de acceso se incluyen para que las clases pueden acceder
a las variables de derecha e izquierda de las subclases TimedDiffDrive. Por ltimo, en el main()
puedo probar la clase enviando el robot hacia adelante por 2 segundos, y luego se detienen.(Vase
el Ejemplo 3-6.)
Ejemplo 3-6 BassicDriffDriver.java
package com.scottpreston.javarobot.chapter3;
import com.scottpreston.javarobot.chapter2.J SerialPort;
import com.scottpreston.javarobot.chapter2.SingleSerialPort;
import com.scottpreston.javarobot.chapter2.Utils;
public class BasicDiffDrive {
// Driver que usar el MiniSSC
private MiniSsc ssc;
// Rueda izquierda enganchada al pin0
public static final int LEFT_WHEEL =0;
// Rueda derecha enganchada al pin1
public static final int RIGHT_WHEEL =1;
// Establece todo los valores neutrales
private int right =SSCProtocol.NEUTRAL;;
private int left =SSCProtocol.NEUTRAL;
private int rightHigh =SSCProtocol.MAX;
private int rightLow =SSCProtocol.MIN;
private int leftHigh =SSCProtocol.MAX;
private int leftLow =SSCProtocol.MIN;
// right will always be the one inverted can change this
private boolean motorsInverted =false;
// El constructor toma a J SerialPort
public BasicDiffDrive(J SerialPort serialPort) throws Exception {
// Crea MiniSSC
ssc =new MiniSsc(serialPort);
}
// Configura los valores del motor
public void setMotors(int left, int right) {
this.left =left;
this.right =right;
}
// Mueve realmente los motores
private void move() throws Exception {
// Rueda izquierda
ssc.move(LEFT_WHEEL, left);
// Rueda derecha
ssc.move(RIGHT_WHEEL, right);
}
// Mueve en reversa
public void reverse() throws Exception {
// if inverted move motors opposite or same.
if (motorsInverted) {
// Direccion opuesta
setMotors(leftHigh, rightLow);
} else {
// Misma direccin
setMotors(leftHigh, rightHigh);
}
// Mueve el motor
move();
}
// Mueve hacia adelante
public void forward() throws Exception {
if (motorsInverted) {
setMotors(leftLow, rightHigh);
} else {
setMotors(leftLow, rightLow);
}
move();
}
// Gira el eje a la derecha
public void pivotRight() throws Exception {
if (motorsInverted) {
setMotors(leftLow, rightLow);
} else {
setMotors(leftLow, rightHigh);
}
move();
}
// Gira el eje a la izquierda
public void pivotLeft() throws Exception {
if (motorsInverted) {
setMotors(leftHigh, rightHigh);
} else {
setMotors(leftHigh, rightLow);
}
move();
}
// Para el movimiento
public void stop() throws Exception {
// Establece los motores al mismo valor
setMotors(SSCProtocol.NEUTRAL, SSCProtocol.NEUTRAL);
move();
}
// Acceso
public boolean isMotorsInverted() {
return motorsInverted;
}
// Seteo
public void setMotorsInverted(boolean motorsInverted) {
this.motorsInverted =motorsInverted;
}
// Acceso
public int getLeftHigh() {
return leftHigh;
}
// Seteo
public void setLeftHigh(int leftHigh) {
this.leftHigh =leftHigh;
}
// Acceso
public int getLeftLow() {
return leftLow;
}
//Seteo
public void setLeftLow(int leftLow) {
this.leftLow =leftLow;
}
// Acceso
public int getRightHigh() {
return rightHigh;
}
// Seteo
public void setRightHigh(int rightHigh) {
this.rightHigh =rightHigh;
}
// Acceso
public int getRightLow() {
return rightLow;
}
// Seteo
public void setRightLow(int rightLow) {
this.rightLow =rightLow;
}
// Simple Programa
public static void main(String[] args) {
try {
// Obtener la instancia de SingleSerialPort
J SerialPort sPort =(J SerialPort) SingleSerialPort.getInstance(1);
// Crea una instancia de BasicDiffDrive
BasicDiffDrive diffDrive =new BasicDiffDrive(sPort);
// Mueve hacia adelante
diffDrive.forward();
// Pausa de 2 segundos
Utils.pause(2000);
// Parada
diffDrive.stop();
// Cierra el puerto serie
sPort.close();
} catch (Exception e) {
// Imprime hasta obtener la pila de salida
e.printStackTrace();
System.exit(1);
}
}
}

La siguiente clase simplifica un poco el movimiento mediante la adicin de pause() y stop(). Al
extender la clase BasicDiffDrive y la creacin de nuevos mtodos con parmetros para tener un
argumento milisegundo, nuestro robot puede moverse en una direccin particular durante una
unidad de tiempo dada. (Vase el Ejemplo 3-7.)
Nota: he encontrado que el uso de resolucin de milisegundos es tan exacta como los
codificadores de rueda a travs de distancias cortas (<3 metros o segundos <10). Esto es
debido a que el deslizamiento de las ruedas y el tiempo para detener las exactitudes son en
su extremo inferior con estas distancias y velocidades. Pero incluso estas deficiencias son
superadas por los sensores de medicin de distancia con el fin de eliminar la "prctica"
necesidad de encoders de rueda.
Ejemplo 3-7 TimedDiffDriver.java
package com.scottpreston.javarobot.chapter3;
import com.scottpreston.javarobot.chapter2.J SerialPort;
import com.scottpreston.javarobot.chapter2.SingleSerialPort;
import com.scottpreston.javarobot.chapter2.Utils;
public class TimedDiffDrive extends BasicDiffDrive {
//Constructor con J SerialPort
public TimedDiffDrive(J SerialPort serialPort) throws Exception {
super(serialPort);
}
// Hacia adelante
public void forward(long ms) throws Exception {
// Super llamada
forward();
// Pausa
Utils.pause(ms);
// Parada
stop();
}
// Reversa
public void reverse(long ms) throws Exception {
reverse();
Utils.pause(ms);
stop();
}
// Giro hacia la izquierda
public void pivotLeft(long ms) throws Exception {
pivotLeft();
Utils.pause(ms);
stop();
}
// Giro hacia la derecha
public void pivotRight(long ms) throws Exception {
pivotRight();
Utils.pause(ms);
stop();
}
// Programa Simple
public static void main(String[] args) {
try {
// Obtener instancia de SingleSerialPort
J SerialPort sPort =(J SerialPort) SingleSerialPort.getInstance(1);
// Creando la instancia de TimedDiffDrive
TimedDiffDrive diffDrive =new TimedDiffDrive(sPort);
// Mueve hacia adelante por 2 segundos
diffDrive.forward(2000);
// Cierre del puerto serie
sPort.close();
} catch (Exception e) {
// Imprime hasta encontrar en la pila la salida
e.printStackTrace();
System.exit(1);
}
}
}

La ltima cosa que necesito para la unidad diferencial sea completa es un control de velocidad. Sin
embargo, no siempre se han rodado robots. Yo podra querer implementar clases de navegacin con
robots con patas o las implementaciones de otros sectores de la unidad diferencial (tal vez incluso
un carro con el acelerador, freno y volante). En este caso, porque quiero volver a usar mis clases de
navegacin (vase el captulo 7), debera crear una interfaz y luego usar esa interfaz en clases
posteriores. La interfaz que voy a crear es J Motion. Esta clase tiene todos los mtodos de
BasicDiffDrive y TimedDiffDrive, adems de los mtodos para el control de velocidad. (Vase el
Ejemplo 3-8.)
Ejemplo 3-8 La interface JMotion.java
package com.scottpreston.javarobot.chapter3;
public interface J Motion {
// hacia adelante
public void forward() throws Exception;
// reversa
public void reverse() throws Exception;
// giro derecho
public void pivotRight() throws Exception;
// giro izquierdo
public void pivotLeft() throws Exception;
// parada
public void stop() throws Exception;
// hacia adelante
public void forward(int ms) throws Exception;
// reversa
public void reverse(int ms) throws Exception;
// giro derecho
public void pivotRight(int ms) throws Exception;
// giro izquierdo
public void pivotLeft(int ms) throws Exception;
// ajuste de velocidad del robot
public void setSpeed(int speed)throws Exception ;
// obtener la velocidad del robot
public int getSpeed();

Nota: La velocidad no funcionar en un servo hackeado porque es bien completa o total en
off. All tendr que retrasar los ciclos de encendido y apagado de tu servo a algo muy
rpido. Puede ser difcil conseguir que esto funcione y sea suave dada nuestra tasa de
baudios. Sin embargo, no va a funcionar bien para un control electrnico de velocidad
(ECS), pero es posible que desee ajustar la velocidad a una resolucin mayor que 10.
En la clase SpeedDiffDrive, yo implemento la interfaz J Motion y tiene una velocidad de campo que
he de pagar a 5. El setSpeed () es el corazn del mtodo, ya que establece los valores altos para el
servo controlador, as como los valores bajos. Por lo tanto, a una velocidad de 10, el alto valor sera
255, mientras que a una velocidad de 9 sera 255 a 13 (12,7) =242, y as sucesivamente. En la parte
inferior al de la clase, por eso tengo que implementar los mtodos de la interfaz que ya existen en la
super-clase. Por qu tenemos que crear slo tiene que pasar a travs de? J ava no soporta herencia
mltiple, por lo que el compilador slo ve el mtodo BasicDiffDrive para la interfaz y no la clase
TimedDiffDrive. (Vase el Ejemplo 3-9.)
Ejemplo 3-9SpeedDiffDrive.java
package com.scottpreston.javarobot.chapter3;
import com.scottpreston.javarobot.chapter2.J SerialPort;
import com.scottpreston.javarobot.chapter2.SingleSerialPort;
public class SpeedDiffDrive extends TimedDiffDrive implements J Motion{
// Ajuste de Velocidad Inicial
private int speed =5;
// Constructor con J SerialPort
public SpeedDiffDrive(J SerialPort serialPort) throws Exception{
super(serialPort);
}
// Acceso para la Velocidad
public int getSpeed() {
return speed;
}
// Seteo de Velocidad
public void setSpeed(int speed) throws Exception {
// Mantiene la Velocidad en tre MIN y MAX
if (speed <1 || speed >10) {
throw new Exception("Speed out of range 1-10.");
}
// Ajuste de Velocidad
this.speed =speed;
// get high for left
setLeftHigh(getSpdHI());
// get low for left
setLeftLow(getSpdLO());
// get high for right
setRightHigh(getSpdHI());
// get low for right
setRightLow(getSpdLO());
}
// get speed as fraction of 127 (half of MiniSSC)
private int getSpd() {
double s =(double) 127 * (speed / 10.0);
return (int) s;
}
// Retorna Velocidad alta
private int getSpdHI() {
return getSpd() +127;
}
// Retorna Velocidad baja
private int getSpdLO() {
return 127 - getSpd();
}
// Codigo simple
public static void main(String[] args) {
try {
// Obtiene la instancia de SingleSerialPort
J SerialPort sPort =(J SerialPort)SingleSerialPort.getInstance(1);
// Crea la instancia de SpeedDiffDrive
SpeedDiffDrive diffDrive =new SpeedDiffDrive(sPort);
// Ajuste de Velocidad de 5
diffDrive.setSpeed(5);
// Avanzar 2 segundos
diffDrive.forward(2000);
// Cierra el puerto
sPort.close();
} catch (Exception e) {
// Imprima hasta conseguir la pila de salida
e.printStackTrace();
System.exit(1);
}
}
// Para interface passthroughs
public void forward(int ms) throws Exception{
super.forward(ms);
}
public void reverse(int ms) throws Exception{
super.reverse(ms);
}
public void pivotRight(int ms) throws Exception{
super.pivotRight(ms);
}
public void pivotLeft(int ms) throws Exception{
super.pivotLeft(ms);
}
}

Resumen De La Seccin
Las tres clases de esta seccin te llevar a travs del movimiento de ms ruedas utilizando un
controlador servo de serie y / o control de velocidad electrnico. Las clases que se trataron fueron:
BasicDiffDrive.java: El control diferencial de la unidad bsica.
TimedDiffDrive.java: La versin extendida de BasicDiffDrive que permite el movimiento
que se producen a intervalos de tiempo especficos.
J Motion.java: La interfaz que define los movimientos bsicos de todos los tipos de
movimiento (para ruedas y robots con patas)
SpeedDiffDrive.java: La versin extendida de TimedDiffDrive que le da el control de
velocidad a cualquier movimiento.
El siguiente tipo de movimiento todava va a hacer con servos, pero esta vez se pasar; algo en su
robot en lugar del propio robot. Se basan en los mismos principios discutido aqu, pero en vez de
crear mtodos como forward () o pivotRight (), se crear mtodos como lookup () o lookRight ()
para mover la cmara.......
3.3 Pan Y Mecanismos De Inclinacin
A veces slo quiero trasladar parte de su robot. Si usted tiene una cmara y estn haciendo algunas
cosas con visin artificial (vase el captulo 6), entonces usted definitivamente quiere un pan y un
sistema de cmara de inclinacin. El que yo uso se muestra en la Ilustracin 3-7 y comprende unos
pocos soportes y dos servos, que se pueden adquirir a partir de Lynxmotion por menos de $ 35. Yo
tomo a los mismos conceptos utilizados en nuestros sistemas de accionamiento diferencial como
agrupar servos juntos en una clase, y luego vamos a usar nuestra clase MiniSSC para controlar los
servos.

Ilustracin 3-7 El Pan Tilt Lynxmotion y su Kit
La Ilustracin 3-8 muestra un diagrama que resume las clases.

Ilustracin 3-8 Resumen de las Clases
Objetivos del Cdigo
El objetivo de esta seccin es crear una clase para controlar un mecanismo de inclinacin de la base
y de un controlador servo.
Discusin del Cdigo
La parte ms importante de esta clase es el preconfigurado de constantes, por ejemplo, qu pins
conectar los servos? Hasta qu punto pueden los servos moverse? Cules son las posiciones de
reposo? Estas son las cosas que usted tendr que experimentar. Los campos restantes son stepSize
(cantidad de bytes que el sistema se mover en pasos por defecto en tres), velocidad (la velocidad
del servo se mover entre los pasos) y el MiniSSC, que hace el trabajo.
El constructor es la J SerialPort y el mtodo de movimiento llama a mtodos separados para mover
los servos de control horizontal y vertical. Los dos mtodos horz() y vert() se ver en los valores de
posicin actuales y luego envia correspondientes seales en serie a la SSC, siempre y cuando las
posiciones estn dentro del alcance del sistema de giro e inclinacin. En lugar de siempre en
posiciones de byte de 0 a 255, he aadido dos mtodos horzDegree() y vertDegree() que convierte
ngulos de 0 a 180, y bytes desde 0 a 255. Los mtodos existen para mover la base y mecanismo de
inclinacin en pasos. Esto es til si usted tiene un sistema de cmaras de seguimiento y usted slo
quiere dar un paso en una direccin, pero no s hasta qu punto a la izquierda, derecha, arriba o
abajo desea mover.
Porque quiero que el pan y tilt para moverse sin problemas desde una posicin a otra en el mtodo
setServoTiming (), para realizar alguna comprobacin de errores y ver si el tipo de movimiento
especificado es mayor que la velocidad mxima. Por ejemplo, si el servo puede pasar de 0 a 90
grados en 240 milisegundos, y quiero que se mueva all en 200 milisegundos, necesito una
excepcin porque el servo no puede moverse tan rpido.
Adems, si el tamao de paso es menor que el tamao mnimo, necesito una excepcin porque el
servo slo puede responder a las seales tan rpido como el controlador serial pueda enviar a una
velocidad de 9600 baudios.
En la prueba el mtodo main (), que es una instancia de la clase PanTilt con el StandardSerialPort
(J SerialPort), y luego moverse hacia la izquierda hasta que est en su lmite, luego a la derecha,
luego hacia arriba y luego hacia abajo. Aunque una excepcin es una manera bastante descuidada
de codificacin, yo quera mostrar cmo se pueden utilizar las excepciones para evitar que el
sistema se haga dao a s mismo. (Vase el Ejemplo 3-10.)





Ejemplo 3-10 PanTilt.java
package com.scottpreston.javarobot.chapter3;
import com.scottpreston.javarobot.chapter2.J SerialPort;
import com.scottpreston.javarobot.chapter2.SingleSerialPort;
public class PanTilt{
// Conectado el pin 6 a MinSSC-II
public static final int HORZ_SERVO =6;
// conectada a la patilla 7 de MinSSC-II
public static final int VERT_SERVO =7;
private int horzPos =SSCProtocol.NEUTRAL;
private int vertPos =SSCProtocol.NEUTRAL;
// should set these to the best limits of your pan/tilt system
public static final int MAX_UP =145;
public static final int MAX_DOWN =45;
public static final int MAX_RIGHT =235;
public static final int MAX_LEFT =25;
public static final int VERT_NEUTRAL =95;
public static final int HORZ_NEUTRAL =140;
// 3 milisegundos a 9600 baudios
public static final int MIN_STEP_SIZE =3;
// 2 milisegundos para servo standard
public static final int MIN_DELAY_SIZE =2;
// retardo en milisegundos entre movimientos
private int moveDelay =50;
// tamao en bites de nico paso
private int stepSize =MIN_STEP_SIZE;
private int speed =0;
// MiniSSC haciendo el trabajo
private MiniSsc ssc;
// tomando el constructor J SerialPort
public PanTilt(J SerialPort sPort) throws Exception{
ssc =new MiniSsc(sPort);
}
// moviendo los servos a las posiciones
private void move() throws Exception {
horz(horzPos);
vert(vertPos);
}
mover los servos con parmetros de entrada
// h =horizontal servo
// v =vertical servo
public void moveBoth(int h, int v) throws Exception{
// establece campos privados
horzPos =h;
vertPos =v;
// move
move();
}
public void horz(int pos) throws Exception{
// check to see if position within limits
if (pos <MAX_LEFT || pos >MAX_RIGHT ) {
throw new Exception("Out of horizontal range.");
}
// establece el pos
horzPos =pos;
// movimiento
ssc.move(HORZ_SERVO,pos);
}
public void horzDegree(int angle) throws Exception{
// comprobar para ver si el ngulo est dentro de los lmites de 0-180
if (angle <0 || angle >180) {
throw new Exception("Out of range, angle 0-180.");
}
// convierte fraccin de 255
double theta =((double)angle/180 ) * 255.0 ;
// movimiento
horz((int)theta);
}
public void vert(int pos) throws Exception{
if (pos <MAX_DOWN || pos >MAX_UP ) {
throw new Exception("Out of vertical range.");
}
vertPos =pos;
ssc.move(VERT_SERVO,pos);
}
public void vertDegree(int angle) throws Exception{
if (angle <0 || angle >180) {
throw new Exception("Out of range, angle 0-180.");
}
double theta =((double)angle/180 ) * 255.0 ;
vert((int)theta);
}
// reseteo a posicion actual
public void reset( ) throws Exception{
horzPos =HORZ_NEUTRAL;
vertPos =VERT_NEUTRAL;
move();
}
// movimiento derecho con pasos especficos
public void moveRight(int size) throws Exception{
horz(horzPos+size);
}
// movimiento actual derecho stepSize
public void moveRight()throws Exception {
moveRight(stepSize);
}
public void moveLeft(int size) throws Exception{
horz(horzPos-size);
}
public void moveLeft()throws Exception {
moveLeft(stepSize);
}
public void moveUp(int size) throws Exception{
vert(vertPos+size);
}
public void moveUp()throws Exception {
moveUp(stepSize);
}
public void moveDown(int size) throws Exception{
vert(vertPos-size);
}
public void moveDown()throws Exception {
moveDown(stepSize);
}
// acceso
public int getHorzPos() {
return horzPos;
}
// seteo
public void setHorzPos(int horzPos) {
this.horzPos =horzPos;
}
// acceso
public int getVertPos() {
return vertPos;
}
// seteo
public void setVertPos(int vertPos) {
this.vertPos =vertPos;
}
// acceso
public int getSpeed() {
return speed;
}
// seteo
public void setSpeed(int speed) {
this.speed =speed;
}
// seteo sincronizado del servo
// stepSize =size of the step as long as it's not minimum step size
// moveDelay =tiempo de retardo entre los pasos
public void setServoTiming(int stepSize, int moveDelay)
throws Exception {
// asegura el funcionamiento
if (stepSize <MIN_STEP_SIZE) {
throw new Exception("Step size not possible at 9600 baud.");
}
if (moveDelay <(stepSize * MIN_DELAY_SIZE)) {
throw new Exception("Move delay not practical for given step size.");
}
this.stepSize =stepSize;
this.moveDelay =moveDelay;
}
public int getMoveDelay() {
return moveDelay;
}
public int getStepSize() {
return stepSize;
}
// programa simple
public static void main(String[] args) {
try {
// obtiene la instancia de SingleSerialPort
J SerialPort sPort =(J SerialPort)SingleSerialPort.getInstance(1);
// crea la instancia de PanTilt
PanTilt pt =new PanTilt(sPort);
// pan izquierda hasta excepcin
while (true) {
try {
pt.moveLeft();
} catch (Exception e) {
break;
}
}
// pan derecho
while (true) {
try {
pt.moveRight();
} catch (Exception e) {
break;
}
}
// reset head
pt.reset();
// tilt arriba
while (true) {
try {
pt.moveUp();
} catch (Exception e) {
break;
}
}
// tilt abajo
while (true) {
try {
pt.moveDown();
} catch (Exception e) {
break;
}
}
// resetea la cabecera
pt.reset();
// cierra el puerto serie
sPort.close();
} catch (Exception e) {
// imprime hasta encontrar la salida en la pila
e.printStackTrace();
System.exit(1);
}
}
}

Resumen De La Seccin
As que ahora usted puede mover el robot y la posicin de su cmara/ojo (s). Si lo mueve con gracia
todava puede tomar un poco de experimentacin, pero creamos algunas clases que proporcionan la
base para la panormica y la inclinacin y otras configuraciones de servo similares. En esta seccin,
he creado las siguientes dos clases:
PanTilt.java: La clase base para las operaciones de giro e inclinacin
PanTiltSpeed.java: Esta se extiende desde PanTilt para proporcionar un movimiento ms
suave de una posicin a otra.
Aunque esto va a funcionar adecuadamente para la mayora de tareas, es posible que an desea un
movimiento ms suave o necesita ms servos para mover. En tales casos, es posible que desee
probar el Lynxmotion SSC-32 y luego implementar otro protocolo adems de la SSCProtocol lo que
puede pasar ms de un servo con un comando de serie nico. Voy a hablar de eso y ms en la
siguiente seccin.
3.4 Control Servo Avanzada
En el ejemplo anterior, lo que mostr pan y tilt con velocidad y control de errores, se puede ver que
el control de unos pocos servos pueden llegar a ser muy complicado. Mientras se preparan para
discutir los brazos robticos y robots con patas, voy a estar trabajando con ms de dos servos, a
veces hasta 12 en el caso de los Extremos Hexapod 2. Yo tambin quera tener el mismo nivel de
control de la velocidad como lo hice con dos servos, y tambin coordinar los movimientos de ms
de un servo al mismo tiempo. En este ejemplo, quiero centrarme en hacer mi robot resolviendo los
problemas de ms alto nivel, como la navegacin en lugar de dedicar todo mi cdigo y ciclos de
CPU para manejar el control de servo. Afortunadamente, hay un control de servo nuevo en el
mercado con todas esas caractersticas: la Lynxmotion SSC-32 (vase la Ilustracin 3-9). Este
controlador servo permite el control de velocidad y temporizacin. Lo usaremos cuando se habla de
controles avanzados servo y movimientos de grupos.

Ilustracin 3-9 Controlador Servo Lynxmotion SSC-32
El Lynxmotion SSC-32 servo controlador tiene 32 pines de salida en comparacin con los ocho
pines del MiniSSC-II. Tambin permite que el mismo protocolo de comunicacin, por lo que si se
crea algo de cdigo para el MiniSSC, se puede volver a usar con el SSC-32 y puede aumentar la
velocidad de transmisin a 115.200. As, cuando el modelo de este controlador, puede implementar
la misma interfaz SSCProtocol, sino porque viene con algunos otros elementos de construccin en
caractersticas como movimientos agrupados y en su momento, vamos a querer aadir un nuevo
protocolo llamado GroupMoveProtocol. Aunque este protocolo es muy til con el LM32, tambin
puede escribir una clase para el MiniSSC para implementar la interfaz. Entonces usted debe ser
capaz de utilizar hardware Plug N Play (PnP), sin cambiar mucho software.
El Lynxmotion SSC-32 controlador servo tiene 32 pines de salida en comparacin con los ocho
pines del MiniSSC-II. Tambin permite el mismo protocolo de comunicacin, por lo que si se crea
algo de cdigo para el MiniSSC, se puede volver a usar con el SSC-32 y puede aumentar la
velocidad de transmisin a 115.200. As, con el modelo de este controlador, puede implementar la
misma interfaz SSCProtocol, ademsviene con algunos otros elementos de construccin en
caractersticas como movimientos agrupados y en su momento, noxotros vamos a querer aadir un
nuevo protocolo llamado GroupMoveProtocol. Aunque este protocolo es muy til con el LM32,
tambin puede escribir una clase para el MiniSSC para implementar la interfaz. Entonces usted
debe ser capaz de utilizar hardware Plug N Play (PnP), sin cambiar mucho software.
El GroupMoveProtocol es diferente a la SSCProtocol por tres razones: una, puede agrupar un
nmero de servos juntos en un solo comando en lugar de enviar cadenas de comandos para cada
servo, dos, puede introducir la velocidad a la que desea desplazarse por cada canal para desplazarse,
y tres, se puede establecer el movimiento mximo para todo el canal.
Usando el GroupMoveProtocol es dThese tres caractersticas le dan la GroupMoveProtocol un
montn de ventajas sobre el SSCProtocol y ahora ya estamos controlando el tiempo con el
controlador y no el mtodo Thread.sleep (), nuestro programa de control tendr que cambiar
tambin. Estas tres caractersticas le dan la GroupMoveProtocol un montn de ventajas con respecto
a la SSCProtocol y ahora porque estamos controlando sincronizacin con el controlador y no el
mtodo Thread.sleep (), nuestro programa de control tendr que cambiar tambin. En mi clase, yo
quiero tres tipos de mtodos. El primer movimiento se acaba de hacer lo que el SSCProtocol hace,
excepto que voy a dar al mtodo un argumento extra que designa el momento de pasar en
milisegundos. El segundo tipo de movimiento ser un movimiento de grupo. Esto mover todos los
servos en el grupo asociado a la posicin deseada. El tercer tipo de movimiento ser determinar
cmo establecer los grupos y pines. He incluido un diagrama de clases de estas clases en la
Ilustracin3-10.

Ilustracin 3-10 Diagrama UML de las clases de la seccin 3.4
Objetivos Del Cdigo
El objetivo aqu es crear una interfaz para gestionar la GroupMoveProtocol para que pueda ser
implementado por el MiniSSC y LM32.


Ejemplo 3-11GroupMoveProtocol.java
package com.scottpreston.javarobot.chapter3;
public interface GroupMoveProtocol {
public static final String CMD_TERM ="\r";
/**
* This is the SSC Constructor Mode w/500 default speed
* @param ch - channel 0-31
* @param pos - position 0-255
*/
public void sscCmd(int ch, int pos) throws Exception;
/**
* This is the native constructor mode.
* @param ch - channel 0-31
* @param pos - position 0-255
* @param spd - speed in ms
* @param tm =time to move in milliseconds
*
*/
public void cmd(int ch, int pos, int spd) throws Exception;
/**
*
* @param time - length in milliseconds to move
* @throws Exception
*/
public void move(int time) throws Exception;
}
Debido a que el LM32 tiene comandos para la sincronizacin y podemos agrupar los servos, vamos
a tener que hacer mucho menos en nuestra clase, y nuestros tiempos se vern ms suave y ms
fluido.
Objetivos Del Cdigo
El objetivo es poner en prctica el GroupMoveProtocol para el LM32.
Discusin del Cdigo
Uno de los beneficios de un lenguaje agradable es la reutilizacin de cdigo. Tenga en cuenta que
acabo de ampliar la clase SSC, por lo que esta clase va a hacer lo mismo que un estndar MiniSSC-
II....
La diferencia observada en la siguiente clase es que la interfaz es el formato real de la cadena de
comandos en la createCmd mtodo(). Adems, debido a que estamos acostumbrados a tratar con las
posiciones del servo entre 0-255, me dej esto en lugar de que el programa de trabajadores para
realizar un seguimiento de los anchos de pulso entre 750 y 2250 milisegundos.

Los dos campos de la clase son cmds-un StringBuffer y un booleano para indicar el estado de
cualquier clase con este objeto. Debido a que el tiempo est determinado por el LM32, opto por
utilizar un temporizador para indicar la clase de cambio de estado (ocupado =false). Esto se hace a
travs de la setBusy(), mtodo en el que se establece una nica tarea que se ejecute a una hora
determinada en el futuro (ahora +milisegundos en el futuro).
El constructor llama al super constructor con el J SerialPort, y establece el campo maxPins a 32. El
mtodo move() convierte el StringBuffer a un byte [] antes de enviar el puerto serie a travs del
controlador, ejecute mtodo.
Nota: Tenga en cuenta que podra haber puesto en un parmetro aqu por un retraso en la
llamada a execute(), pero yo quera mostrar otra forma de hacer lo mismo sin ocupar
recursos durante un movimiento.
La construccin del comando serie tiene la siguiente sintaxis:
"#" +channel (0-31)
+"P" +pulsewidth (750-1500milliseconds)
+"S" +speed(milliseconds for move)
Puede encadenar hasta 32 comandos juntos antes de tener que darlo por terminado aadiendo lo
siguiente:
"T" +time for total move(milliseconds) +"\r"
El ancho de pulso es el tiempo en milisegundos que he simplificado a travs del mtodo getpw().
ste entregar el ancho de pulso que va de 750 a 1500 de un byte entre 0 y 255. Finalmente, el
programa de prueba utiliza slo dos servos y los mueve a las posiciones 100 y 200,
respectivamente, durante un plazo de tiempo de 1 segundo. (Vase el Ejemplo 3-12.)
Ejemplo 3-12 LM32.java
package com.scottpreston.javarobot.chapter3;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import com.scottpreston.javarobot.chapter2.J SerialPort;
import com.scottpreston.javarobot.chapter2.SingleSerialPort;
import com.scottpreston.javarobot.chapter2.Utils;
public class LM32 extends Ssc implements SSCProtocol, GroupMoveProtocol {
// buffer para almacenar comandos
private StringBuffer cmds =new StringBuffer();
// velocidad predeterminada en milisegundos
public static int DEFAULT_SPEED =500;
// ocupado o no
private boolean busy =false;
// tomando el constructor J SerialPort
public LM32(J SerialPort sPort) throws Exception {
super(sPort);
super.setMaxPin(32);
}
// mover comando con el parmetro de milisegundos
public void move(int ms) throws Exception {
// Esto detiene el subproceso actual para el movimiento del brazo hasta
/ / que termina de completar su accin
while (busy) {
Utils.pause(2);
}
// establecer el estado de los objetos de ocupado
setBusy(ms);
// anexar orden final
String cmd =cmds.append("T" +ms +CMD_TERM).toString();
// Enviar bytes al LM32
execute(cmd.getBytes(), 0);
// limpia el comando String
cmds =new StringBuffer();
/ / se restablece la cadena de buffer para nuevo conjunto de
/ / Comandos
}
/ / Sobrescribir el actual comando SSC
public void sscCmd(int ch, int pos) throws Exception {
cmd(ch, pos, DEFAULT_SPEED);
}
/**
* @param ch - channel 0-31
* @param pos - position 0-255
* @param spd - speed in milliseconds
*/
public void cmd(int ch, int pos, int spd) throws Exception {
/ / Asegurar que la posicin es vlida
if (pos <0 || pos >255) {
throw new Exception("position out of bounds");
}
/ / Llamada createCmd luego aadir al bfer de cadena
cmds.append(createCmd(ch, pos, spd));
}
/ / Permite una cadena de comandos en bruto para ser enviados
public void setRawCommand(String rawCmd) {
cmds.append(rawCmd);
}
/ / Este es el protocolo para la cadena de comandos para el LM32
public static String createCmd(int ch, int pos, int spd) {
String out ="#" +ch +"P" +getPw(pos) +"S" +spd;
return out;
}
/ / Establece el LM32 ocupado durante milisegundos especficos
private void setBusy(long ms) {
// the set busy function
busy =true;
/ / Obtiene momento en que se debe hacer
Date timeToRun =new Date(System.currentTimeMillis() +ms);
Timer timer =new Timer();
/ / Horarios que se ejecute tan ocupada puede establecer en false
timer.schedule(new TimerTask() {
public void run() {
busy =false;
}
}, timeToRun);
}
// acceso
public boolean isBusy() {
return busy;
}
// mtodo de utilidad esttica
public static int getPw(int pos) {
int pulsewidth;
double percent =(double) pos / 255;
double pwfactor =percent * 1500;
// establece anchura de pulso como funcin del tamao de byte
pulsewidth =750 +(int) pwfactor;
return pulsewidth;
}
// programa simple
public static void main(String[] args) {
try {
// obtener una sola instancia puerto serial
J SerialPort sPort =(J SerialPort) SingleSerialPort.getInstance(1);
// creado la nueva LM32
LM32 lm32 =new LM32(sPort);
// establece la posicn del servo en pin 0
lm32.sscCmd(0, 100);
// establece la posicn del servo en pin 1
lm32.sscCmd(1, 200);
// dice a los servos para mover all en 1 segundo.
lm32.move(1000);
// cierra el puerto serie
sPort.close();
} catch (Exception e) {
// print stack trace and exit
e.printStackTrace();
System.exit(1);
}
}
}



Mover grupo con el MiniSSC-II

Esto ser ms difcil en el MiniSSC-II ya que hay que controlar dos series de tiempo. El primer
momento ser el paso de la posicindel servo A a la posicin del servo B. El segundo momento es
el tamao de paso limitada por 9600. Esto significa que el tamao de paso del servo para cada uno
de los servos es dependiente del nmero de servos que se han conectado. Debido a que cada
comando est a unos 3 milisegundos si tiene dos servos tomar cerca de 6 milisegundos, 9
milisegundos para tres servos, etc. Para que esto funcione, tendremos que crear una manera de
procesar estos comandos por separado para cada paso, para cada servo, y para cada intervalo de
tiempo.
Objetivos del Cdigo
Nuestro objetivo es duplicar en un MiniSSC-II lo que ya est hecho por nosotros en el LM32.
Discusin del Cdigo
Para facilitar las cosas, voy a crear una estructura de datos llamada ServoPosition, que voy a
guardar en una lista de comandos. A pesar de que podra haber usado una segunda matriz, esto
pareca ms legible. (Vase el Ejemplo 3-13.)
Ejemplo 3-13 ServoPosition.java
package com.scottpreston.javarobot.chapter3;
public class ServoPosition {
public int pin;
public int pos;
public ServoPosition (int pin, int pos) throws Exception{
if (pos >255 || pos <0) {
throw new Exception("Position out of range, 0-255 only.");
}
this.pin =pin;
this.pos =pos;
}
}
En MiniSscGM, tengo dos ArrayLists como campos. Los primeros comandos ArrayList almacena
todos los comandos como una lista de ServoPositions. El segundo almacena todos los servos segn
la definicin de sus posiciones actuales. El constructor toma el J SerialPort y createServos
llamadas(). Este mtodo slo crea un ServoPosition nuevo y lo agrega a la clase ArrayList.
El mtodo sscCmd(), requiere de la interfaz GroupMoveProtocol acaba de llamar el mtodo Move
del mismo nombre y los parmetros.
E mtodo cmd()agrega la posicin de los servos al ArrayList hasta que el mtodo move() se llama
desde mov () es donde est toda la accin tiene lugar. En move(), lo primero que tenemos que hacer
es conseguir la mxima diferencia entre las posiciones de los servos en el comando. Este nmero
determinar el tamao de paso para cada duracin. As que si el movimiento total es de 1000
milisegundos y el tamao de paso es de 100 posiciones, me di cuenta de que el servo se mueve una
posicin cada 10 milisegundos si el protocolo y servo eran lo suficientemente rpido.
Lo siguiente en move(), es necesario determinar el nmero total de pasos basados en el tamao de
paso mnimo. Dado que el tamao mnimo es de 3, tendramos un total de 33 pasos en el orden,
teniendo cada uno de ellos (1000/33) =30. La ltima parte del move() es incrementar la posicin,
moviendo el servo, y despus haciendo una pausa el programa antes de que lo hace la siguiente
etapa. (Vase el Ejemplo 3-14.)
Ejemplo 3-14 MiniSscGM.java
package com.scottpreston.javarobot.chapter3;
import java.util.ArrayList;
import com.scottpreston.javarobot.chapter2.J SerialPort;
import com.scottpreston.javarobot.chapter2.SingleSerialPort;
import com.scottpreston.javarobot.chapter2.Utils;
public class MiniSscGM extends Ssc implements SSCProtocol, GroupMoveProtocol {
// comandos de almacenamiento en la lista
private ArrayList commands =new ArrayList();
// store servos in list
private ArrayList servos =new ArrayList();
// constructor takes J SerialPort as parameter
public MiniSscGM(J SerialPort jSerialPort) throws Exception {
super(jSerialPort);
setMaxPin(7);
// create servos
createServos();
}
// add servos to list
private void createServos() throws Exception{
for (int i =0; i <getMaxPin() +1; i++) {
ServoPosition svo =new ServoPosition(i, SSCProtocol.NEUTRAL);
// index will be same as id.
servos.add(svo);
}
}
public void sscCmd(int ch, int pos) throws Exception {
// calls overridden move method later in this class
move(ch, pos);
}
public void cmd(int ch, int pos, int spd) throws Exception {
// not going to implement the spd variable for the MiniSSC-II
ServoPosition svoPos =new ServoPosition(ch, pos);
commands.add(svoPos);
}
public void move(int time) throws Exception {
// all servo moves will have a minimum step-size of 3
/*
* gets maximum difference between current positions and new position
*/
int maxDiff =0;
for (int i =0; i <commands.size(); i++) {
ServoPosition newPos =(ServoPosition) commands.get(i);
ServoPosition curPos =(ServoPosition) servos.get(newPos.pin);
int tmpDiff =Math.abs(newPos.pos - curPos.pos);
if (tmpDiff >maxDiff) {
maxDiff =tmpDiff;
}
}
// total steps since 3 is min size.
double totalSteps =((double) maxDiff / 3.0);
/ / Calcular el tiempo de pausa
/ / Tiempo total de movimiento divded por el total de pasos
int pauseTime =(int) ((double) time / totalSteps);
// bucle hasta que la diferencia total entre todos los servos// posicin actual y la posicin meta es
cero
while (getTotalDiff() >0) {
for (int i =0; i <commands.size(); i++) {
ServoPosition newPos =(ServoPosition) commands.get(i);
ServoPosition curPos =(ServoPosition) servos.get(newPos.pin);
int tmpDiff =Math.abs(newPos.pos - curPos.pos);
if (newPos.pos >curPos.pos) {
if (tmpDiff >2) {
curPos.pos =curPos.pos +3;
} else {
curPos.pos =newPos.pos;
}
} else if (newPos.pos <curPos.pos) {
if (tmpDiff >2) {
curPos.pos =curPos.pos - 3;
} else {
curPos.pos =newPos.pos;
}
}
// mover la posicin del servo de corriente ms o menos 3
move(curPos.pin, curPos.pos);
Utils.pause(pauseTime);
}
}
// comandos que restablece lista.
commands =new ArrayList();
}
// ayudante mtodo para obtener la diferencia
private int getTotalDiff() {
int totalDiff =0;
for (int i =0; i <commands.size(); i++) {
ServoPosition newPos =(ServoPosition) commands.get(i);
ServoPosition curPos =(ServoPosition) servos.get(newPos.pin);
int tmpDiff =Math.abs(newPos.pos - curPos.pos);
totalDiff =totalDiff +tmpDiff;
}
return totalDiff;
}
private ServoPosition getServo(int id) {
return (ServoPosition) servos.get(id);
}
// misma muestra como programa LM32
public static void main(String[] args) {
try {
// obtener una sola instancia puerto serial
J SerialPort sPort =(J SerialPort) SingleSerialPort.getInstance(1);
// crear nuevos LM32
MiniSscGM miniSscGM =new MiniSscGM(sPort);
// establece la posicin de servo en el pin 0
miniSscGM.sscCmd(0, 100);
// establece la posicin de servo en el pin 1
miniSscGM.sscCmd(1, 200);
// dice a los servos para mover all en 1 segundo.
miniSscGM.move(1000);
// close serial port
sPort.close();
} catch (Exception e) {
// Imprime hasta encontrar en la pila la salida
e.printStackTrace();
System.exit(1);
}
}
}

Resumen De La Seccin
Se puede ver en la GroupMoveProtocol que el LM32 tiene un montn de ventajas con respecto a la
SSCProtocol cuando se desea un movimiento ms suave o tener un montn de servos que quiere
mandar a la vez. En esta seccin, he creado las siguientes cuatro clases:
GroupMoveProtocol.java: Al igual que el Protocolo de cooperacin Sur-Sur sino que se
utiliza para los movimientos agrupados del LM32.
LM32.java: La clase de implementacin del Lynxmotion SSC-32.
ServoPosition.java: Una posicin servo estructura de datos para ayudar a aplicar el Grupo
MoveProtocol en el MiniSSC.
MiniSscGM: La implementado GroupMoveProtocol para la MiniSSC. En la siguiente
seccin, hablaremos de cmo utilizar el LM32 y el GroupMoveProtocol con un brazo
robtico.


3.5 El Brazo Robot
Mover el robot en el suelo es slo un tipo de movimiento. El segundo tipo es el movimiento desde
una posicin fija. Para demostrar esto, yo voy a usar un brazo robtico. Si usted no tiene un brazo
de robot, puede adquirir los componentes de Lynxmotion, Inc. al www.lynxmotion.com (ver
Ilustracin 3-11) o hacerlo por s mismo.

Ilustracin 3-11 Brazo Robtico
He incluido un diagrama de clases de estas clases en la Ilustracin 3-12.

Ilustracin 3-12 Diagrama UML de LA Seccin 3.5


Objetivos del Cdigo
El objetivo en este ejemplo es crear un modelo simple de un brazo de robot.
Discusin del Cdigo
Los campos de esta clase son en su mayora constantes estticas que definirn el rango de
movimiento de sus dos ejes: el hombro y el codo. De los campos restantes, ssc de tipo MiniSSC es
el trabajador, y shoulderPos y elbowPos estn en la clase para mantener el estado. El constructor de
la clase toma el J SerialPort, y el mtodo move() es slo un paso a travs de la MiniSS. Los dos
mtodos, shoulder() y elbow(), toma como parmetros de entrada posiciones desde 0 a 255 para los
miembros respectivos, y el rest() se mueve tanto en el hombro y el codo en sus respectivas
posiciones de reposo.
Nota: Si utiliza esta clase, es posible que el movimiento sea ms rpido y brusco. Para
reducir la velocidad y que sea suave, mirar hacia adelante a la discusin de la clase
ComplexArm.
Por ltimo, en main() Acabo en mover el brazo a su posicin de reposo, y luego a otra posicin, a
continuacin, cierre el puerto serie. (Vase el ejemplo 3-15.)
Ejemplo 3-15 BasicArm.java
package com.scottpreston.javarobot.chapter3;
import com.scottpreston.javarobot.chapter2.J SerialPort;
import com.scottpreston.javarobot.chapter2.SingleSerialPort;
public class BasicArm {
private MiniSsc ssc;
// establecer los parmetros de hombro y codo
public static final int SHOULDER_PIN =0;
public static final int SHOULDER_MAX =SSCProtocol.MAX;
public static final int SHOULDER_MIN =SSCProtocol.MIN;
public static final int SHOULDER_REST =55;
public static final int ELBOW_PIN =1;
public static final int ELBOW_MAX =SSCProtocol.MAX;
public static final int ELBOW_MIN =SSCProtocol.MIN;
public static final int ELBOW_REST =65;
// variables de instancia de la posicin actual
private int shoulderPos =SSCProtocol.NEUTRAL;
private int elbowPos =SSCProtocol.NEUTRAL;
//habla con el constructor J SerialPort como parmetro
public BasicArm(J SerialPort sPort) throws Exception {
ssc =new MiniSsc(sPort);
}
// passthrough to ssc
private void move(int pin, int pos) throws Exception {
ssc.move(pin, pos);
}
// mueve el hombro
public void shoulder(int pos) throws Exception {
if (pos <SHOULDER_MIN || pos >SHOULDER_MAX) {
throw new Exception("Out of shoulder range.");
}
shoulderPos =pos;
move(SHOULDER_PIN, pos);
}
// mueve el codo
public void elbow(int pos) throws Exception {
if (pos <ELBOW_MIN || pos >ELBOW_MAX) {
throw new Exception("Out of elbow range.");
}
elbowPos =pos;
move(ELBOW_PIN, pos);
}
public void rest() throws Exception {
shoulder(SHOULDER_REST);
elbow(ELBOW_REST);
}
public static void main(String[] args) {
try {
// obtiene una instancia bsiica del puerto
J SerialPort sPort =(J SerialPort) SingleSerialPort.getInstance(1);
// create new BasicArm
BasicArm arm =new BasicArm(sPort);
// mueve a posicin res
arm.rest();
// mueve el codo 150
arm.elbow(150);
// mueve el hombro a 200
arm.shoulder(200);
// cierra el puerto serie
sPort.close();
} catch (Exception e) {
// imprime hasta que encuntre en la pila la salida
e.printStackTrace();
System.exit(1);
}
}
}

La prxima clase ser formalizar posiciones un poco ms que un simple byte 150 para el codo y el
byte 200 para el hombro.
Objetivos del Cdigo
El objetivo aqu es hacer que las posiciones sean ms fciles de invocar, y tambin para simplificar
el uso del brazo.


Discusin del Cdigo
El nico campo que se va a utilizar en esta clase ser el brazo de tipo BasicArm. El constructor
toma el J SerialPort y mueve el brazo a su posicin de reposo. De los dos mtodos de posicin, Toa )
y Tob() encapsula las posiciones de A y B en un mtodo para que usted no tenga que recordar
dentro de una clase de invocacin. Hago una pausa entre los mtodos para que el movimiento puede
parar desde que el movimiento sigue siendo desigual. (Vase el ejemplo 3-16.)
Ejemplo 3-16 ArmTesy1.java
package com.scottpreston.javarobot.chapter3;
import com.scottpreston.javarobot.chapter2.J SerialPort;
import com.scottpreston.javarobot.chapter2.SingleSerialPort;
import com.scottpreston.javarobot.chapter2.Utils;
public class ArmTest1 {
private BasicArm arm;
public ArmTest1(J SerialPort sPort) throws Exception {
arm =new BasicArm(sPort);
arm.rest();
}
// a posicin A
public void toA() throws Exception {
arm.shoulder(50);
Utils.pause(1000);
arm.elbow(200);
}
// a posicin B
public void toB() throws Exception {
arm.shoulder(150);
Utils.pause(1000);
arm.elbow(50);
}
// programa simple
public static void main(String[] args) {
try {
J SerialPort sPort =(J SerialPort) SingleSerialPort.getInstance(1);
ArmTest1 arm1 =new ArmTest1(sPort);
arm1.toA();
arm1.toB();
arm1.toA();
sPort.close();
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
}


El brazo en el ejemplo siguiente tendr un servo ms que el brazo Lynxmotion de 5 Ejes
anteriormente. Este brazo tendr un total de seis servos para controlar, y porque esta vez quiero
eliminar el movimiento espasmdico, voy a utilizar el controlador LM32 y la clase. El brazo tiene
los siguientes grados de libertad que se muestra en la Tabla 3-1.
Tabla 3-1 Servos del Brazo y su Descripcin
NOMBRE DEL SERVO FUNCIN
Servo de Rotacin del Hombro Esto hace girar el brazo izquierdo y derecho
alrededor de su base. (Hombro izquierdo-
derecho)
Servo de Altura de Hombro Esto mueve el brazo superior hacia arriba y
hacia abajo junto a su base. (Hombro arriba-
abajo)
Codo Servo Este movimiento del codo hacia arriba y hacia
abajo con respecto tanto a su apndice apndice
base para la mueca. (Bceps - Trceps)
Servo de Mueca Esto mueve la mueca hacia arriba y hacia
abajo con respecto a su codo.
(Antebrazo)
Servo de Pinza de Rotacin Esto hace girar la pinza izquierda y derecha de
la misma manera que la mueca gira a la
izquierda y la derecha. (Mueca)
Servo de Pinza Esta se abre y se cierra la pinza. (Dedos)

Objetivos del Cdigo
Los objetivos aqu son los siguientes:
Para modelar el brazo humano lo mejor que sea posible para que sea fluido y no requiere
una gran cantidad de codificacin.
Para escribir una clase de aplicacin similar a lo que hicimos con el grupo bsico.
Discusin del Cdigo
Antes de crear la clase ComplexArm, tengo que tener ms informacin disponible no slo la
posicin de un brazo y su nmero de pin. Para almacenar esta informacin, extend la clase
ServoPosition y agreg tres campos adicionales: min, max, y neutral. Esta informacin adicional le
ser til al mover seis servos ya que nos estamos moviendo lentamente de una posicin a otra a
travs de una cierta cantidad de tiempo. Tambin tengo que utilizar estas estructuras de datos
debido a que el LM32 utiliza una serie de posiciones de los servos por comando en lugar de
enviarlos por separado. (Vase el ejemplo 3-17.)



Ejemplo 3-17 ServoPosition2.java
package com.scottpreston.javarobot.chapter3;
public class ServoPosition2 extends ServoPosition {
// mnima posicin del brazo
public int min;
// mxima posicin del brazo
public int max;
// posicin neutral del brazo
public int neutral;
public ServoPosition2(int pin) throws Exception {
super(pin,SSCProtocol.NEUTRAL);
min =SSCProtocol.MIN;
max =SSCProtocol.MAX;
neutral =SSCProtocol.NEUTRAL;
}
public ServoPosition2(int pin, int pos, int min, int max) throws Exception{
super(pin,pos);
if (min >255 || min <0) {
throw new Exception("Minimum out of range, 0-255 only.");
}
if (max >255 || max <0) {
throw new Exception("Maximum out of range, 0-255 only.");
}
this.min =min;
this.max =max;
this.neutral =pos;
}
}

La clase ComplexArm en este ejemplo utiliza campos de tipo ServoPosition2. Nombr estos
campos de acuerdo con la extremidad que representan (shoulder1, shoulder2, elbow, y as
sucesivamente). En los servos ArrayList que almacena estas posiciones de los servos para su uso
posterior. En lm32, tengo una instancia de la clase trabajadora LM32. El constructor toma el
J SerialPort y llama al mtodo init(). Init() crea nuevas instancias de las posiciones de los servos y
los agrega a la ArrayList de los servos (es un mtodo separado para un constructor simple). El rest()
en ComplexArm es similar a BasicArm, excepto que en lugar de llamar a cada servo
separadamente, me itera a travs de la lista de los servos, crear el comando, y luego llamar a move()
durante un tiempo de 1 segundo. Los mtodos de PosA() y posB() tienen posiciones especficas
para cada servo, pero en vez de sacudir a una posicin y haciendo una pausa, los movimientos son
lentos durante un tiempo total de 1 segundo El mtodo move() comprueba el intervalo de iteracin a
travs de la lista y comprueba los lmites de los pines. Luego llama a los comandos de movimiento
LM32().
El resultado es el mismo que BasicArm, pero ms suave, y con ms ejes. (Vase el Ejemplo 3-18.)


Ejemplo 3-18 ComplexArm.java
package com.scottpreston.javarobot.chapter3;
import java.util.ArrayList;
import com.scottpreston.javarobot.chapter2.J SerialPort;
import com.scottpreston.javarobot.chapter2.SingleSerialPort;
public class ComplexArm{
// servo positions for differnt servos
// hombro 1
private ServoPosition2 s1;
// hombro 2
private ServoPosition2 s2;
// codo
private ServoPosition2 e;
// mueca
private ServoPosition2 w;
// grip 1
private ServoPosition2 g1;
// grip 2
private ServoPosition2 g2;
// trabajador LM32
private LM32 lm32;
/ / Lista de servos
private ArrayList servos;
public ComplexArm(J SerialPort serialPort) throws Exception {
lm32 =new LM32(serialPort);
/ / Poner en el mtodo particular para la limpieza
init();
}
private void init() throws Exception {
/ / Note el pasador de posicin no se utiliza para el LM32 porque recuerda
/ / La posicin
s1 =new ServoPosition2(0);
s2 =new ServoPosition2(1);
e =new ServoPosition2(2);
w =new ServoPosition2(3);
g1 =new ServoPosition2(4);
g2 =new ServoPosition2(5);
// aadir a la coleccin para facilitar las comprobaciones
servos.add(s1);
servos.add(s2);
servos.add(e);
servos.add(w);
servos.add(g1);
servos.add(g2);
}
public void rest() throws Exception {
for (int i =0; i <servos.size(); i++) {
ServoPosition2 tmpPos =(ServoPosition2) servos.get(i);
lm32.sscCmd(tmpPos.pin, tmpPos.neutral);
}
lm32.move(1000);
}
// mueve a posicin A (determinado experimentalmente)
public void posA() throws Exception {
lm32.sscCmd(s1.pin, 50);
lm32.sscCmd(s2.pin, 135);
lm32.sscCmd(e.pin, 75);
lm32.sscCmd(w.pin, 200);
lm32.sscCmd(g1.pin, 150);
lm32.sscCmd(g2.pin, 255);
lm32.move(1000); // move in 1 second
}
// mueve a position B (determinado experimentalmente)
public void posB() throws Exception {
lm32.sscCmd(s1.pin, 220);
lm32.sscCmd(s2.pin, 135);
lm32.sscCmd(e.pin, 100);
lm32.sscCmd(w.pin, 190);
lm32.sscCmd(g1.pin, 130);
lm32.sscCmd(g2.pin, 255);
lm32.move(1000); // move in 1 second
}
private void move(int pin, int pos) throws Exception {
// comprueba el primer rango
checkRange(pin, pos);
// a continuacin
lm32.move(pin, pos);
}
// comprobar los servos para ver si la posicin solicitada esta
// dentro de los parmetros del servo
private void checkRange(int pin, int pos) throws Exception {
for (int i =0; i <servos.size(); i++) {
ServoPosition2 tmpPos =(ServoPosition2) servos.get(i);
if (tmpPos.pin ==pin) {
if (pos >tmpPos.max || pos <tmpPos.min) {
throw new Exception("Positions out of bounds for pin "
+pin +".");
}
}
}
}
public static void main(String[] args) {
try {
// obtener una sola instancia del puerto serial
J SerialPort sPort =(J SerialPort) SingleSerialPort.getInstance(1);
// crea un nuevo ComplexArm
ComplexArm arm =new ComplexArm(sPort);
arm.rest();
arm.posA();
arm.posB();
sPort.close();
} catch (Exception e) {
// Imprime hasta encontrar en la pila la salida
e.printStackTrace();
System.exit(1);
}
}
}

Resumen De La Seccin
El movimiento con un brazo complejo es casi todo lo que necesitar siempre con control servo.
Tenemos un control preciso sobre la posicin y la velocidad de movimiento, as como los
movimientos coordinados y precisos.
En esta seccin, he creado las siguientes clases:
BasicArm.java: Esta clase modela el brazo robot bsico, con un hombro y un codo.
ArmTest1.java: Esta clase explica cmo mover el brazo bsico en dos posiciones diferentes.
ServoPosition2.java: Esta clase extiende la clase ServoPosition creado anteriormente para el
mnimo, mximo y valores neutros que se utilizarn en la ComplexArm.
ComplexArm.java: Esta clase se utiliza la clase ServoPosition2 y cuenta con un total de cinco ejes
de movimiento frente a los dos en el class.Since BasicArm. Puesto que hemos creado una
extremidad en esta seccin, dos, cuatro, o seis servos no debera ser mucho ms difcil. En la
siguiente seccin, te voy a mostrar cmo crear las piernas de la misma manera que hemos creado
brazos y luego me ir a mover todos juntos sin problemas usando el LM32.
3.6 Robots con Patas
Mover un robot con patas es muy similar a la modelizacin del ComplexArm en la seccin 3.5.
Tiene mltiples servos y mltiples posiciones que las piernas necesita. La nica cosa que no se
incluye es un modo de andar. El modo de andar en robots con patas es el orden y la direccin de los
movimientos de las piernas. Por ejemplo, un ser humano tiene el paso siguiente:
1. Levante la pierna izquierda hacia arriba.
2. Mueva la pierna izquierda hacia adelante.
3. Ponga la pierna izquierda hacia abajo.
4. Cambie su peso a la pierna izquierda.
5. Levante la pierna derecha hacia arriba.
6. Mueva la pierna derecha hacia adelante.
7. Ponga la pierna derecha hacia abajo.
8. Cambie su peso a la pierna derecha.
9. Repetir.
Esos son nueve comandos de dos piernas en una sola direccin, que es ms complicado de lo que
las clases de la unidad diferencial creada en la seccin 3.1. Pero debido a que el hexpodo
implementa la interfaz J Motion si nuestro robot tiene patas o ruedas, la navegacin ser la misma.
Un diagrama de clases para esto se muestra en la Ilustracin 3-13. Para tener una mejor idea de lo
que vamos a tener en movimiento, observe la foto en la Figura 3-14. Cuenta con un total de 12
servos, con cuatro grados de libertad por pata para un total de 48 movimientos posibles.

Ilustracin 3--13 UML e la Seccin 3.6

Ilustracin 3-14 Hexapodo Lynxmotion
Objetivos Del Cdigo
El objetivo es implementar J Motion para un robot con patas.
Discusin del Cdigo
Creo que usted encontrar que un robot hexpodo es nada ms que algunos brazos complejos que
tienen que trabajar juntos. La clase que sigue los dos grupos de servos de la pierna hexpodo y
aade algunos mtodos de movimiento para la pierna. Los dos campos son de tipo ServoPosition2:
uno para el movimiento horizontal y uno para el vertical. El constructor no hace falta ser un
J SerialPort porque a diferencia de la ComplexArm, el partido de ida ser slo una estructura de
datos compleja. Funcionar para establecer y obtener los comandos que se utilizan con el LM32.
Los Mtodos de up(), down(), forward() y backwards() establecen los mandatos para las posiciones
predeterminadas definidas por las posiciones de los servos o los valores predeterminados. El
mtodo neural hace lo mismo para los dos servos. (Vase el Ejemplo 3-19.)





Ejemplo 3-19 BasicLeg.java
package com.scottpreston.javarobot.chapter3;
public class BasicLeg {
// cada pata tiene 2 servos
private ServoPosition2 vertServo;
private ServoPosition2 horzServo;
// constructor genrico simplemente toma los pines
public BasicLeg(int vPin, int hPin)throws Exception {
vertServo =new ServoPosition2(vPin);
horzServo =new ServoPosition2(hPin);
}
// constructores con ServoPosition2's
public BasicLeg(ServoPosition2 vertServo, ServoPosition2 horzServo) {
this.vertServo =vertServo;
this.horzServo =horzServo;
}
// mueve la pierna hacia arriba
public String up() {
return LM32.createCmd(vertServo.pin,vertServo.max,LM32.DEFAULT_SPEED);
}
// mueve la pierna hacia abajo
public String down() {
return LM32.createCmd(vertServo.pin,vertServo.min,LM32.DEFAULT_SPEED);
}
// mueve la pierna hacia adelante
public String forward() {
return LM32.createCmd(horzServo.pin,horzServo.max,LM32.DEFAULT_SPEED);
}
// mueve hacia atrs la pierna
public String backward() {
return LM32.createCmd(horzServo.pin,horzServo.min,LM32.DEFAULT_SPEED);
}
// resetea servo horizontal
public String neutralHorz() {
return LM32.createCmd(horzServo.pin,horzServo.neutral,LM32.DEFAULT_SPEED);
}
// resetea servo vertical
public String neutralVert(){
return LM32.createCmd(vertServo.pin,vertServo.neutral,LM32.DEFAULT_SPEED);
}
// restablece los servos
public String neutral() {
return neutralVert() +neutralHorz();
}
}


La clase hexpodo tiene como campos el LM32 como la clase trabajadora y seis patas definidas
como BasicLegs. Yo tambin defini dos grupos de la pierna como ArrayList. Debido a la marcha
que eleg, me ir a mover tres patas al mismo tiempo. Al poner en una lista, puedo mover todos los
tramos de este grupo con un solo comando.
Los campos UP, DOWN, y as sucesivamente. La velocidad es la variable int velocidad y
MAX_SPEED representa lo el tiempo mnimo que debe ser para el movimiento de grupo de tres
patas. El constructor toma, lo has adivinado, el J SerialPort y llama a dos mtodos init() y
setLegGroups(). El mtodo init crea todas las posiciones de las piernas de los seis BasicLegs. El
mtodo setLegGroups los aade a estos mtodos legGroup1 y legGroup2.
El paso forward() consiste en una combinacin de ocho comandos separados. Los comandos de
marcha se crean mediante el mtodo getTotalMove() que comprende un StringBuffer. El mtodo
funciona mediante la iteracin a travs de todas las piernas y (en funcin del comando) devuelve la
cadena del mtodo BasicLeg.motion(). Esto se repite hasta que todas las patas lo hacen. A
continuacin, el grupo que se ejecute en el tiempo especificado por el mtodo getSpeedInMs().
El mtodo getSpeedInMs () utiliza una relacin inversa entre el tiempo de la pierna en movimiento
y la velocidad. Esto es as que el 10 sigue siendo rpido y 1 sigue siendo lento. Por ejemplo: la
velocidad del robot a la velocidad de 10 es 2500 a 2500 +250 milisegundos por movimiento de un
grupo de la pierna, y a una velocidad de 1 la velocidad del robot es de 2500 a 250 +250 =2500
milisegundos por la pierna.
En el mtodo forward() con un parmetro de milisegundos, recorre llamando hacia adelante hasta
que se acabe el tiempo. Todo esto es una funcin de la velocidad del robot y que incluso produce
una excepcin si el tiempo de desplazamiento solicitado es menor que el tiempo mnimo. (Vase el
ejemplo 3-20.)
Ejemplo 3-20 Hexapod.java
package com.scottpreston.javarobot.chapter3;
import java.util.ArrayList;
import com.scottpreston.javarobot.chapter2.J SerialPort;
import com.scottpreston.javarobot.chapter2.SingleSerialPort;
import com.scottpreston.javarobot.chapter2.Utils;
public class Hexapod implements J Motion {
private LM32 lm32;
private BasicLeg leg1; // left front
private BasicLeg leg2; // left middle
private BasicLeg leg3; // left back
private BasicLeg leg4; // right front
private BasicLeg leg5; // right middle
private BasicLeg leg6; // right back
private ArrayList legGroup1 =new ArrayList();
private ArrayList legGroup2 =new ArrayList();
private static final int UP =0;
private static final int DOWN =1;
private static final int FORWARD =2;
private static final int BACKWARD =3;
private static final int NEUTRAL =4;
private int speed =5;
private static final int MIN_SPEED =250;
public Hexapod(J SerialPort serialPort) throws Exception {
lm32 =new LM32(serialPort);
// 2 mtodos para limpiar el constructor
init(); // inicializa las piernas
setLegGroups(); // fijar las patas a los grupos
}
// crea las piernas
private void init() throws Exception {
// 1st posicin vertical del servo (up/down)
// 2nd posicin horizontal del servo (forward/backward)
leg1 =new BasicLeg(new ServoPosition2(0, 127, 50, 200),
new ServoPosition2(1, 127, 50, 200));
leg2 =new BasicLeg(new ServoPosition2(4, 127, 50, 200),
new ServoPosition2(5, 127, 100, 150));
leg3 =new BasicLeg(new ServoPosition2(8, 127, 50, 200),
new ServoPosition2(9, 127, 50, 200));
leg4 =new BasicLeg(new ServoPosition2(16, 127, 200, 50),
new ServoPosition2(17, 127, 200, 50));
leg5 =new BasicLeg(new ServoPosition2(20, 127, 200, 50),
new ServoPosition2(21, 127, 150, 100));
leg6 =new BasicLeg(new ServoPosition2(24, 127, 200, 50),
new ServoPosition2(25, 127, 200, 50));
}
// poner las piernas en grupos de caminantes
private void setLegGroups() throws Exception {
legGroup1.add(leg1);
legGroup1.add(leg3);
legGroup1.add(leg5);
legGroup2.add(leg2);
legGroup2.add(leg4);
legGroup2.add(leg6);
}
// esto crear una cadena completa de comandos para todos los tramos
public String getTotalMove(ArrayList legs, int cmd) throws Exception {
StringBuffer cmds =new StringBuffer();
for (int i =0; i <legs.size(); i++) {
BasicLeg tmpLeg =(BasicLeg) legs.get(i);
if (cmd ==UP) {
cmds.append(tmpLeg.up());
}
if (cmd ==DOWN) {
cmds.append(tmpLeg.down());
}
if (cmd ==FORWARD) {
cmds.append(tmpLeg.forward());
}
if (cmd ==BACKWARD) {
cmds.append(tmpLeg.backward());
}
if (cmd ==NEUTRAL) {
cmds.append(tmpLeg.neutral());
}
}
return cmds.toString();
}
// Simple movimiento hacia adelante
public void forward() throws Exception {
lm32.setRawCommand(getTotalMove(legGroup1, DOWN));
lm32.move(getSpeedInMs());
lm32.setRawCommand(getTotalMove(legGroup2, UP));
lm32.move(getSpeedInMs());
lm32.setRawCommand(getTotalMove(legGroup2, FORWARD));
lm32.move(getSpeedInMs());
lm32.setRawCommand(getTotalMove(legGroup1, BACKWARD));
lm32.move(getSpeedInMs());
lm32.setRawCommand(getTotalMove(legGroup2, DOWN));
lm32.move(getSpeedInMs());
lm32.setRawCommand(getTotalMove(legGroup1, UP));
lm32.move(getSpeedInMs());
lm32.setRawCommand(getTotalMove(legGroup1, FORWARD));
lm32.move(getSpeedInMs());
lm32.setRawCommand(getTotalMove(legGroup2, BACKWARD));
lm32.move(getSpeedInMs());
}
public static void main(String[] args) {
try {
J SerialPort sPort =(J SerialPort) SingleSerialPort.getInstance(1);
Hexapod hex =new Hexapod(sPort);
hex.forward();
hex.forward();
sPort.close();
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
public void forward(int ms) throws Exception {
if (getSpeedInMs() * 8 <ms) {
throw new Exception("Speed requested is less than minimum speed.");
}
int remaining =ms;
while (remaining >getSpeedInMs() * 8) {
forward();
remaining =remaining - getSpeedInMs() * 8;
}
Utils.pause(remaining);
}
public void stop() throws Exception {
lm32.setRawCommand(getTotalMove(legGroup1, DOWN));
lm32.setRawCommand(getTotalMove(legGroup2, DOWN));
lm32.move(getSpeedInMs());
}
public void reverse() throws Exception {
}
public void pivotRight() throws Exception {
}
public void pivotLeft() throws Exception {
}
public void reverse(int ms) throws Exception {
}
public void pivotRight(int ms) throws Exception {
}
public void pivotLeft(int ms) throws Exception {
}
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed =speed;
}
private int getSpeedInMs() {
return (MIN_SPEED* 10) - (MIN_SPEED * speed) +MIN_SPEED;
}
}

Resumen De La Seccin
Con las clases creadas en esta seccin, le animo a experimentar con sus andares propios o diferentes
nmeros de patas.
En esta seccin, he creado las siguientes clases:
BasicLeg.java: esta clase es similar a la ComplexArm creado en la seccin anterior.
Hexapod.java: Esta clase implementa la interfaz J Motion para mover el robot patas de la
misma manera que lo hara un robot con ruedas.
3.7 Resumen Del Captulo
Mi objetivo en este captulo es presentarle a la solucin de problemas de movimiento en robtica.
mostr cmo resolver tres tipos de movimiento (ruedas, servo fijo, gaited) con dos tipos diferentes
de servo-controladores: el de Scott Edwards MiniSSC-II y la Lynxmotion SSC-32. Ambos son muy
buenos.Yo uso el MiniSSC-II en mi robot principal Feynman5, y el LM32 en mi hexpodo.
En la seccin 3.1, he creado el protocolo SerialSSC y ha creado una super-clase en general, tanto
para los MiniSSC y LM32 clases de implementacin. Tambin creamos la clase MiniSSC que puso
a prueba nuestro control servo primero desde el PC.
En la seccin 3.2, he creado tres clases de unidades diferenciales para el movimiento de ruedas y
generado una interfaz comn que se llama movimiento J Motion.
En la seccin 3.3, he utilizado la clase MiniSSC para realizar operaciones de giro e inclinacin para
la configuracin de una cmara web.
En la seccin 3.4, para resolver algunos de los problemas de movimiento experimentado en el
apartado 3.3, que introdujo el servo controlador LM32, as como un nuevo protocolo para el
movimiento llamado GroupMoveProtocol. He implementado este protocolo con el LM32 y la
implementacin MiniSscGM
En la seccin 3.5, he utilizado la clase LM32 para crear un brazo robtico movimiento fluido con
seis servos.
Por ltimo, en la seccin 3.6, he implementado la interfaz J Motion en un robot de seis patas para
demostrar que podramos utilizar la clase J Motion con un robot de accionamiento diferencial o un
robot piernas alternativamente.
En el prximo captulo, vamos a dejar de moverse un poco y usar el BASIC Stamp para
comunicarse con algunos de los sensores que pueden utilizar en su robot. No, vamos a discutir las
brjulas digitales, sensores de la lgica, y el sonar y sensores infrarrojos a distancia.

You might also like