UNIVERSIDAD AUSTRAL DE CHILE SEDE PUERTO MONTT ESCUELA DE INGENIERIA EN COMPUTACION

UNIVERSIDAD AUSTRAL DE CHILE SEDE PUERTO MONTT ESCUELA DE INGENIERIA EN COMPUTACION Investigación y Desarrollo de métodos alternativos para el contro

13 downloads 68 Views 3MB Size

Recommend Stories


UNIVERSIDAD AUSTRAL DE CHILE FACULTAD DE CIENCIAS DE LA INGENIERIA ESCUELA DE INGENIERIA NAVAL
UNIVERSIDAD AUSTRAL DE CHILE FACULTAD DE CIENCIAS DE LA INGENIERIA ESCUELA DE INGENIERIA NAVAL PRINCIPALES CONSIDERACIONES EN LA SELECCIÓN E INSTALAC

UNIVERSIDAD AUSTRAL DE CHILE
UNIVERSIDAD AUSTRAL DE CHILE FACULTAD DE CIENCIAS AGRARIAS ESCUELA DE INGENIERIA EN ALIMENTOS Capacidad Antagonista Frente a Listeria monocytogenes d

Story Transcript

UNIVERSIDAD AUSTRAL DE CHILE SEDE PUERTO MONTT ESCUELA DE INGENIERIA EN COMPUTACION

Investigación y Desarrollo de métodos alternativos para el control de sillas de ruedas motorizadas.

Seminario de Titulación para optar al título de Ingeniero en Computación

PROFESOR PATROCINANTE: Sr. Mauricio Henríquez Schott

JOSE DANIEL CARRASCO MUÑOZ PUERTO MONTT – CHILE 2011

Con todo mi amor y cariño dedico mi tesis a mi familia…

INDICE 1. Introducción .................................................................................................. 1 2. Objetivos........................................................................................................ 4 2.1 Objetivo general ...................................................................................... 4 2.2 Objetivos específicos.............................................................................. 4 3. Planteamiento del Problema ........................................................................ 5 3.1 Antecedentes ........................................................................................... 5 3.1.1 Definición del problema ................................................................... 9 3.1.2 Esfuerzos anteriores ...................................................................... 13 3.1.3 Solución propuesta ........................................................................ 16 3.2 Justificación .......................................................................................... 22 3.2.1 Situación sin Proyecto ................................................................... 22 3.2.2 Situación con Proyecto .................................................................. 23 3.3 Delimitación ........................................................................................... 24 4. Metodología ................................................................................................. 26 5. Recursos...................................................................................................... 29 5.1 Hardware ................................................................................................ 29 5.2 Software ................................................................................................. 29 5.3 Otros ....................................................................................................... 30 6. Cuerpo ......................................................................................................... 31 6.1 Construcción de la librería para manejar la controladora ................. 31 6.2 Modificación de la silla de ruedas y construcción de un programa de control simple .............................................................................................. 55 6.2.1 Iniciación ......................................................................................... 55 6.2.2 Elaboración ..................................................................................... 56 6.2.3 Construcción ................................................................................... 58 6.2.4 Transición........................................................................................ 86 6.3 Creación de métodos de control avanzados ...................................... 87 6.3.1 Creación del método de control con mouse ................................ 87 6.3.1.1 Iniciación ................................................................................... 87 6.3.1.2 Elaboración ............................................................................... 88 6.3.1.4 Transición ............................................................................... 107 6.3.2 Creación del método de control con Wiimote ............................ 108 6.3.2.1 Iniciación ................................................................................. 108 6.3.2.2 Elaboración ............................................................................. 110 6.3.2.3 Construcción .......................................................................... 111 6.3.2.4 Transición ............................................................................... 125 6.3.3 Creación del método de control con reconocimiento de rostro. ................................................................................................................. 126 6.3.3.1 Iniciación ................................................................................. 126 6.3.3.2 Elaboración ............................................................................. 128

6.3.3.3 Construcción .......................................................................... 129 7. Conclusiones y/o Recomendaciones ...................................................... 139 8. Bibliografía ................................................................................................ 141

TABLAS Tabla 1: Comparación de empresas proveedoras y sus soluciones. ........ 14 Tabla 2: Complejidad del Dominio Operaciones. ......................................... 19 Tabla 3: Definición del equipo de trabajo. .................................................... 21 Tabla 4: Comandos aceptados por la controladora AX2550. ...................... 38 Tabla 5: Métodos de la clase AX2550. ........................................................... 40 Tabla 6: Atributos y propiedades de la clase AX2550. ................................ 42 Tabla 7: Atributos y propiedades de la clase ExpectedResponse. ............ 46 Tabla 8: Atributos y propiedades de la clase Response. ............................ 47 Tabla 9: Métodos de la clase WheelchairControl. ........................................ 68 Tabla 10: Atributos y propiedades de la clase WheelchairControl. ........... 69 Tabla 11: Atributos y propiedades de la clase InputDeviceLogic. ............. 74 Tabla 12: Métodos de la clase InputDeviceLogic. ........................................ 74 Tabla 13: Métodos de la clase KeyboardInputLogic. ................................... 77 Tabla 14: Atributos y propiedades de la clase KeyboardInputLogic. ........ 78 Tabla 15: Métodos de la clase MouseInputLogic. ........................................ 92 Tabla 16: Atributos y propiedades de la clase MouseInputLogic............... 93 Tabla 17: Atributos de la clase TankMovementLogic. ............................... 102 Tabla 18: Métodos de la clase TankMovementLogic. ................................ 103 Tabla 19: Atributos y propiedades de la clase Tank. ................................. 105 Tabla 20: Atributos y propiedades de la clase WiimoteInputLogic. ......... 115 Tabla 21: Métodos de la clase WiimoteInputLogic. ................................... 116 Tabla 22: Atributos y propiedades de la clase CameraInputLogic. .......... 133 Tabla 23: Métodos de la clase CameraInputLogic. .................................... 134

ILUSTRACIONES Ilustración 1: Distribución de discapacidades por tipo, 2006 [Casen]. ........ 5 Ilustración 2: Silla de ruedas de acción mecánica. ........................................ 6 Ilustración 3: Muletas ortopédicas genéricas. ............................................... 7 Ilustración 4: Andador ortopédico genérico................................................... 8 Ilustración 5: Silla de ruedas motorizada de configuración genérica modelo Jazzy 1115 [Pride]. ..................................................................... 10 Ilustración 6: Controlador de silla de rueda motorizada de succión y soplido [Wheelchair]................................................................................ 11 Ilustración 7: Controladora de silla de rueda motorizada para la pera [Wheelchair]. ............................................................................................ 12 Ilustración 8: Disciplinas, fases e iteraciones de AUP. ............................... 27 Ilustración 9: Diagrama de casos de uso de la controladora...................... 33 Ilustración 22: Diagrama de clases de la solución que contiene la librería AX2550. ..................................................................................................... 34 Ilustración 10: Controladora RoboteQ AX2550. ........................................... 35 Ilustración 11: Diagrama eléctrico usado en el proyecto. ........................... 36 Ilustración 12: Puerto serial USB. ................................................................. 37 Ilustración 13: Código del método Write de la clase AX2550. .................... 44 Ilustración 14: Código del método DataRecievedHandler de la clase AX2550. ..................................................................................................... 45 Ilustración 15: Código del método WriteCommand de la clase AX2550. ... 47 Ilustración 16: Código del método que maneja el evento de cambio de velocidad del motor 1 de la clase AX2550. ............................................ 49 Ilustración 17: Código de ejemplo mostrando el control simplificado de motores..................................................................................................... 50 Ilustración 18: Clase NumericAX2550Member. ............................................ 51 Ilustración 19: Ejemplo de código en donde se consulta por valores de los accesorios de la controladora. ............................................................... 52 Ilustración 20: Programa simple de pruebas................................................ 54 Ilustración 21: Diagrama de casos de uso para el programa de control simple. ...................................................................................................... 56 Ilustración 39: Diagrama de clase de la librería que implementa las lógicas de control. ................................................................................................ 57 Ilustración 23: Silla de ruedas a usar. ........................................................... 59 Ilustración 24: Conector usado en el sistema eléctrico. ............................. 61 Ilustración 25: Baterías montadas en soportes. .......................................... 61 Ilustración 26: Modelo de lámpara comprada en el mercado. .................... 62 Ilustración 27: Base de aluminio conectado a dos cuellos de ganso extraídos de lámparas. ............................................................................ 63 Ilustración 28: Silla de ruedas con soporte para base de aluminio soldada y pintada. .................................................................................................. 65

Ilustración 29: Formulario para control con teclado. .................................. 67 Ilustración 30: Diagrama de flujo de la ejecución de un movimiento de la silla. ........................................................................................................... 72 Ilustración 31: Clase InputDeviceLogic y sus clases hijas. ........................ 73 Ilustración 32: Código del método VectorMove2D de la clase InputDeviceLogic. .................................................................................... 76 Ilustración 33: Código de los métodos de la clase KeyboardInputLogic que manejan el evento tecla soltada y tecla presionada. ............................ 79 Ilustración 34: Código de la propiedad UseKeyboard de la clase KeyboardInputLogic. ............................................................................... 80 Ilustración 35: Código del hilo de control del teclado de la clase KeyboardInputLogic. ............................................................................... 81 Ilustración 36: Código del método OnControlLogicMovementIssued de la clase WheelchairControl. ........................................................................ 83 Ilustración 37: Sentido de giro de las ruedas y dirección de la silla. ......... 84 Ilustración 38: Diagrama de casos de uso para control con el mouse. ..... 88 Ilustración 40: Formulario de control del mouse con uso de GTK.Drawingarea. .................................................................................... 91 Ilustración 41: Código del método manejador del evento de cambio de estado (Toggled) del Checkbox “Usar Mouse” de la clase formulario. ................................................................................................................... 94 Ilustración 42: Código del método OnMouseMoved de la clase MouseInputLogic. .................................................................................... 95 Ilustración 43: Código del método MouseControlThread de la clase MouseInputLogic. .................................................................................... 97 Ilustración 44: Plano cartesiano e interpretación de movimiento. ............. 98 Ilustración 45: Plano cartesiano e acción de motores. ............................. 100 Ilustración 46: Código del método Vector2DtoTank de la clase TankMovementLogic. ............................................................................ 104 Ilustración 47: Formulario del método de control del mouse en acción.. 106 Ilustración 48: Control Nintendo Wiimote................................................... 108 Ilustración 49: Diagrama de casos de uso para fase de control con Wiimote. .................................................................................................. 110 Ilustración 50: Interfaz de usuario para control Wiimote. ......................... 113 Ilustración 51: Código de los métodos Connect y Disconnect de la clase WiimoteInputLogic. ............................................................................... 117 Ilustración 52: Código del método OnWiimoteButtonPress de la clase WiimoteInputLogic. ............................................................................... 118 Ilustración 53: Código del método ButtonAccelerationThread de la clase WiimoteInputLogic. ............................................................................... 120 Ilustración 54: Control Wiimote, sus acelerómetros y orientación. ......... 122 Ilustración 55: Código del método OnWiimoteAccelerometerChanged de la clase WiimoteInputLogic....................................................................... 123

Ilustración 56: Código del método WiimoteAccControlThread perteneciente a la clase WiimoteInputLogic. ...................................... 124 Ilustración 57: Programa de ejemplo que reconoce el rostro y los ojos de una persona. .......................................................................................... 126 Ilustración 58: Casos de uso de método de control con reconocimiento de rostro. ..................................................................................................... 128 Ilustración 59: Rostro y movimiento de la silla. ......................................... 130 Ilustración 60: Formulario del método de control con reconocimiento de rostro. ..................................................................................................... 132 Ilustración 61: Código del método CameraControlThread de la clase CameraInputLogic. ................................................................................ 136

SINTESIS

En el rubro de soluciones de movilidad para personas con discapacidad que limitan el uso de sus piernas, existe un gran abanico de productos en el mercado orientados a ellos.

En el conjunto de las sillas de ruedas eléctricas se puede apreciar una fuerte tendencia a producir estas en una configuración estándar (Joystick en un apoyabrazos) que es una solución genérica y no útil para todas las personas con discapacidad en las piernas debido a esta configuración. En el mercado existen empresas dedicadas a crear soluciones específicas para personas con estos tipos de discapacidad que no le es aplicable o cómodo usar un Joystick, pero el acceso a estas soluciones esta en gran medida limitado por su alto costo.

En vista de las limitaciones descritas y gracias a los avances en el rubro de la computación, se idea el presente proyecto con la finalidad de usar un computador con una controladora para crear un prototipo de solución genérica para movilidad, pero con una mayor cantidad de posibles métodos de control para el piloto.

El proyecto considera el desarrollo de una librería para utilizar una controladora de motores (AX2550) y cuatro métodos de control, los cuales son el control con teclado, mouse, Wiimote y reconocimiento facial.

En el desarrollo del proyecto se usó la metodología AUP, en base a la cual se orientó el proyecto a través de fases, divididas por etapas, las cuales dividieron el proyecto en objetivos lógicos. La metodología también fomenta la creación de diagramas de casos de uso, diagramas de flujo, etc. lo que ayuda al alumno a visualizar de mejor medida tanto los requerimientos y flujo del proyecto.

Una vez finalizadas las fases del desarrollo se obtuvo un prototipo de silla de ruedas completamente funcional, capaz de desplazarse con motores eléctricos controlados por los métodos descritos. En el desarrollo de este programa se creó una librería que abstrae los diferentes métodos de control, siendo posible su utilización a futuro en otros proyectos de manera simple. También es posible agregar a esta librería más lógicas y métodos de control para su uso en otros proyectos similares.

ABSTRACT

In the area of mobility solutions for people with disability that limits the use of their legs there exists a large amount of products in the market.

In the group of electric wheelchairs there exists a large tendency to produce them in a standard configuration (Joystick in armrest) which is a generic solution and it is not useful for all leg disabled people because of this configuration. In the market there exists companies dedicated to the creation of specific solutions for people with these type of disability where using a Josystick it is not practical, but the access to this type of solutions is limited due to its high cost.

Considering

the

limitations

described

and

thanks

in

the

advancements in the area of computing, the following project is conceived that is using a computer with an electric motor controller to create a generic solution prototype for mobility, but with a greater amount of possible control methods for the pilot.

The project considers the development of a library for using a motor controller (AX2550) and for control methods, which are control with keyboard, mouse Wiimote and facial recognition.

AUP software development methodology was used as a basis of orientation for this project which divided it in phases which are divided by stages, all these segmented the project in logic objectives. The methodology also encourages the creation of use case diagrams, flow diagrams, etc. which helps the student to visualize the requirements and the project flow in a better way.

Once completed all phases of the project, a completely functional wheelchair prototype was created, capable of moving with electric motors controlled by the described methods. In the development of this program a control method abstraction library was created, making this library usable in the future for other projects in a simple way. It is also possible to add to this library more logic and control methods for its use in other similar projects.

1. Introducción

Las piernas de los seres humanos son las que nos otorgan la movilidad física, esta es una de nuestras capacidades más importantes, que permite un alto nivel de independencia necesaria para el diario vivir de hoy en día.

Cuando las piernas o la comunicación entre el cerebro y los músculos de las piernas presentan problemas, la dependencia creada de las sillas de ruedas reduce enormemente la calidad de vida del afectado y sus cercanos, ya que la persona necesita desplazarse para alimentarse, hacer sus necesidades básicas, hacer tramites, desarrollarse académicamente y profesionalmente, una silla de ruedas manual propulsada mecánicamente permite hasta cierto punto a una persona desplazarse, pero estas mismas no siempre pueden ser propulsadas por la persona y en el caso de poder ser propulsada por esta son muy engorrosas de utilizar.

Por esto se han desarrollado en el mundo diversas soluciones como sillas de ruedas propulsadas por motores, andadores, etc. Todo lo cual ha ayudado en gran medida a reducir el problema de la movilidad. Pero estas soluciones no son aplicables con éxito a todo el grupo de personas con problemas para desplazarse, de este grupo, hay un subconjunto de personas con patologías que les impiden propulsar la silla mecánicamente debido a su

1

discapacidad y también usar los controles estándar de las sillas de ruedas motorizadas. La única posibilidad que tienen estas personas, es solicitar un producto personalizado especifico para su discapacidad a un valor muy alto.

Por todo lo anterior nace la idea de desarrollar una silla de ruedas prototipo que sirva de ayuda a las personas con discapacidades especificas, permitiéndoles adquirir movilidad y un cierto grado de independencia que les permita realizar sus actividades diarias de manera más normal.

Para el desarrollo y implementación del prototipo se utilizara una silla de ruedas, motores DC, baterías, una controladora de motores, un netbook y diversos dispositivos de entrada, entre ellos wiimote y el TouchPad, también se tendrá que desarrollar un programa en C# que interpretara las señales de los controles y se comunicará con la controladora para darle ordenes a los motores que sean significativas para el individuo que controle la silla.

En el presente documento se indicaran los antecedentes recopilados a lo largo del estudio del problema, concentrándose en soluciones de control para las sillas de ruedas motorizadas. Además se hace mención a otros intentos para solucionar problemas de movilidad para personas con discapacidades específicas incluyendo algunos datos del mercado actual y estadísticas a nivel País.

2

Profundizando más, se especifica la complejidad de desarrollar métodos de control y la interpretación de los dispositivos externos a un computador, se establece un plan de trabajo, la metodología a usar y se hacen estimaciones de duración del proyecto.

3

2. Objetivos 2.1 Objetivo general

Desarrollar un prototipo de silla de ruedas motorizada funcional, que permita mediante variados métodos de entrada controlarla y de esta forma, aportar a dar una solución real a los problemas de movilidad de personas con diferentes discapacidades físicas.

2.2 Objetivos específicos



Implementar el protocolo de la interfaz de la controladora RoboteQ AX2550 [RoboteQ] en lenguaje C# para poder controlar los motores eléctricos de una silla de ruedas prototipo de manera confiable, para así poder implementar un algoritmo de control sobre este.



Adaptar periféricos de control de la silla de ruedas y desarrollar un programa que permita controlarla mediante un computador (netbook), usando métodos tradicionales (Teclado, mouse).



Investigar y desarrollar métodos alternativos de control mediante interfaces hombre/máquina no estándar (Wiimote, análisis de imagen).

4

3. Planteamiento del Problema 3.1 Antecedentes

Según la última publicación del informe CASEN 2006 [Casen], la cantidad de personas con discapacidad en Chile alcanza a 1.119.867, lo que equivale a un 6,9% de la población total del país. De ellos 346.892 (31,0%) tienen discapacidad física y/o de movilidad (problemas post operatorios, accidentes, fracturas, embarazos de alto riesgo, genéticos, etc.).

Ilustración 1: Distribución de discapacidades por tipo, 2006 [Casen].

5

Esto significa que estas personas necesitan de algún tipo de ayuda para realizar sus actividades diarias, y en el caso de las personas con problemas para desplazarse, necesitarán en muchos casos una silla de ruedas la cual puede ser accionada mecánicamente con la fuerza de sus brazos o la ayuda de otra persona que la empuja.

Ilustración 2: Silla de ruedas de acción mecánica.

6

También existen otras soluciones para discapacidades leves como las muletas ortopédicas o los andadores.

Ilustración 3: Muletas ortopédicas genéricas.

7

Ilustración 4: Andador ortopédico genérico.

Accionar la silla mecánicamente, usar muletas ortopédicas, andadores o tener un ayudante permanentemente no es posible para todas las personas, por lo tanto la movilidad queda gravemente reducida y la dependencia de terceros marcada.

8

3.1.1 Definición del problema

Gracias

a

la

demanda

por

dispositivos

que

permitan

mayor

independencia de parte del usuario, diversas empresas se dedican a ofrecer diferentes soluciones, las cuales en su mayoría consisten en sillas de ruedas accionadas por motores eléctricos. Estas son controladas por un joystick fijo en uno de sus apoya brazos, estos en algunos casos permite la regulación de altura y posición.

9

Ilustración 5: Silla de ruedas motorizada de configuración genérica modelo Jazzy 1115 [Pride].

Esta configuración se considera genérica y no sirve para todos los discapacitados, hay personas que por razones de fuerza mayor no pueden controlar la silla usando este método como por ejemplo personas que no pueden usar bien su extremidad superior del lado del joystick, o simplemente por comodidad no es la mejor solución.

10

Para solucionar esto, una persona se puede recurrir a empresas especializadas en el rubro para crear una silla de ruedas personalizadas para el método de control deseado (ejemplo: control a través de un boquilla donde el piloto sopla o succiona aire, dependiendo de cómo lo haga significara una orden diferente), lo cual solucionará el problema del control, pero a un costo que en la mayoría de los casos supera diez veces el costo de las sillas de ruedas motorizadas convencionales del mercado, haciéndolo una alternativa poco atractiva.

Ilustración 6: Controlador de silla de rueda motorizada de succión y soplido [Wheelchair].

11

Ilustración 7: Controladora de silla de rueda motorizada para la pera [Wheelchair].

12

3.1.2 Esfuerzos anteriores

En el mercado actual anteriores

para

solucionar

se puede ver el resultado de los esfuerzos problemas

de

movilidad

ocasionados

por

discapacidades. Un ejemplo de esto sería el modelo SpinLife [SpinLife] Geo (S3500), esta es una de las sillas de ruedas motorizada más económica del mercado, su fuente energía son dos baterías de 12v (12AH), su velocidad máxima son 6,4Km/h, su capacidad de carga máxima son 113Kg, y su controladora es una PG VR2, esta ultima es una controladora basada en un joystick apoyado en uno de sus apoyabrazos.

PG Drives Technology [PGDrives] es una empresa especializada en controladoras para motores eléctricos, orientada a vehículos industriales y sillas de ruedas. Las controladoras de la empresa PG solo ofrecen soluciones con joystick, lo que limita la usabilidad en discapacitados puesto que no todos podrán controlarla, ya que existen discapacidades que no permiten mover los brazos parcial o completamente, en consecuencia no es posible operar el joystick y por lo tanto seria imposible entregarle ordenes a los motores (ejemplo: personas con una lesión medular, parkinson, personas con amputaciones, etc.).

13

Tabla 1: Comparación de empresas proveedoras y sus soluciones.

Empresa

Velocidad

Capacidad

Máxima

de carga

Modelo

Permobil C300 PS

8Km/h

Control

Precio

Joystick,

$ 2.975.000

botones

CLP

136Kg

[Permobil] Geo Drive Medical

$ 599.500 6,4Km/h

113Kg

Joystick

S3500

CLP

Pride

$ 749.500 Go Chair

5,5Km/h

113Kg

Joystick CLP

[Pride] Pride

$ 1.749.500 Jazzy

6,4Km/h

136Kg

Joystick CLP

[Pride] Electricmobility P321

6,4Km/h

$ 1.092.000

asistida

CLP

114Kg

[ElectricMob]

Como se puede ver, no hay soluciones comerciales ruedas motorizadas para discapacidades específicas.

14

Joystick,

masivas de sillas de

El alumno tesita realizó búsquedas en los buscadores de patentes principales (Ej.: Espacenet [Espacenet]) por sillas de ruedas motorizadas con métodos de control alternativos y no se lograron encontrar patentes en este contexto.

15

3.1.3 Solución propuesta

Como se señaló anteriormente, las sillas de ruedas motorizadas en el comercio de hoy no son una solución para los diversos tipos de discapacidades. Por este motivo surge la idea de crear un prototipo que sea capaz de atravesar esta barrera.

Lo que el estudiante busca alcanzar en este proyecto, es combinar el uso de una controladora, motores eléctricos, un PC y métodos de entrada para desarrollar una silla de ruedas motorizada prototipo, la cual sea capaz de permitirle a una persona con discapacidades que no le permitan manejar las sillas de ruedas disponibles en el mercado, trasladarse por sus propios medios gracias a las virtudes del prototipo en el área de control.

Los métodos de control serían los siguientes:



Wiimote: Joystick tipo control remoto, que se comunica a través de la tecnología Bluetooth, su ventaja es ser móvil, se puede usar en cualquier extremidad o afirmar a cualquier parte del cuerpo, el control tiene acelerómetros que permiten determinar el movimiento de este y la

16

orientación del control. Sus desventajas son el uso de baterías y el tamaño o peso que puede ser una dificultad en ciertas personas.



Reconocimiento de imagen: Su ventaja es la independencia de extremidades necesarias, ya que se usa el rostro del usuario como referencia. Sus desventajas serían el ser experimental y en consecuencia no ser necesariamente fiable.



Touchpad: Mouse táctil de un computador, sus ventajas son que permite saber la magnitud de la intensidad de las ordenes (acelerar suave o brusco), ser fácil de controlar con un dedo. Su desventaja es la dependencia del uso de una extremidad para accionarlo.



Teclado: Teclado de un computador, sus ventajas son ser una forma simple de control, fácil de implementar y compatible. Sus desventajas seria su dependencia del uso de las manos, el tamaño del teclado y la ausencia de la intensidad de la orden a la hora de enviar comandos.

Estos métodos permitirán que la persona dirija la silla desde un control no necesariamente en su apoyabrazos, en el caso del Wiimote, puede ser con un dedo en el caso del TouchPad o sin necesidad de utilizar las extremidades

17

como es el caso del reconocimiento de imágenes con movimientos de la cabeza. Gracias a esta amplia cantidad de opciones, todas disponibles en una unidad para así adaptarse lo mejor posible a las necesidades existentes y ofrecer opciones de control para personas con limitaciones severas de movilidad.

El resultado será una silla de ruedas motorizada con un elevando nivel de abstracción del método de control, para así proveer de una solución a un área dejada de lado en el rubro de las soluciones de transporte para discapacitados.

18

Tabla 2: Complejidad del Dominio Operaciones.

Valor Parámetro Nivel de programación

Concepto Alta

Detalle según tabla Nota

5.5

Control en tiempo real simple

Nivel matemático

Alta

5.5

Cálculos en tiempo real

Operaciones con manejo Alta

5.1

Operaciones de entrada

de dispositivos

y salida a nivel físico Promedio Alta

5.3

A continuación se especifica el detalle de cada punto:



Nivel de Programación: Se crearan clases, usaran librerías externas para manejo de dispositivos y usaran otros elementos de la P.O.O., se usarán hilos para la recepción y envío de datos donde la sincronización es crítica. Como metodología guía se usará AUP para organizar las etapas del trabajo.

19



Nivel Matemático: Para el correcto funcionamiento de todos los dispositivos orientados al control de los motores como para los de los dispositivos de entrada, se necesitarán hacer cálculos críticos que necesariamente tendrán que ser eficientes y casi instantáneos, que determinarán las acciones necesarias a seguir para poder controlar la silla, como por ejemplo calcular la resultante de los vectores de fuerza del dispositivo wiimote para detectar el ángulo de este en un espacio 3D y así transformarlo en una reacción por parte de los motores.



Operaciones con manejo de dispositivos: Existirá un comunicación usando operaciones de entrada y salida con el puerto serial, lo cual hará necesario desarrollar el protocolo de comunicaciones, para así poder darle ordenes a la controladora y accionar los botones. También habrá comunicación Bluetooth con el dispositivo Wiimote y control a través de reconocimiento de imágenes obtenidas a través de una cámara.

20

Tabla 3: Definición del equipo de trabajo.

Persona Profesor Patrocinante

Labor Es el responsable de dirigir el proyecto. En este proyecto es el alumno responsable por el desarrollo del tema de tesis presentado y quien será

Desarrollador

encargado

de

la

construcción

del

software,

modificaciones a la silla de ruedas, hacer pruebas y documentación relacionada con el proyecto.

21

3.2 Justificación 3.2.1 Situación sin Proyecto

Al no existir soluciones genéricas para los diferentes tipos de discapacidades, la persona cuya discapacidad le impida utilizar los métodos de control actuales para sillas de ruedas motorizadas (Joystick), si no puede costearse una silla de ruedas motorizada personalizada de alto costo, no podrá movilizarse por si mismo y necesitará asistencia de terceros de forma permanentemente.

22

3.2.2 Situación con Proyecto

Existiendo una solución prototipo de métodos de control genérico para sillas de ruedas motorizadas, los desarrolladores de sillas de ruedas de este tipo tendrán la base para crear una solución implementable a nivel funcional para una silla de ruedas motorizada con libertad respecto a los dispositivos de control.

Esto provee de una solución versátil al usuario de la silla de ruedas reduciendo en gran medida la dificultad del método de control en las sillas de ruedas motorizadas

23

3.3 Delimitación



La solución se limitará a métodos de control que puedan ser interpretados a través del uso de un computador.



La solución se limitará a la confección e implementación de una única silla de ruedas motorizada prototipo.



El software será a nivel prototipo y no una solución comercial terminada.



El proyecto es de investigación, por lo tanto se espera llegar a un nivel de control de la silla de ruedas suficiente para la demostración de un prototipo.



El método de control de reconocimiento de imagen se presentara como experimental, debido a la complejidad de la implementación de este, es posible que no se llegue a un nivel de usabilidad practico.



Dentro del desarrollo del proyecto, es posible implementar algún otro método de control no mencionado en el anteproyecto, debido al gran abanico de dispositivos interpretables por un computador, puede ser que

24

en el periodo de desarrollo de la tesis se decida adjuntar controles adicionales.

25

4. Metodología

Se eligió la metodología AUP para desarrollar este proyecto de seminario de titulación. La razón de esta elección fue la necesidad de una metodología de desarrollo ágil y genérica. Esta metodología otorga el orden necesario, sin forzar o indagar en prácticas orientadas al desarrollo de sistemas de información, y sus actividades son compatibles con el desarrollo de esta solución del dominio de Operaciones. Además se eligió por ser una metodología iterativa e incremental, necesaria para el desarrollo de este proyecto, donde todas las actividades tienen predecesoras.

AUP cuenta con disciplinas y fases, en donde cada fase presenta iteraciones, tal como se muestra en la siguiente ilustración.

26

Ilustración 8: Disciplinas, fases e iteraciones de AUP.

El proyecto se desarrollará en tres etapas. La primera etapa consistirá en el desarrollo del protocolo de comunicación serial para la controladora, después como actividad sucesora a este se implementará un método de control simple (teclado) para controlar la silla de ruedas. Como actividad sucesora de esta y final se desarrollarán los métodos de control mas avanzados para la silla de ruedas, como el Wiimote o el sistema de movimiento por reconocimiento de rostro.

27

Cada actividad principal será desarrollada en un ciclo de AUP, y se realizará una interacción por cada método de control a implementar, debido a que cada uno necesita pasar por cada una de las fases de la metodología por separado y la complejidad de estos.

28

5. Recursos 5.1 Hardware

A continuación se detalla el hardware necesario para este proyecto: 

Adaptador serial-USB: necesario ya que los computadores de hoy no traen puerta serial y la controladora es serial.



Netbook: necesario para ejecutar el código de la aplicación.

5.2 Software

A continuación se detalla el software necesario para este proyecto: 

.Net Framework y Mono: Conjunto de herramientas para el desarrollo de aplicaciones en C#.



IDE Visual Studio/MonoDevelop: IDE para desarrollo en C#.



OpenCV: Es una librería “Open Source” de visión artificial originalmente desarrollada por Intel.



Librería Wiimote: Librería para acceso a dispositivo Wiimote.



Sistema operativo: Linux.

29

5.3 Otros

A continuación se detallan otros dispositivos necesarios para este proyecto:



Controladora RoboteQ AX 2550: Controladora de motores de potencia suficiente para mover una persona.



Silla de ruedas: Proporcionada por el patrocinante, será la base del proyecto.



Baterías 12v: Fuente de energía para la controladora y los motores.



Cámara: Origen de datos para el control por reconocimiento de imagen.



Wiimote: Control Bluetooth con acelerómetros que se usara para controlar la silla.

30

6. Cuerpo 6.1 Construcción de la librería para manejar la controladora 6.1.1 Iniciación

En esta etapa se

definió el alcance del proyecto el cual abarca la

creación de una librería en Mono [Mono] usando el IDE MonoDevelop [MonoDevelop], esta librería será permitirá al programador usar el lenguaje del Framework .Net para darle ordenes a la controladora RoboteQ AX2550 de manera estructurada, la librería a construir será la base para todas las aplicaciones desarrolladas en esta tesis. Esta librería no busca ser una librería de alta fiabilidad, ya que el alcance de esta tesis se considera experimental.

31

6.1.2 Elaboración

Durante el desarrollo de la fase de construcción de esta etapa, los diagramas de clases y de casos de uso sufrieron modificaciones, debido a la naturaleza de investigación del proyecto y los constantes replanteamientos de la forma en que debía ser presentada la solución.

A continuación se presenta el diagrama de casos de uso final del proyecto, en este diagrama se puede apreciar el programa de la capa superior como la entidad que invoca los casos de uso, esto ocurre debido a que la solución a presentar es una librería, y quien invoca sus funcionalidades es un programa con lógica de una capa superior.

32

Ilustración 9: Diagrama de casos de uso de la controladora.

Para la construcción se necesitara

evaluar las diferentes formas de

comunicarse con una puerta serial y elegir una para ser la forma de comunicación definitiva de la controladora.

A continuación se presenta el diagrama de clases de la librería que se comunicaría con la controladora.

33

Ilustración 10: Diagrama de clases de la solución que contiene la librería AX2550.

34

6.1.3 Construcción

En la construcción se estudio el manual de la controladora AX2550.

Ilustración 11: Controladora RoboteQ AX2550.

Para iniciar esta fase, el alumno energizó la controladora con las 2 baterías disponibles de 12v en serie (sumando 24v), se conectaron los motores y se puso un switch de emergencia para desconectar el sistema de acuerdo a los diagramas proporcionados por el fabricante.

35

Ilustración 12: Diagrama eléctrico usado en el proyecto.

La controladora dispone de una perilla para cambiarla de modo, esta se dejó en modo de comunicación serial para computador ya que toda la comunicación con la controladora se hace a través del puerto serial. El computador portátil que se usará en la silla de ruedas no posee puerta serial, por lo tanto se provee de un puerto serial a través de un puerto serial USB.

36

Ilustración 13: Puerto serial USB.

Posterior a esto se procedió a iniciar la comunicación con la puerta serial a modo rápido usando el comando screen (GNU Linux),

desde la cual se

enviaron comandos básicos de prueba como consultar los amperios de las baterías (?a convertido a binario), a los cuales la controladora respondió adecuadamente.

37

Tabla 4: Comandos aceptados por la controladora AX2550.

Comando %rrrrrr !Ann !Ann !Bnn !bnn !C !c ?a o ?A ?v o ?V ?p o ?P ?r o ?R ?m o ?M ?e o ?E ?i o ?I

Tipo Comando Comando Comando Comando Comando Comando Comando Consulta Consulta Consulta Consulta Consulta Consulta Consulta

?k o ?K

Consulta

Descripción Reiniciar controladora Canal 1, comando hacia delante de valor nn Canal 1, comando de reversa de valor nn Canal 2, comando hacia delante de valor nn Canal 2, comando de reversa de valor nn Encender salida del accesorio C Apagar salida del accesorio C Leer amperes de las baterías Leer voltaje aplicado a los motores Leer entradas análogas 1 y 2 Leer entradas análogas 3 y 4 Leer temperatura del disipador de calor Leer voltaje interno y de la batería Leer entradas digitales Lectura rápida de la velocidad y posición del codificador

Posteriormente se procedió a trabajar con el Framework mono [Mono] y se probaron varias formas de conectarse a través del puerto serial, para finalmente trabajar

con

la

librería

perteneciente

al

Framework

monoBOTICS

[monoBOTICSFramework] para la comunicación serial (MBF.SerialPort), la cual cumplió correctamente con la función de comunicarse con la puerta serial correctamente. Posteriormente se realizo la construcción de la librería para la controladora con sus clases.

38

Toda la comunicación con la controladora AX2550 se efectuara a través del uso de una instancia de esta clase.

Esta clase agrupa todos los métodos necesarios para usar las funciones de la controladora además de los métodos para conectarse y desconectarse de esta.

Las tablas a continuación muestran los métodos, atributos y propiedades de la clase AX2550.

39

Tabla 5: Métodos de la clase AX2550.

Tipo devuelto

Descripcion

Open

void

StopMotors Reset

void void

Constructor, recibe la dirección del puerto serial a abrir como cadena. Abre la conexión con la controladora a través del puerto serial. Detiene los motores. Reinicia la controladora.

Close

void

Cierra la comunicación con la puerta serial.

ReadParameter: string parameter

string

Obtiene el parámetro entrado como cadena de la configuración interna de la controladora y devuelve su valor como cadena.

WriteParameter: string parameter, string val

void

Escribe el valor (val) del parámetro entrado en la configuración interna de la controladora.

DataRecievedHandler: object sender, SerialDataReceivedEventArgs e

void

Función que responde al evento DataRecieved de la librería Serial Port, esta función procesa carácter a carácter los datos recibidos de la puerta serial y los compara con la lista de respuestas esperadas para confirmar su ejecución.

Write: string command

void

TemperatureConvert: int analogValue

int

WriteCommand: string command, int expectedResponseLines

ExpectedR esponse

Escribe un comando en la controladora y monitorea una respuesta exitosa de comando.

Motor1DirectionChange: object sender, ValueChangedEventArgs< MBF.Core.Spin > args

void

Maneja el evento de cambio de sentido de giro del motor 1.

Motor1SpeedChange: object sender, ValueChangedEventArgs< int > args

void

Maneja el evento de cambio de velocidad del motor 1.

Nombre Métodos públicos AX2550: string port

Métodos privados

Convierte un string a cadena de bytes para ser enviados por el puerto serial. Convierte desde un valor análogo a temperatura en grados Celsius, esta función proviene de la documentación de la controladora.

40

Motor2DirectionChange: object sender, ValueChangedEventArgs< MBF.Core.Spin > args Motor2SpeedChange: object sender, ValueChangedEventArgs< int > args Battery1AmpsQueried: object sender, ValueQueriedEventArgs< int > args Battery2AmpsQueried: object sender, ValueQueriedEventArgs< int > args Heatsink1TemperatureQueried: object sender, ValueQueriedEventArgs< int > args Heatsink2TemperatureQueried: object sender, ValueQueriedEventArgs< int > args AnalogInput1ValueQueried: object sender, ValueQueriedEventArgs< int > args AnalogInput2ValueQueried: object sender, ValueQueriedEventArgs< int > args AnalogInput3ValueQueried: object sender, ValueQueriedEventArgs< int > args AnalogInput4ValueQueried: object sender, ValueQueriedEventArgs< int > args

void

Maneja el evento de cambio de sentido de giro del motor 2.

void

Maneja el evento de cambio de velocidad del motor 2.

void

Maneja el evento de la consulta por la intensidad de corriente de la batería 1.

void

Maneja el evento de la consulta por la intensidad de corriente de la batería 2.

void

Maneja el evento de la consulta por la temperatura del disipador 1.

void

Maneja el evento de la consulta por la temperatura del disipador 2.

void

Maneja el evento de la consulta por la entrada análoga 1.

void

Maneja el evento de la consulta por la entrada análoga 2.

void

Maneja el evento de la consulta por la entrada análoga 3.

void

Maneja el evento de la consulta por la entrada análoga 4.

41

Tabla 6: Atributos y propiedades de la clase AX2550.

Nombre Atributos controllerSerialPort encoding writeBuffer readBuffer

Tipo

Descripción

SerialPort System.Text.ASCIIEncoding List< byte > List< byte >

expectedResponseList

List< ExpectedResponse >

actualResponse

ExpectedResponse

carriageReturn

byte

delay

int

maxSpeed

int

minSpeed

int

TempTable

int[]

motors batteries heatsinks

DSMotor< int, IntNumeric >[] Battery< int, IntNumeric >[] Heatsink< int, IntNumeric >[] NumericAX2550Member< int, IntNumeric >[]

Puerta serial. Encoding necesario para convertir textos. Buffer de escritura. Buffer de lectura. Lista de respuestas esperadas que aseguran la fiabilidad. Respuesta actual siendo recibida. Variable que almacena el valor del salto de línea para su fácil lectura. Ms. de descanso entre escrituras/lecturas. Máxima velocidad posible en los motores. Mínima velocidad posible en los motores. Tabla de interpolación para conversión a grados Celsius de los valores entregados por los disipadores. Motores de la controladora. Baterías de la controladora. Disipadores de la controladora.

analogInputs Propiedades Motors [get, set] Batteries [get, set] Heatsinks [get, set] AnalogInputs [get, set] Connected [get]

DSMotor< int, IntNumeric >[] Battery< int, IntNumeric >[] Heatsink< int, IntNumeric >[] NumericAX2550Member< int, IntNumeric >[]

Entradas análogas de la controladora. Cotores de la controladora. Baterias de la controladora. Disipadores de la controladora. Entradas análogas de la controladora. Consulta si esta conectada la controladora.

bool

42

Para poder conectarse con la controladora, primero se debe instanciar esta con la dirección del puerto serial a utilizar (ej: “/dev/ttyUSB0”), posteriormente se llama al método Open(), lo cual inicia la conexión con la controladora.

El desarrollo de una librería para esta controladora tiene la ventaja que para cualquier mensaje enviado, la controladora responde con el mismo mensaje para confirmar su recepción, esto permitiría confirmar la comunicación correcta de la controladora mensaje a mensaje. Para aprovecharse de esto se creo un sistema de confirmación de respuestas, representadas como una lista objetos de tipo ExpectedResponse,

A continuación se muestra el código de las funciones encargadas de escribir en la puerta serial y la función invocada al dispararse el evento DataRecieved de la puerta serial.

43

Ilustración 14: Código del método Write de la clase AX2550.

44

Ilustración 15: Código del método DataRecievedHandler de la clase AX2550.

La clase ExpectedResponse es un contenedor para una respuesta esperada en particular, en la clase AX2550 se crea una lista para agrupar todas las respuestas esperadas, ya que el envío de comandos a la controladora puede realizarse de manera asíncrona.

45

Al enviarse un comando a la controladora, (ej: “!a8F”), se agregara inmediatamente la respuesta esperada (ExpectedResponse) “!a8F” a la lista de respuestas esperadas, si la respuesta no vuelve en un tiempo determinado, se lanza una excepción la cual puede ser manejada en las capas superiores.

A continuación se muestran los atributos y propiedades de las clases ExpectedResponse y Response, además un ejemplo la función WriteCommand que ejecuta la lógica mencionada anteriormente.

Tabla 7: Atributos y propiedades de la clase ExpectedResponse.

Nombre Atributos expectedString response

Tipo

Descripción

string Response

responseCount

int

index responseRecieved Propiedades ExpectedString [get, set] Response [get, set]

int bool

Cadena esperada. Objeto respuesta. Cantidad de líneas de respuesta recibidas. Indice de la respuesta. Confirma la recepción de la respuesta.

ResponseCount [get, set]

int

Index [get, set] ResponseRecieved [get, set]

int

string Response

bool

Cadena esperada. Objeto respuesta. Cantidad de líneas de respuesta recibidas. Indice de la respuesta. Confirma la recepción de la respuesta.

46

Tabla 8: Atributos y propiedades de la clase Response.

Nombre Atributos

Tipo

Descripción

data

List< string >

Líneas de las cadenas de respuesta.

List< string >

Líneas de las cadenas de respuesta.

Propiedades Data [get, set]

Ilustración 16: Código del método WriteCommand de la clase AX2550.

47

Los motores y diferentes accesorios de la controladora están organizados dentro de la clase usando la misma lógica vista en otros desarrollos con el Framework monoBOTICS, en donde los motores se instancian heredando de la librería de motores (MBF.Motors), la cual contiene la estructura para representar un motor que tiene las propiedades de sentido de giro y velocidad a las

cuales

se

conecta

la

controladora,

estos

son

objetos

de

tipo

NumericMember y BiStateMember, lo cuales tienen la cualidad de disparar eventos al cambiar su estado o valor, la clase controladora esta suscrita a estos eventos, entonces al cambiarse el valor de estos la clase controladora maneja el evento ValueChanged y ejecuta los comandos necesarios en la puerta serial para cambiar el sentido de giro o velocidad de los motores. A continuación se muestra el código del método que maneja el evento.

48

Ilustración 17: Código del método que maneja el evento de cambio de velocidad del motor 1 de la clase AX2550.

La el uso de NumericMembers permite al programador en las capas superiores acceder a los motores de la controladora como propiedades, simplificando el código a usar y mejorando la eficiencia. A continuación se muestra un código de ejemplo para acceder a los motores de manera fácil, en donde la controladora ejecuta todos los comandos necesarios al cambiar el valor de la propiedad velocidad de un motor.

49

Ilustración 18: Código de ejemplo mostrando el control simplificado de motores.

Los disipadores y baterías se instancian con clases contenedoras aparte, la clase disipador tiene la propiedad temperatura y la clase batería amperes. Para estos se quiso usar la clase NumericMember, pero esta no cumplía

50

completamente con los requisitos para poder usarse de la manera deseada, ya que al consultar el valor de estas propiedades se deberían generar las consultas en la controladora, para lo cual la clase NumericMember no poseía un evento. Para solucionar este problema se creo una nueva clase que hereda de NumericMember, esta clase se llama NumericAX2550Member, la cual dispara el evento ValueQueried que se dispara al consultarse el valor contenido.

Ilustración 19: Clase NumericAX2550Member.

51

Ilustración 20: Ejemplo de código en donde se consulta por valores de los accesorios de la controladora.

Con esto concluye la etapa de construcción de la librería para poder utilizar las funciones de la controladora de motores AX2550.

52

6.1.4 Transición

En esta etapa se realizaron diversas pruebas con la controladora, las cuales consistieron en la confección de un programa para realizar pruebas, en las cuales se probó consultar por los amperes de la batería, la temperatura de los disipadores y los datos de las entradas análogas, de las cuales la controladora pudo responder correctamente a la consulta el 100% de las veces. También se probó el envío de comandos a los motores, en los cuales el alumno agregó un código simple en el cual la controladora le envía comandos a la controladora dependiendo de la tecla presionada a través de la consola (Console.ReadKey), el cual se probó muchas veces teniendo un 100% de éxito en el envío de comandos. A continuación se muestra el código de pruebas utilizado.

53

Ilustración 21: Programa simple de pruebas.

54

6.2 Modificación de la silla de ruedas y construcción de un programa de control simple 6.2.1 Iniciación

En esta etapa se analizará la estructura física de la silla de ruedas, se analizarán problemas mecánicos que pueda presentar la silla como es el caso de los motores, cadenas, engranajes, pivote de las ruedas delanteras, etc. También se montara una base para el netbook móvil usando partes domesticas. Por el lado programación, se diseñará un programa de control simple con el teclado y se usará la silla de tal forma que se pueda probar el movimiento y se puedan resolver problemas de diseño relacionados con movimientos de la silla.

55

6.2.2 Elaboración

Durante el desarrollo de la fase de construcción de esta etapa, los diagramas de clases y de casos de uso sufrieron modificaciones, debido a la naturaleza de investigación del proyecto y los constantes replanteamientos de la forma en que debía ser presentada la solución.

A continuación se presenta el diagrama de casos de uso del programa para controlar la silla con el teclado.

Ilustración 22: Diagrama de casos de uso para el programa de control simple.

56

A continuación se presenta el diagrama de clases final de esta etapa, este fue desarrollado en esta iteración y las iteraciones posteriores del desarrollo.

Ilustración 23: Diagrama de clase de la librería que implementa las lógicas de control.

57

6.2.3 Construcción

Se inició la etapa inspeccionando la silla de ruedas disponible para el desarrollo de esta tesis, la silla en cuestión se muestra en la siguiente ilustración:

58

Ilustración 24: Silla de ruedas a usar.

La silla de ruedas presentaba varios signos de deterioro en algunas partes móviles a causa del largo periodo de almacenaje de esta, para recuperar su funcionalidad adecuada se reemplazaron 4 rodamientos pertenecientes a las ruedas, se lubricaron y re-tensaron las cadenas.

59

Las baterías disponibles para este proyecto son dos baterías de scooter de 12 Volts, estas se montaron en la base de la silla, a continuación se conectó la controladora a estas usando el diagrama eléctrico mencionado en la etapa anterior, esta instalación incluyó la instalación de conectores eléctricos necesarios para desconectar la controladora y también conectarla a un transformador para cargar las baterías, también se instaló un switch de emergencia para apagar la controladora, este puede ser usado además como switch de emergencia en caso de algún inconveniente que requiera detener la silla, finalmente se rotularon todos los cables para su fácil identificación.

A continuación se muestran los conectores usados y la instalación de las baterías.

60

Ilustración 25: Conector usado en el sistema eléctrico.

Ilustración 26: Baterías montadas en soportes.

61

Posteriormente se procedió búsqueda y construcción de la base par el netbook, se requiere que esta sea móvil, por lo tanto se analizaron varios diseños de brazos que cumplan con la función de ser móviles, no se doblen con las fuerzas de aceleración de la silla y que sea barato de construir, para esto se analizó como alternativa el uso de un cuello de tipo ganso proveniente de las lámparas de escritorio actualmente disponibles en el mercado, posterior a este análisis el alumno visitó varias tiendas para buscar una lámpara adecuada. Después de ver distintos tipos de modelos y precios se optó por usar dos lámparas de valor 1.990 pesos disponibles en el mercado.

Ilustración 27: Modelo de lámpara comprada en el mercado.

62

Se compro para la base una lámina de aluminio para reducir el peso, ya que la inercia del conjunto fijo de la base puede hacer que se doblen los cuellos de ganso al acelerar, el alumno procedió a dimensionar esta lámina y se conecto a los cuellos de ganso, obteniéndose una base adecuada para el netbook como se muestra en la siguiente ilustración.

Ilustración 28: Base de aluminio conectado a dos cuellos de ganso extraídos de lámparas.

63

Esta base de aluminio necesita de otra base a la cual anclar los cuellos de ganso, para esto el alumno recurrió al uso las herramientas disponibles como una maquina soldadora al arco, un esmeril angular, un taladro con brocas para metal y un spray antioxidante para construir una base adecuada para sostener la parte inferior de los cuellos de ganso y así poder sostener la base de aluminio a una altura útil para el piloto. A continuación se presenta una ilustración con los resultados de la construcción de esta base.

64

Ilustración 29: Silla de ruedas con soporte para base de aluminio soldada y pintada.

Una vez terminado esto se cambió de contexto y el alumno inicia la construcción un programa de control simple para probar el control de la silla, este programa usa una ventana GTK y desde esta ventana se capturan los eventos de presión de las teclas en un formulario, este se diseñó considerando una disposición de teclas por defecto usada en videojuegos para el control de la silla (W, A, S y D) con el propósito de simplificar el control de esta. A

65

continuación se presenta el formulario inicial para el control de la silla de ruedas.

Este formulario consiste de: 

“Combo box entry” editable para seleccionar la puerta serial del computador a usar.



Un botón “Connect” para iniciar la conexión con la controladora.



Dos “Spin button” para controlar la potencia y la potencia mínima a aplicarse a los motores.



Cuatro “Progress bar” que representan la potencia y dirección aplicada a los dos motores.



Un “Notebook” que separa en pestañas los diversos métodos de control.



Un “Check box” para activar el método de control del teclado.



Cuatro botones que permiten configurar teclas a usar para mover la silla.



Cuatro “Progress bar” que representan las componentes en X y Y del vector movimiento ejecutado presionando teclas.

66

Ilustración 30: Formulario para control con teclado.

Para contener todo el código principal del sistema perteneciente a la silla se construyo la clase WheelchairControl, esta es la clase núcleo del sistema ya que

conecta la clase formulario, la clase

controladora y las clases que

contienen la lógica de control entre si. A continuación se muestran los métodos, atributos y propiedades de la clase WheelchairControl.

67

Tabla 9: Métodos de la clase WheelchairControl.

Nombre Métodos públicos ConnectController: string port

Tipo devuelto

Método que llama a la conexión de la controladora. Método para desconectarse de la controladora. Método usado para detener la silla de ruedas.

void

DisconnectController

void

Stop

void

Descripcion

Métodos protegidos OnControlLogicMovementIssued: object sender, Vector2D< double > args

virtual void

68

Método que captura los eventos disparados por las lógicas de entrada para posteriormente aplicarle la lógica de movimiento de tanque y finalmente enviar las ordenes a los motores.

Tabla 10: Atributos y propiedades de la clase WheelchairControl.

Nombre Atributos

Tipo

keyboardInputLogic

KeyboardInputLogic

mouseInputLogic

MouseInputLogic

wiimoteInputLogic

WiimoteInputLogic

cameraInputLogic

CameraInputLogic

tankMovementLogic

TankMovementLogic

tank

Tank

keyboardControlEnable

bool

mouseControlEnable

bool

wiimoteControlEnable

bool

cameraControlEnable

bool

controller

AX2550

power

int

minPower

int

Propiedades ControllerConnected [get]

Descripción

bool

CameraInputLogic [get]

CameraInputLogic

KeyboardLogic [get]

KeyboardInputLogic

MouseInputLogic [get]

MouseInputLogic

WiimoteInputLogic [get]

WiimoteInputLogic

Controller [get]

AX2550

69

Lógica de control de entrada para la silla. Lógica de control de entrada para la silla. Lógica de control de entrada para la silla. Lógica de control de entrada para la silla. Lógica de control de salida disponible para la silla. Objeto para recibir los datos de la lógica de control de tanque. Variable para activar o desactivar el método de control de entrada por teclado. Variable para activar o desactivar el método de control de entrada por Mouse. Variable para activar o desactivar el método de control de entrada por Wiimote. Variable para activar o desactivar el método de control de entrada por cámara. Controladora. Variable para controlar la potencia máxima de la controladora. Variable para controlar la potencia mínima de la controladora para romper la inercia. Consulta si la controladora se encuentra conectada. Lógica de control de entrada para la silla. Lógica de control de entrada para la silla. Lógica de control de entrada para la silla. Lógica de control de entrada para la silla. Controladora.

MinPower [get, set]

int

Power [get, set]

int

WiimoteControlEnable [get, set]

bool

MouseControlEnable [get, set]

bool

KeyboardControlEnable [get, set]

bool

CameraControlEnable [get, set]

bool

Propiedad para controlar la potencia mínima de la controladora para romper la inercia. Propiedad para controlar la potencia máxima de la controladora. Propiedad para activar o desactivar el método de control de entrada por Wiimote. Propiedad para activar o desactivar el método de control de entrada por Mouse. Propiedad para activar o desactivar el método de control de entrada por teclado. Propiedad para activar o desactivar el método de control de entrada por cámara.

Para explicar en mejor forma el funcionamiento general de las clases y como se relacionan entre si, a continuación se muestra el flujo de eventos del sistema:

1. Esperar datos. 2. Clase método de entrada acusa actividad. 3. Clase de lógica de control de entrada procesa los datos, aplica filtros, zonas muertas, etc. 4. Si hubo movimiento, clase de lógica de control de entrada dispara evento de movimiento ejecutado 5. Clase de control de la silla (WheelchairControl) al estar suscrito a este evento, lo maneja.

70

6. Clase control de la silla usa la clase de lógica de control de salida de tanque (TankMovementLogic) para procesar el vector movimiento. 7. Clase de lógica de control de tanque devuelve los datos en una clase representando un tanque que contiene los datos de la potencia para ambos motores. 8. Clase control de la silla escribe los datos en las propiedades que representan a los motores en la clase controladora (AX2550). 9. Si hubo cambio de valor en los objetos de los motores, estos disparan el evento cambio de valor cambiado (ValueChanged). 10. Clase controladora al estar suscrito a este evento, lo maneja. 11. Clase controladora escribe los comandos necesarios en la controladora. 12. La controladora ejecuta los comandos cambiando la polaridad y potencia aplicada a los motores. 13. La silla de ruedas se mueve.

A continuación se muestra un diagrama de flujo de un movimiento de la silla:

71

Ilustración 31: Diagrama de flujo de la ejecución de un movimiento de la silla.

La clase WheelchairControl permite el acceso a varios de sus atributos como las lógicas de control o la controladora a través de propiedades, esto es debido a la alta comunicación necesaria entre clases, por ejemplo la clase formulario puede cambiar la zona muerta del control Wiimote, y esta puede ser accedida y modificada desde la clase formulario de la siguiente forma: wheelChairControl.LogicaDeEntrada.ZonaMuerta = valorDelFormulario;

72

Continuando con la construcción del proyecto, se analiza la forma en que debiesen interpretar los dispositivos de entrada. Si la controladora recibiese información en bruto de los diferentes dispositivos de entrada para energizar los motores, el control de la silla de ruedas resultaría ser bastante brusco y en muchos casos inmanejable debido a los ruidos de los diferentes métodos de entrada, para esto se crearon clases de lógica de entrada para cada uno de los diferentes métodos (en este caso KeyboardInputLogic), y una clase que contiene la funcionalidad que comparten entre si (InputDeviceLogic), estas fueron agrupadas en otro proyecto dentro de la solución, HMIDLogic (HumanMachine Interface Device Logic).

Ilustración 32: Clase InputDeviceLogic y sus clases hijas.

La clase InputDeviceLogic concentra toda la lógica que comparten los diferentes métodos de control. A continuación se muestran las tablas de atributos y métodos de la clase InputDeviceLogic.

73

Tabla 11: Atributos y propiedades de la clase InputDeviceLogic.

Nombre Atributos deadzone maxThreshold

Tipo

Descripción

double double

continuosFeedbackInputDelay

int

Zona muerta global. Umbral de movimiento global. Retraso entre ejecución de los cambios de la entrada de controles.

Propiedades Deadzone [get, set] MaxThreshold [get, set] ContinuosFeedbackInputDelay [get, set]

double double int

Zona muerta global. Umbral de movimiento global. Retraso entre ejecución de los cambios de la entrada de controles.

Tabla 12: Métodos de la clase InputDeviceLogic.

Nombre Métodos protegidos

Tipo devuelto

Descripcion

VectorMove2D: Vector2D< double > vector, double deadzone, double maxThreshold

Virtual Vector2D

VectorMove2D: Vector2D< double > vector

Virtual Vector2D

OnMovementIssued: object sender, Vector2D< double > vector

virtual void

Realiza la transformación de un vector de movimiento en bruto a un vector de movimiento procesado, que evalúa zonas muertas, limita a umbrales y construye el vector de movimiento en base a eso. Sobrecarga que utiliza la zona muerta y umbrales locales. Función que dispara el evento MovementIssued que puede ser atajada por otras capas para procesar el movimiento resultado.

Varias clases de la solución usan la clase Vector2D contenida en la librería SimpleMath, esta clase creada por el alumno y se usa para representar

74

vectores de dos dimensiones, la ventaja de usar esta clase es que el proyecto usa mucho vectores en dos dimensiones y esta clase además de representarlos, permite la suma, división, multiplicación, etc. de vectores entre si usando los operadores unarios o funciones incluidas dentro de la clase.

La función VectorMove2D de la clase InputDeviceLogic es la función principal que comparten y usan los hijos de esta clase, esta función transforma un Vector2D de movimiento en bruto de un dispositivo de entrada, evalúa si supera la zona muerta, lo compara con un vector de movimiento máximo posible y devuelve el vector resultante filtrado, este vector resultante tiene componentes entre los valores -1 y 1 que representan la cantidad máxima de intención de movimiento en cada eje. A continuación se muestra el contenido de la función VectorMove2D.

75

Ilustración 33: Código del método VectorMove2D de la clase InputDeviceLogic.

76

La clase KeyboardInputLogic hereda de la clase InputDeviceLogic y es la encargada de aplicar la lógica específica de movimiento del teclado. A continuación se muestran las tablas de atributos, métodos y propiedades de la clase KeyboardInputLogic.

Tabla 13: Métodos de la clase KeyboardInputLogic.

Nombre Métodos públicos OnKeyPressed: object sender, KeyboardInputLogicEventArgs args OnKeyReleased: object sender, KeyboardInputLogicEventArgs args Métodos privados KeyAccelerationThread

Tipo devuelto

Descripción

virtual void

Método manejado del evento tecla presionada.

virtual void

Método manejado del evento tecla soltada.

void

Hilo de control si se usa el método de control del teclado.

77

Tabla 14: Atributos y propiedades de la clase KeyboardInputLogic.

Nombre Atributos

Tipo

Descripción

forwardKeyPressed

bool

backwardKeyPressed

bool

leftKeyPressed

bool

rightKeyPressed

bool

useKeyboard

bool

keyboardHeading

Vector2D

previousKeyboardHeading

Vector2D

keyboardAcceleration keyboardAccelerationThread Propiedades

double Thread

UseKeyboard [get, set]

bool

Variable de control si la tecla esta presionada. Variable de control si la tecla esta presionada. Variable de control si la tecla esta presionada. Variable de control si la tecla esta presionada. Variable usada para activar este método de control (inicializa el hilo de control al activarse por property). Vector dirección de movimiento del teclado. Vector dirección de movimiento previo del teclado. Relación de aceleración. Hilo de control del teclado. Variable usada para activar este método de control (inicializa el hilo de control al activarse por property).

Esta clase esta diseñada de tal forma que se subscribe al evento de tecla presionada de otra clase (para permitir usar diferentes formas de leer el teclado) y al ejecutarse el manejador del evento esta guarda el estado de las teclas presionadas (adelante, atrás, izquierda y derecha). A continuación se muestra el código de las funciones que manejan el los eventos de tecla presionada y tecla soltada.

78

Ilustración 34: Código de los métodos de la clase KeyboardInputLogic que manejan el evento tecla soltada y tecla presionada.

Al habilitarse este método de control a través de su propiedad UseKeyboard, automáticamente se inicializa el hilo de control del teclado. A continuación se

79

muestra

la

definición

de

la

propiedad

UseKeyboard

de

la

clase

KeyboardInputLogic.

Ilustración 35: Código de la propiedad UseKeyboard de la clase KeyboardInputLogic.

El hilo de control del teclado esta constituido principalmente por un ciclo continuo que funciona mientras este habilitado el uso del teclado, este ciclo esta encargado de monitorear las teclas presionadas, y en base a esto construir un vector de aceleración de componentes unitarias (accelVector), este vector (Vector2D) se promedia en cada ciclo con un vector de movimiento del teclado (keyboardHeading) de una manera proporcional controlada por la variable keyboardAcceleration (30%), para así proporcionar una aceleración suave. En

80

cada vuelta del ciclo, este dispara el evento MovementIssued si el vector ha cambiado (ya que se compara con el vector previousKeyboardAcceleration en cada vuelta del ciclo que contiene el último vector calculado), esto se hace para mejorar la eficiencia del uso del procesador.

Ilustración 36: Código del hilo de control del teclado de la clase KeyboardInputLogic.

81

La clase WheelchairControl esta suscrita al evento MovementIssued disparado por la clase KeyboardLogic, y por cada vez que se dispara obtiene una nueva intención de movimiento por parte del conductor de la silla. La clase WheelchairControl maneja el evento en la función OnMovementIssued, en esta función

(si

la

controladora

esta

conectada)

se

llama

a

la

clase

TankMovementLogic (detallada en la siguiente iteración), esta procesa el Vector2D de intención de movimiento y retorna un objeto de tipo tanque (Tank), que contiene los valores de aceleración de los dos motores en disposición de tanque, posteriormente en la misma función se le asignan a las propiedades dirección y sentido de los motores de la controladora los valores contenidos en la clase Tank, lo cual según lo descrito en la primera etapa de esta tesis, ejecuta todos los comandos necesarios en la controladora y acciona los motores moviendo la silla de ruedas en la dirección deseada. A continuación el código de la función OnMovementIssued de la clase WheelchairControl.

82

Ilustración 37: Código del método OnControlLogicMovementIssued de la clase WheelchairControl.

Con este desarrollo al presionar la tecla W (ejemplo avanzar adelante), al pasar por todas las capas y eventos, se le asigna el valor del sentido del motor 1 en anti-horario, y el del motor 2 en sentido horario y la potencia de ambos motores en un valor capturado por el formulario (el motor 1 esta en una dirección opuesta al motor 2, por lo tanto para que las dos ruedas giren en un sentido que

83

la silla avance hacia delante, tienen que tener sentidos opuestos), esto logra hacer que la silla avance hacia adelante.

Ilustración 38: Sentido de giro de las ruedas y dirección de la silla.

Al soltar una tecla, se dispara el evento de tecla soltada, y el paso por las diferentes capas termina con la acción de poner la potencia de ambos motores en cero, esto detiene la silla. Para los otros casos como el girar la silla en sentido anti-horario, se configura el motor 1 (motor en la derecha) con sentido horario, el motor 2 en sentido horario y la potencia al valor capturado del formulario, esto hace que la rueda de la izquierda haga torque en sentido antihorario respecto al centro masa de la silla al igual que la rueda derecha,

84

haciendo que la silla gire sobre si misma en el sentido deseado. El caso es similar para hacer girar la silla en sentido horario, se configuran ambos motores en sentido anti-horario, ambas ruedas generan torque en sentido horario respecto del centro de masa y la silla gira en el sentido deseado. Finalmente, para el caso de la reversa, el sentido del motor 1 es horario y del motor 2 es anti-horario, lo cual completa las 5 acciones (avanzar, retroceder, girar horario, girar anti-horario y detenerse) necesarias para un control básico de la silla de ruedas.

85

6.2.4 Transición

Se realizaron varias pruebas de movimiento que implican el transito dentro de una casa estrecha, el control fue apto para el manejo de la silla dentro de entornos cerrados, las respuestas de la controladora fueron fiables, se detecto una única falla en la comunicación con la controladora que consiste en que cuando baja la carga de las baterías, el control se vuelve errático, para evitar esto puede usarse una batería aparte para energizar la controladora, cosa de aislarla del sistema de las baterías que se descargan rápido y mueven los motores, pero esa solución queda fuera del alcance de esta tesis. En las pruebas se detectó que se puede mejorar la suavidad del control, ya que a veces puede ser un poco brusco, pero esto también queda fuera del alcance de esta tesis.

86

6.3 Creación de métodos de control avanzados 6.3.1 Creación del método de control con mouse 6.3.1.1 Iniciación

En esta etapa se espera desarrollar un método de entrada a través del mouse (touchpad). Para la elaboración del primer método de control análogo se tendrán que considerar más variables que en el método de control anterior y estudiar formas de comunicación con dispositivos de interfaz humana, analizar las formas de interpretar los comandos enviados a través de estos dispositivos. Esta etapa esta acotada solamente al control de la silla a través del mouse en su versión touchpad.

87

6.3.1.2 Elaboración

Durante el desarrollo de la fase de construcción de esta etapa, los diagramas de clases y de casos de uso sufrieron modificaciones, debido a la naturaleza de investigación del proyecto y los constantes replanteamientos de la forma en que debía ser presentada la solución. A continuación se presenta una ilustración con el modelo de caos de uso para esta etapa.

Ilustración 39: Diagrama de casos de uso para control con el mouse.

88

6.3.1.3 Construcción

Se inicia esta fase buscando la forma de comunicarse a través del mouse para leer sus movimientos, se inicio esto tratando de leer los desplazamientos desde las librerías de sistema ofrecidas por el Framework, estas solo ofrecían capturar el mouse cuando se mueve sobre un control GTK, lo cual no se traduce a un movimiento, ya que el mouse tiene que partir dentro de este control GTK y al moverse se saldrá de esta área, por lo tanto se necesitaba una solución mas directa, para ello se trato de leer el streaming de datos proveniente desde el dispositivo mouse en el sistema, lo cual resulto en un streaming de datos, del cual se enviaban los datos del mouse en 3 bytes, posterior a un análisis, este método se considero poco fiable, además de traspasar las capas del sistema del servidor X de una manera no muy elegante y requería el uso de privilegios especiales. Posteriormente se optó por usar una solución antiguamente vista en videojuegos, la cual consiste en usar un control de formulario, en este caso un GTK.DrawingArea, esta área se creó en el formulario con un tamaño de 300 x 300 pixeles, de esta área se puede manejar el evento MotionNotifyEvent, este evento se dispara cada vez que el cursor se mueve dentro del área del control GTK.DrawingArea, y por cada vez que se dispara, se le ordena al sistema que mueva el cursor al centro del GTK.DrawingArea, así efectivamente el cursor queda “atrapado”, reportando los movimientos del mouse en los argumentos del evento.

89

Una vez clara la forma de leer los datos del mouse, se procede a la creación de la interfaz visual del método de control

Este formulario consiste de: 

Los mismos controles para comunicarse con la controladora de la fase anterior, ya que esta funcionalidad se comparte.



Un “Notebook” que separa en pestañas los diversos métodos de control.



Un “Check box” para activar el método de control del mouse.



Un control “DrawingArea” que es el área de movimiento del mouse donde se capturan sus movimientos.



Dos botones que inician la captura del movimiento del mouse, uno para modo arrastre y modo normal.



Dos “Spinbutton” que permiten ajustar las zonas muertas de los dos modos de movimiento.



Dos “Spinbutton” que permiten ajustar los umbrales de los dos modos de movimiento.

90

Ilustración 40: Formulario de control del mouse con uso de GTK.Drawingarea.

Posteriormente analiza la forma de interpretación para los movimientos del mouse, para esto se recurre al clásico método de moverse en juegos de primera persona (FPS) de arrastre, esto quiere decir que al mover el mouse, el actor se arrastra como si se tratase del cursor, y al detenerse el mouse este se detiene, lo cual se representa en una persona tocando la superficie del touchpad, arrastrando su dedo en la dirección que desea moverse y levantarlo (DragMode), esto se transformara en un movimiento de la silla hasta donde se

91

levantó el dedo el piloto de la silla. A demás de la forma de interpretación de arrastre, se considera que esta forma de controlar la silla puede ser tediosa si se necesita hacer un viaje largo, para esto se considera una segunda forma de interpretar el movimiento del mouse, que consiste en moverse constantemente en la dirección a la que esta orientado el puntero del mouse (NormalMode).

Para

concretar

esto

se

procede

con

la

construcción

de

la

clase

MouseInputLogic, esta clase según la estructura definida, hereda de la clase InputDeviceLogic, la cual le permite usar varias funciones genéricas de esta. A continuación se muestran los atributos, propiedades y métodos de la clase MouseInputLogic.

Tabla 15: Métodos de la clase MouseInputLogic.

Nombre Métodos públicos OnMouseMoved: object sender, MouseInputLogicEventArgs args Métodos privados MouseControlThread

Tipo devuelto

Descripción

virtual void

Función llamada por el evento de movimiento de mouse en el formulario.

void

Hilo que contiene la lógica del método de control del mouse.

92

Tabla 16: Atributos y propiedades de la clase MouseInputLogic.

Nombre Atributos

Tipo

Descripción

useMouse

bool

mouseControlThread

Thread

mouseControlMode

controlMode

mouseHeading previousMouseHeading

Vector2D Vector2D

dragModeDeadzone

double

dragModeMaxThreshold

double

mousePosition

Vector2D

Variable usada para activar este método de control (inicializa el hilo de control al activarse por property). Hilo de control de los movimientos del mouse. Modo de control del mouse (ninguno, normal, arrastre). Vector de movimiento. Vector de movimiento previo.. Zona muerta para usar el mouse en el modo arrastre. Umbral para usar el mouse en el modo arrastre. Vector que contiene la posición en bruto del mouse.

Propiedades Variable usada para activar este método de control (inicializa el hilo de control al activarse por property).

UseMouse [get, set]

bool

MouseControlMode [get, set]

controlMode

DragModeDeadzone [get, set]

double

DragModeMaxThreshold [get, set]

double

Modo de control del mouse (ninguno, normal, arrastre). Zona muerta para usar el mouse en el modo arrastre. Umbral para usar el mouse en el modo arrastre.

La clase MouseInputLogic funciona de manera similar a KeyboardInputLogic, esta clase se suscribe a los eventos de movimiento de mouse del formulario.

93

Ilustración 41: Código del método manejador del evento de cambio de estado (Toggled) del Checkbox “Usar Mouse” de la clase formulario.

Este método subscribe a la clase MouseInputLogic a los eventos de movimiento del mouse del formulario cuando se activa la casilla (MouseMoved). La clase MouseInputLogic al recibir información de movimiento gatillado por el evento MouseMoved de la clase formulario la almacena para ser procesada posteriormente por el hilo de control del mouse.

94

Ilustración 42: Código del método OnMouseMoved de la clase MouseInputLogic.

La clase MouseInputLogic al igual que la clase KeyboardInputLogic usa un hilo temporizado de control para procesar la lógica de control del mouse, ya que de enviar actualizaciones de movimiento por cada evento de movimiento del formulario podría sobrecargar tanto el procesador del computador como la controladora.

El control del mouse la al ser un control análogo, necesita de zonas muertas y rangos máximos de movimiento para evitar ruidos, etc. En consecuencia para la interpretación del control se analiza la forma de interpretar los comandos, para esto se usa el GTK.DrawingArea como un plano cartesiano bidimensional de

95

superficie cuadrada, al igual que el touchpad y la posición del puntero del mouse sobre este como el vector de la intención de movimiento.

El hilo de control del mouse es encargado de procesar las entradas de datos del mouse previamente almacenadas en variables, este dependiendo del método de control, calcula el vector intención de movimiento usando el umbral y zona muerta adecuados, y si este vector cambia, gatilla el evento MovementIssued al cual esta suscrito la clase WheelchairControl, y este ejecuta la lógica acorde de igual forma que en la fase anterior.

96

Ilustración 43: Código del método MouseControlThread de la clase MouseInputLogic.

Para la transformación de vector de intención de movimiento a órdenes de motores en disposición de tanque, se analiza la lógica para desarrollarlo primero:

Como la silla no puede moverse a la izquierda o la derecha, los movimientos horizontales significaran rotación.

97

Ilustración 44: Plano cartesiano e interpretación de movimiento.

Para llevar el vector de intención de movimiento creado desde el GTK.Drawingarea a acciones de una silla de ruedas con dos motores, se analiza el caso del movimiento de los tanques ya que presenta una distribución de tracción similar a la silla de ruedas de esta tesis, donde se le aplica fuerza al tanque desde sus dos extremos laterales en la misma o diferentes direcciones entregando desplazamiento y rotación.

98

Para nuestro caso estas fuerzas provienen de dos motores y como el control es análogo se permite indicar gradualmente la dirección además de la magnitud de la velocidad con que se desea desplazar.

Para esto el alumno desarrolló una lógica de control representada por la imagen a continuación.

99

Ilustración 45: Plano cartesiano e acción de motores.

Esta lógica separa el plano donde se representa el vector movimiento en el plano por cuadrantes, y posteriormente estos cuadrantes se separan con una

100

recta en diagonal para su estudio(x = y e –x = y). El estudiante observa primero el cuadrante numero uno del plano, donde las intenciones de movimiento son combinadas y se encuentran las ordenes de avanzar hacia delante y doblar al mismo tiempo, bajo estas condiciones la rueda afirmada al motor numero uno necesita girar empujando hacia delante en todo el cuadrante, caso que no se repite para el motor dos, ya que separado por la línea diagonal (donde x = y) se separa la intención de movimiento, en la parte superior de la recta ( y > x ), el piloto espera avanzar mientras la silla rota como movimiento secundario, en este caso ambos motores giran hacia delante variando su potencia, en el segundo caso de la parte inferior de la recta ( x > y ), el piloto desea girar la silla en sentido horario principalmente a la vez que avanza un poco, por lo tanto el motor dos empieza a girar empujando la rueda hacia atrás. Esta situación se repite en los otros cuadrantes intercambiando de roles los motores, por lo cual se llega a un algoritmo que separa en cuadrantes el comportamiento de los motores, por ejemplo en el cuadrante uno, se ve que la potencia del motor uno será el largo de la hipotenusa del vector de desplazamiento en relación a la hipotenusa de un vector imaginario que se extiende hasta el limite del plano cartesiano, caso similar ocurre con el motor dos, pero este varia su potencia en relación al ángulo, para el ángulo PI/4 (45°), en esta situación el motor dos esta detenido y a medida que aumenta este ángulo hasta PI/2 (90°) se aumenta la potencia gradualmente, caso opuesto ocurre a medida que se acerca al ángulo cero, donde se aumenta la potencia gradualmente también pero en el otro

101

sentido, es decir con signo negativo. Lo mismo se repite para el cuadrante tres, solo que con el signo opuesto, finalmente este caso se repite también para los cuadrantes dos y cuatro, pero con los roles de los motores cambiados.

Esta lógica de control es implementada en la clase TankMovementLogic, esta clase es la encargada de recibir los vectores de intención de movimiento (de tipo Vector2D) entregados por la lógica de control de entrada y con estos vectores procesar la lógica de salida, entregando un objeto de tipo Tank que representa al vehículo con los datos de la potencia de los motores necesarios para ejecutar el movimiento deseado. La clase TankMovementLogic no fue detallada en la iteración anterior, ya que esta fue construida en esta etapa y adaptada posteriormente para su uso con el control del teclado.

A continuación se muestran los atributos, las propiedades y los métodos de la clase TankMovementLogic.

Tabla 17: Atributos de la clase TankMovementLogic.

Nombre Atributos

Tipo

Descripción

tank

Tank

Estructura para transportar los datos.

102

Tabla 18: Métodos de la clase TankMovementLogic.

Nombre Métodos públicos Vector2DtoTank: Vector2D vector

Tipo devuelto

Descripción

Tank

Función que transforma el vector de intención de movimiento a movimiento de tanque.

La clase TankMovementLogic esta construida por una función principal, que recibe el Vector2D de intención de movimiento y devuelve la estructura Tank con los datos necesarios para aplicarse a los motores. A continuación se muestra el código de la función Vector2DtoTank.

103

Ilustración 46: Código del método Vector2DtoTank de la clase TankMovementLogic.

A continuación se muestran los atributos y propiedades de la clase contenedora de los datos Tank.

104

Tabla 19: Atributos y propiedades de la clase Tank.

Nombre Atributos enginePower Propiedades EnginePower [get, set]

Tipo

Descripción

double[]

Potencia de los motores 1 y 2.

double[]

Potencia de los motores 1 y 2.

A continuación se presenta una ilustración del formulario del método de control en acción.

105

Ilustración 47: Formulario del método de control del mouse en acción.

106

6.3.1.4 Transición

Posterior a la construcción del algoritmo se procede a realizar pruebas reales en terreno, las cuales dan resultados satisfactorios, moviendo la silla en la dirección deseada, pero aun sin control fino de las potencias, después de esto el alumno procede a calibrar ciertas variables como por ejemplo la potencia a los motores, las zonas muertas y los limites de potencia de las zonas, lo cual lleva finalmente a un control fiable de la silla moviéndose en la dirección deseada con la aceleración deseada.

107

6.3.2 Creación del método de control con Wiimote 6.3.2.1 Iniciación

En esta etapa se espera desarrollar un método de entrada a través de un control inalámbrico Nintendo Wiimote.

Ilustración 48: Control Nintendo Wiimote.

Para la elaboración de este método de control análogo se tendrá que entablar comunicación por medio de Bluetooth con el control, además de analizar las formas de interpretar los comandos enviados a través de este

108

dispositivo. Esta etapa esta acotada solamente al control de la silla a través del control Nintendo Wiimote.

109

6.3.2.2 Elaboración

A continuación se presenta el diagrama de casos de uso confeccionado para esta etapa.

Ilustración 49: Diagrama de casos de uso para fase de control con Wiimote.

110

6.3.2.3 Construcción

El alumno inicia esta etapa buscando la forma de comunicarse con el control Nintendo Wiimote, como el control usa la tecnología inalámbrica Bluetooth, lo primero que el alumno hace es agregar la librería Bluetooth perteneciente

al

monoBOTICS

Framework

[monoBOTICSFramework],

posteriormente para acceder al control se usa la librería Wiimote perteneciente al mismo Framework. Posteriormente se analiza la forma de controlar la silla con el control, este posee varios botones, un control en 4 direcciones no análogo, y tres acelerómetros (uno por cada eje), por lo tanto se decide diseñar un método de control con las flechas del control para moverlo de manera similar al teclado y como segunda forma, usando los acelerómetros inclinando el control en sus ejes.

Este formulario consiste de: 

Los mismos controles para comunicarse con la controladora de la fase anterior, ya que esta funcionalidad se comparte entre métodos de control.



Un “Notebook” que separa en pestañas los diversos métodos de control.



Un “Check box” para activar el método de control con Wiimote.



Un “Check box” para activar el uso de los acelerómetros.

111



Un “Check box” para activar el intercambios de ejes X e Y de los acelerómetros, para poder usar el control de forma horizontal.



Dos “Spinbutton” que permiten ajustar la zonas muerta y el umbral (en radianes) del control Wiimote.



Un “Text box” en donde se puede escribir la dirección física del control Wiimote a conectarse.



Un botón para iniciar o cerrar la conexión con el control Nintendo Wiimote.



Cuatro “Progress bar” que representan las componentes en X y Y del vector movimiento ejecutado.

112

Ilustración 50: Interfaz de usuario para control Wiimote.

Para

interpretar

este

método

de

control

se

construye

la

clase

WiimoteInputLogic, esta es la encargada de procesar todos los datos provenientes del control Nintendo Wiimote y es capaz de entregar los vectores

113

de intención de movimiento al gatillarse el evento MovementIssued. A continuación se muestran los atributos, propiedades y métodos de la clase WiimoteInputLogic.

114

Tabla 20: Atributos y propiedades de la clase WiimoteInputLogic.

Nombre Atributos

Tipo

Descripción

wiimote

Wiimote

wiimoteControlThread

Thread

buttonAccelerationThread

Thread

wiimoteAccHeading

Vector2D

wiimoteBtnHeading

Vector2D

Vector movimiento de los botones.

swapAxis

bool

Variable para usar intercambio de ejes.

UseButtons

bool

useAcelerometers

bool

accDataRecieved

bool

btnData

CWiid.BTN_FLAGS

prevRoll

double

prevPitch

double

buttonAcceleration Propiedades

double

IsConnected [get]

bool

Wiimote [get]

Wiimote

SwapAxis [get, set]

bool

UseAcelerometers [get, set]

bool

Clase Wiimote del framework monoBOTICS. Hilo de control de los acelerómetros. Hilo de control para el movimiento de los botones. Vector movimiento en bruto de los acelerómetros.

Variable para activar la lectura de los botones. Variable para activar la lectura de los acelerómetros. Variable para acusar el recibo de información de los acelerómetros. Información de botones entregada por el Wiimote. Ángulo en radianes de guiñada previa del Wiimote. Ángulo en radianes de inclinación previa del Wiimote. Aceleración de los botones. Consulta si el control Nintendo Wiimote está conectado. Devuelve el objeto Wiimote para poder usar cosas específicas del control. Propiedad para activar la lectura de los acelerómetros. Propiedad para acusar el recibo de información de los acelerómetros.

115

Tabla 21: Métodos de la clase WiimoteInputLogic.

Nombre

Tipo devuelto

Descripción

Métodos públicos Connect

void

Connect: string macAddress

void

Disconnect

void

Función que se conecta a cualquier Nintendo Wiimote y configura variables básicas. Función que se conecta a un Nintendo Wiimote especifico y configura variables básicas. Función para desconectarse del control Nintendo Wiimote.

Métodos privados Función que configura las variables básicas del Wiimote. Hilo que ejecuta la lógica de los botones del control Wiimote.

Setup

void

ButtonAccelerationThread

void

OnWiimoteButtonPress object sender, ButtonPressedEventArgs args

void

Función que maneja el evento de botón presionado del Wiimote y almacena el botón presionado para usarlo en el hilo.

OnWiimoteAccelerometerChanged: object sender, AccelerometerChangedEventArgs args

void

Función que maneja el evento de cambio en los acelerómetros del Wiimote y almacena la inclinación y guiñada.

WiimoteAccControlThread

void

Hilo que ejecuta la lógica de los acelerómetros del control Wiimote.

En esta clase el primer problema a solucionar es la realización de la conexión con el control, ya que este al ser un dispositivo Bluetooth, hay que iniciar la conexión con un dispositivo específico y cerrarla, para esto se crearon las funciones Connect y Disconnect de la clase WiimoteInputLogic.

116

Ilustración 51: Código de los métodos Connect y Disconnect de la clase WiimoteInputLogic.

Una vez probada la conexión y desconexión del control, se abordó la construcción del método de control con los botones de las flechas,

117

Para leer los datos provenientes del Wiimote, la clase WiimoteInputLogic se subscribe a los eventos AccelerometerChanged y ButtonPressed de la clase Wiimote. El evento ButtonPressed es gatillado al presionarse cualquier botón del control, este método almacena la información de los botones para su posterior uso en el hilo de control. A continuación se presenta el código del método que maneja el evento ButtonPressed.

Ilustración 52: Código del método OnWiimoteButtonPress de la clase WiimoteInputLogic.

Si esta activado el uso de los botones en el formulario, se lanza el hilo de control de los botones y al haber un botón presionado se construye un vector aceleración, el cual se multiplica por el vector intención de movimiento, la existencia de este hilo y el vector aceleración permite aceleraciones suaves. De

118

no crearse este hilo y enviar las órdenes a la controladora directamente desde el evento ButtonPressed el movimiento de la silla resultaría bastante brusco debido a la aplicación de torque brusca a los motores. Cabe también destacar que se comparo la información de los botones usando el operador and binario junto al valor de las banderas de los botones (btnFlags), esto permite preguntar si esta presionado más de un botón a la vez permitiendo usar la combinación del botón adelante y el botón izquierda. A continuación se presenta el código del

método

del

hilo

de

control

ButtonAccelrationThread.

119

de

los

botones

del

Wiimote

Ilustración 53: Código del método ButtonAccelerationThread de la clase WiimoteInputLogic.

Además se suscribe al formulario a el evento ButtonPressed con el propósito de asignar los botones + y – del control Wiimote a subir o bajar el valor Power del

120

formulario, para así poder controlar la potencia deseada desde el control sin tener que acceder al computador.

Posteriormente el alumno procedió a desarrollar el método de control usando los acelerómetros del control Nintendo Wiimote, para desarrollar este método de control se uso como base la forma interpretación de los acelerómetros utilizado por varias aplicaciones similares para controlar cosas que se mueven, como por ejemplo un vehículo, el cual consiste en monitorear el cabeceo y guiñada del control, para esto la librería Wiimote ofrece la lectura basada en eventos de estos valores, los cuales obtiene usando los valores de los acelerómetros para calcular el vector en dirección del de fuerza de gravedad, gracias a esto se puede acceder a los valores Roll y Pitch (guiñada y cabeceo) desde los argumentos del evento AccelerometerChanged de la clase Wiimote.

121

Ilustración 54: Control Wiimote, sus acelerómetros y orientación.

Al igual que el método de control del mouse, se procede a almacenar los valores de Roll y Pitch para su uso posterior en un hilo, esto ocurre en la función

manejadora

del

evento

AccelerometerChanged

llamada

OnWiimoteAccelerometerChanged, esto es necesario ya que la frecuencia con la que se gatilla el evento muchas veces es muy superior que la cantidad de veces que es necesario procesar el vector intención de movimiento y disparar el evento

OnMovementIssued.

A

continuación

OnWiimoteAcelerometerChanged.

122

el

código

de

la

función

Ilustración 55: Código del método OnWiimoteAccelerometerChanged de la clase WiimoteInputLogic.

Los datos capturados en el manejador del evento posteriormente son procesados por el hilo WiimoteAccControlThread, hilo que funciona de manera similar al hilo de control del método de control con el mouse. A continuación se presenta el código de la funcion WiimoteAccControlThread.

123

Ilustración 56: Código del método WiimoteAccControlThread perteneciente a la clase WiimoteInputLogic.

Finalmente la clase WheelchairControl se subscribe al evento MovementIssued de la clase WiimoteInputLogic, siendo manejado por la misma función que el método de control del mouse y el teclado, ocasionando que el vector de intención

de

movimiento

resultante

sea

procesado

por

la

clase

TankMovementLogic y los datos sean enviados a la clase controladora, moviendo los motores de la forma deseada.

124

6.3.2.4 Transición

Posterior a la construcción del algoritmo se procede a realizar pruebas reales en terreno, las cuales dan resultados satisfactorios, moviendo la silla en la dirección deseada, pero aun con detalles respecto a la fineza del movimiento o los ángulos máximos para movimiento, por lo tanto estos se agregaron, mejorando la sensibilidad y personalización del control. También se agrego la posibilidad de intercambiar los ejes para usar el control de manera transversal aumentando el nivel de personalización aun mas, después de pruebas queda demostrado que el control de manera transversal es mas intuitivo y fácil para controlar la silla, debido a que se necesita mas fineza para rotar la silla que para avanzar o retroceder.

125

6.3.3 Creación del método de control con reconocimiento de rostro. 6.3.3.1 Iniciación

En esta etapa se espera desarrollar un método de entrada a través de un control que emplea el reconocimiento facial, desde el cual se detectará la posición del rostro desde una imagen obtenida desde una cámara con la librería envoltorio de EmguCV [EmguCV] (que implementa la funcionalidad de la librería OpenCV [OpenCV] de procesamiento de imágenes) y en base a eso se moverá la silla de ruedas.

Ilustración 57: Programa de ejemplo que reconoce el rostro y los ojos de una persona.

126

Para la elaboración de este método de control análogo el programa tendrá que obtener imágenes en tiempo real desde una Webcam que viene montada de fábrica en el netbook, utilizar la librería de procesamiento de imágenes, además de analizar las formas de interpretar la posición del rostro obtenida a través de este dispositivo. Esta etapa esta acotada solamente al control de la silla a través del reconocimiento facial y de manera experimental, ya que es altamente posible que las herramientas usadas en esta tesis no sean las adecuadas para obtener un movimiento fiable de la silla.

127

6.3.3.2 Elaboración

A continuación se presenta el diagrama de casos de uso del método de control con reconocimiento de rostro.

Ilustración 58: Casos de uso de método de control con reconocimiento de rostro.

128

6.3.3.3 Construcción

El alumno inicia esta etapa el análisis de las herramientas disponibles y las diferentes formas en las que puede un ser humano interactuar con la cámara y transformar esa interacción en movimiento, se llega a la conclusión que la forma mas intuitiva y práctica es la detección de posición y tamaño de rostro para ejecutar un movimiento. Se define como rotación de silla la distancia entre el centro del cuadro capturado de manera horizontal y como avance y retroceso de la silla la diferencia de tamaño entre un cuadro calibrado inicial y el cuadro del tamaño del rostro detectado. A continuación se muestra una ilustración del rostro en el cuadro y sus interpretaciones de la intención de movimiento.

129

Ilustración 59: Rostro y movimiento de la silla.

Posterior a esto se crea el formulario del método de control. Este formulario consiste de:

130



Los mismos controles para comunicarse con la controladora de la fase anterior, ya que esta funcionalidad se comparte entre métodos de control.



Un “Notebook” que separa en pestañas los diversos métodos de control.



Un “Check box” para activar el método de control con reconocimiento de rostro.



Un “Check box” para activar la muestra del cuadro capturado por la cámara en el formulario (por razones de rendimiento).



Dos “Check box” para reflejar horizontal o verticalmente la imagen capturada.



Dos “Spinbutton” que permiten ajustar la zonas muerta y el umbral (en radianes) del método de control.



Cuatro “Progress bar” que representan las componentes en X y Y del vector movimiento ejecutado.

A continuación se muestra el formulario creado para este método de control.

131

Ilustración 60: Formulario del método de control con reconocimiento de rostro.

Posterior a esto se analiza la forma de implementación en código y se procede a la creación de la clase CameraInputLogic que hereda de la clase InputDeviceLogic. A continuación los métodos, atributos y propiedades de la clase CameraInputLogic.

132

Tabla 22: Atributos y propiedades de la clase CameraInputLogic.

Nombre Atributos cap

Tipo

Descripción

Capture

haar

HaarCascade

cameraControlThread

Thread

cameraCenter

Rectangle

lastDetectedFace

Rectangle

useCamera

bool

flipHorizontal

bool

flipVertical

bool

showFrames

bool

haarCascadePath

string

memoryStream

MemoryStream

nextFrame grayFrame Propiedades

Image Image

Objeto captura de EmguCV. HaarCascade necesaria para el reconocimiento de rostros. Hilo que procesa las entradas de la cámara. Rectángulo centro de camara. Rectángulo que marca la posición de la última cara detectada. Variable que determina si se usara la lógica de control de la cámara y se correrá el hilo. Variable que determina si se reflejara la imagen proveniente de la cámara horizontalmente. Variable que determina si se reflejara la imagen proveniente de la cámara verticalmente. Variable que determina si se dibujara el cuadro y se disparara el evento para mostrarlo posteriormente. Ruta a haarCascade. Stream de memoria necesario par convertir Emgu.CV.Image a arreglo de bitmap para mostrar el frame. Cuadro capturado. Cuadro en escala de grises para procesar.

UseCamera [get, set]

bool

ShowFrames [get, set]

bool

FlipHorizontal [get, set]

bool

FlipVertical [get, set]

bool

Propiedad que determina si se usara la lógica de control de la cámara y se correrá el hilo. Propiedad que determina si se dibujara el cuadro y se disparara el evento para mostrarlo posteriormente. Propiedad que determina si se reflejara la imagen proveniente de la cámara horizontalmente. Propiedad que determina si se reflejara la imagen proveniente de la cámara verticalmente.

133

Tabla 23: Métodos de la clase CameraInputLogic.

Nombre

Tipo devuelto

Descripción

void

Función que reinicia el centro de la cámara.

Métodos públicos ResetCenter Métodos privados CameraControlThread

void

GetSingleFace: Emgu.CV.Structure.MCvAvgComp[] faces

Rectangle

Hilo que contiene la lógica de control de la cámara. Función que recibe la lista de caras detectadas y elige la mas cercana a la ultima detectada para evitar fantasmas.

Para activar el método de control se utiliza una lógica similar a los métodos anteriores, una propiedad UseCamera al hacerse verdadera, lanza el hilo de control de la cámara. El hilo de control de la cámara es el encargado de ejecutar todos los comandos desde la captura de imagen hasta la entrega de un vector de movimiento, para esto se crea un algoritmo que hace lo siguiente:

1.

Inicializa la cámara, configura variables necesarias.

2.

Inicia ciclo de control mientras UseCamera sea verdadero.

3.

Se captura un cuadro desde la cámara.

4.

Se convierte la imagen a escala de grises.

134

5.

Se llama a la función de EmguCV que ejecuta el reconocimiento de

rostro y devuelve una lista de rectángulos que representan los rostros detectaos en la imagen. 6.

Se llama a una función de la librería CameraInputLogic llamada

GetSingleFace(), la cual recibe una lista de todos los rectángulos de los rostros detectados y selecciona el mas cercano a el rectángulo detectado anteriormente, para evitar rostros fantasmas o rostros dobles, etc. 7.

Se compara la posición horizontal y tamaño del rostro detectado con un

rostro de calibración inicial. 8.

Se crea un vector movimiento a base de las diferencias de distancia y

tamaño del paso anterior. 9.

Se dispara evento MovementIssued con el vector movimiento.

10.

Si la variable showFames esta activada

se dispara el evento

FrameProccesed que contiene el mapa de bits de la imagen procesada (para mostrar la imagen en el formulario). 11.

Descanso.

12.

Volver al paso 2.

A continuación se presenta el código del método CameraControlThread perteneciente a la clase CameraInputLogic.

135

Ilustración 61: Código del método CameraControlThread de la clase CameraInputLogic.

136

La clase CameraInputLogic además contiene un método llamado ResetCenter, este método reinicia el centro de la cámara a la posición actual del rostro detectado, esto es necesario por que entre movimientos a veces se crean desfases del centro.

Finalmente

la

clase

WheelchairControl

al

estar

suscrita

al

evento

MovementIssued de la clase CameraInputLogic, siendo manejado por la misma función que el método de control del Wiimote, el mouse y el teclado, ocasionando que el vector de intención de movimiento resultante sea procesado por la clase TankMovementLogic y los datos sean enviados a la clase controladora,

moviendo

los

motores

137

de

la

forma

deseada.

6.3.3.4 Transición

El algoritmo creado en la etapa anterior resultó ser exitoso en la ejecución correcta de la lógica, pero el rendimiento de este consumía bastantes recursos del sistema, resultando bastante tosco. El origen de esto era el alto costo de procesamiento de capturar una imagen grande y hacer un procesamiento minucioso en el algoritmo de detección de rostro de EmguCV, para esto el alumno procedió a reducir el tamaño del cuadro de captura y a refinar los parámetros recibidos por el método que ejecuta la detección de rostro, acotándolo en tamaño de las posibles caras a detectar, delta de tamaño de rostro entre pasadas, etc.

Las pruebas finales realizadas en esta etapa fueron exitosas dentro de los objetivos establecidos,

como se esperaba el control con este método era

posible, pero bastante tosco de acuerdo a la metodología de control y los recursos de hardware empleados, pero quedó demostrado que el método de control se puede hacer viable con mejores herramientas.

138

7. Conclusiones y/o Recomendaciones

El trabajo presentado en este documento demuestra el uso de las herramientas de programación, desarrollo de software, comunicación con dispositivos, etc hacen posible el movimiento de la silla de ruedas con diferentes métodos de control, el abanico de los posibles controles a usar a futuro es bastante amplio, por lo cual se puede describir el prototipo desarrollado en este proyecto como una silla de ruedas cuyo método de control puede ser la operación de cualquier dispositivo que se conecte a un computador, demostrando que el uso de este último puede agregar una gran capa de abstracción al rubro de soluciones de movilidad.

El resultado del proyecto se puede describir como una aplicación fácil de usar para controlar el movimiento de una silla de ruedas, esta resulto ser confiable con la excepción del último método de control, es decir se cumplió con los requerimientos establecidos al inicio del proyecto.

El proyecto durante su desarrollo fue sujeto de varios replanteamientos y desafíos no expuestos de manera inicial, uno de estos fue el desarrollo de una librería para abstraer los métodos de control y aplicarles lógica, resultando en una librería que puede ser usada a futuro en otros proyectos.

139

En lo que se refiere a las herramientas usadas se puede destacar que la controladora AX2550 es una controladora bastante sólida en su desempeño y comunicación, en lo que respecta a el IDE MonoDevelop, el alumno tuvo una fácil adaptación al IDE y es totalmente recomendable para futuros desarrollos.

En lo que respecta a la silla de ruedas, esta necesitó mantenimiento por el tiempo sin uso, pero aparte de eso resulta ser una buena base para usarse como prototipo para la construcción de otras sillas de ruedas eléctricas.

Como recomendación el alumno sugiere el uso a futuro en otros proyectos de la librería HMIDLogic que implementa las lógicas de control en este proyecto, ya que se puede usar para cualquier vehículo con disposición de tanque y además puede ser adaptado con facilidad a otros tipos de vehículos con otras configuraciones, para así facilitar el desarrollo de aplicaciones con control de tipo Hombre máquina.

140

8. Bibliografía

[Casen]

Encuesta

de

Caracterización

Socioeconómica

Nacional. Disponible en http://www.mideplan.cl/casen/ [ElectricMob]

Sitio Web de la empresa Electric Mobility orientada a soluciones de movilidad. Disponible en http://www.electricmobility.co.uk/

[EmguCV]

Wrapper en C# de la librería OpenCV. Disponible en http://www.emgu.com/wiki/index.php/Main_Page

[Espacenet]

Sitio Web que contiene una gran base de datos de patentes y buscadores. Disponible en http://www.espacenet.com

[Mono]

Framework para desarrollo de .Net en Linux. Disponible en http://www.mono-project.com/Main_Page

[monoBOTICSFramework] Framework para el desarrollo de software con control de hardware de tipo robótico en Mono. Disponible en

141

[MonoDevelop]

IDE para desarrollar en C Sharp en Linux. Disponible en http://monodevelop.com/

[OpenCV]

Librería abierta de herramiento procesamiento de imagen en C. Disponible en http://opencv.willowgarage.com/wiki/

[Permobil]

Sitio Web de la empresa Permobil orientada a soluciones de movilidad. Disponible en http://www.permobil.com

[PGDrives]

Sitio Web de la empresa PG Drives Technology orientada la manufactura de controladores para sillas de ruedas motorizadas. Disponible en http://www.pgdt.com/

[Pride]

Sitio Web de la empresa Pride orientada a soluciones de movilidad. Disponible en http://www.pridemobility.com

[RoboteQ]

Sitio Web de la empresa RoboteQ orientada a soluciones

electrónicas

individuos. Disponible en http://www.roboteq.com/

142

para

empresas

e

[SpinLife]

Sitio Web de la empresa SpinLife orientada a soluciones de movilidad. Disponible en http://www.spinlife.com

[Wheelchair]

Sitio Web de información de equipo medico y recursos. Disponible en http://wheelchair.ca/drives.php

143

Get in touch

Social

© Copyright 2013 - 2024 MYDOKUMENT.COM - All rights reserved.