Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
Hola,
Tengo la brújula digital CMPS03 conectada a mi Robonova-I, quiero hacer un programa que haga lo siguiente:
- Al encender, toma la posición de referencia, RUMBO
- El robot permanece siempre quieto mientras vea que su posición no ha variado
- Si el robot detecta que esta en otra posición (porque alguien lo ha cambiado de posición) deberá girar por el camino más corto a su posición original y al llegar ahi pararse.
Esto que parece tan sencillo no me funciona siempre, solo en determinados rangos de valores. La brujula me devuelve un numero entre 0 y 255. Las operaciones con el byte de la posición son circulares, es decir 255+1=0 y 0-1=255, etc.
Os dejo mi código (programo en RoboBasic): RUMBO es el valor que toma al ppo y el de referencia; BRUJULA es el valor actual de la posición.
I2CDATA=RUMBO //al encender leo el valor de la posicion que tengo y lo guardo como referencia
MAIN:
I2CDATA=BRUJULA //leo el valor de la brujula
BRUJULA=BRUJULA-RUMBO //considero mi RUMBO=0, por lo tanto desplazo el valor actual de la brujula (ver imagen)
IF BRUJULA>245 OR BRUJULA<10 THEN GOTO SALTO //245-10 es el margen en el que considero q el robot esta en su posicion (ver imagen)
IF BRUJULA<127 THEN GOSUB GIRO_IZDA //aqui elijo qué camino es el mas rápido
IF BRUJULA>127 THEN GOSUB GIRO_DCHA //por la izda o dcha; 127=255/2
SALTO: GOTO MAIN
Lo de elegir el camino más corto no llega a hacerlo bien del todo. Y se vuelve loco si la posición inicial, RUMBO, está cerca del valor 0, como si no tuviese en cuenta el margen de 245-10. Le he dado mil vueltas y he probado montones de cosas y he variado muchas veces el código pero siempre se comporta igual. A mi sobre el papel me funciona, pero en la ejecución no.
¿Me podéis echar una mano?
No conozco ese RoboBasic, pero puede ser que estés teniendo problemas con los signos de las variables. Deberías declarar BRUJULA como signed de 16 bits y RUMBO como unsigned de 8 bits, esto es así porque RUMBO variará entre [0,255] mientras que BRUJULA irá desde [-255,255].
Ahora mirando un poco, he encontrado un manual de referencia de RoboBasic y pone que no soporta operaciones con signos negativos. También pone que BYTE es 8 bits y INTEGER 16bits. Tendrás que buscar una forma alternativa de hacerlo solo con número positivos. Para verlo, simplemente cambia las flechas de tus dibujos, imagina que la azul es la roja y roja la azul... saldrían un número negativo.
Además te recomendaría que usases una tolerancia al movimiento, de forma que si por ejemplo la posición ha cambiado menos que la tolerancia, el robot no haga nada. Esto es porque, imagino, que el robot hará un movimiento mínimo de X pasos de la brújula, si por ejemplo X es 3 y estamos actualmente desviados 2 pasos, quiere decir que se quedaría temblando ya que está fuera del rumbo, pero si se mueve también estará fuera del rumbo, porque no es capaz de girar solo 2 pasos de brújula. He visto que tienes algo así ya puesto, pero asegurate.
Suerte.
Ahora mirando un poco, he encontrado un manual de referencia de RoboBasic y pone que no soporta operaciones con signos negativos. También pone que BYTE es 8 bits y INTEGER 16bits. Tendrás que buscar una forma alternativa de hacerlo solo con número positivos. Para verlo, simplemente cambia las flechas de tus dibujos, imagina que la azul es la roja y roja la azul... saldrían un número negativo.
Como dije antes el byte es circular, así que en caso de salir un numero negativo X, pasa a ser X+256, y entonces estaríamos en el segundo caso cuando BRUJULA>127
Lo de la tolerancia que comentas es lo que pongo yo como margen 245-10, si RUMBO y BRUJULA están en ese rango el robot no se mueve.
Hola, he encontrado el error. 💡
El codigo está bien, lo que va mal es la brujula que no reparte los 256 valores del byte proporcionalmente a lo largo de los 360º de la circunferencia completa. Por eso asumir que el 127 es el valor opuesto a 0 es un error.
Ahora tendre que encontrar la forma o de distribuir equilibradamente un byte en los 360º o hacer otro tipo de algoritmo que solvente esto.
Pues eso no es lo que pone en su hoja de características. ¿Efectuaste un reseteo y una nueva calibración? Puede ser también que esté estropeada y, en ese caso, yo no me fiaría un pelo de ella.
Un saludo