Robótica basada en el comportamiento

0

Estaba leyendo este libro que habla sobre la robótica basada en el comportamiento. Ya que usa IC para la programación en algún punto, usa una función llamada startprocess (). Después de mirar a través de la web, no pude encontrar cómo esta función podría traducirse en la C simple. O cómo implementar un comportamiento simple dos en C

Así que aquí hay dos comportamientos simples, con su sistema de arbitraje. En realidad, entiendo muy bien cómo puede funcionar esto. Lo que no tiene sentido es cómo iniciaría el comportamiento en C

//Cruise Behavior
int cru_trans = 0; //Translational rotation velocity
int cru_rot = 0; //Rotational velocity
int cru_act = 0; //Cruise active flag
int cru_def_vel = 100; //Default speed

void cruise(void){
    while(1){
        cru_act =1; //Cruise Always wants control
        cru_trans = cru_def_vel; //Standard Velocity
        cru_rot = 0; //Don't rotate
    }
}

int av_trans = 0; //avoid translational velocity
int av_rot = 0; // avoid rotational velocity
int av_act = 0; // avoid active flag
int av_def_trans = 100; // avoid default translational velocity
int av_def_rot = 50; //avoid default rotational velocity

void avoid(void){
    int ir_hit = 0; //Local variable for obstacle detection

    while(1){
        ir_hit = ir_detect(); //ir_detect returns which ir sensor sees something
        if(ir_hit == 0){ //No detection
            av_act = 0;
        }
        else if(ir_hit == 3){ //Detection Both side
            av_act = 1;
            av_rot = av_def_rot; //Arbitrary rotate left
            av_trans = 0;
        }
        else{
            av_act = 1; //Avoid wants control
            av_trans = 0; //Don't move forward
            av_rot = av_def_rot; //Rotate away
        }
    }
}

int mot_trans = 0;
int mot_rot = 0;

void motors(){
    while(1){
        drive(mot_trans,mot_rot);
    }

void arbitrate(){
    while(1){
        if(av_act){
            mot_trans = av_trans;
            mot_rot = av_rot;
        }
        else if(cru_act){
            mot_trans = cru_trans;
            mot_rot = cru_rot;
        }
        else{
            mot_trans = 0;
            mot_rot = 0;
        }
    }
}

void main(){
    start_process(avoid());
    start_process(cruise());
    start_process(motors());
    start_process(arbitrate());
}
    
pregunta Hawk_08

2 respuestas

4

La función start_process no forma parte de ninguna biblioteca estándar de C en la que pueda pensar. Creo que solo se está utilizando para ilustrar la creación de un hilo que varía entre Linux, Windows, etc. En un microcontrolador integrado, normalmente es mejor usar una máquina de estado y / o interrupciones para garantizar que el código se ejecute de manera oportuna.

En este caso, eliminaría while (1) de cada función para que cada una realice una única iteración y luego mueva el bucle a la función main de esta manera:

void main() {
    ir_hit = 0;
    while (1) {
        avoid();
        cruise();
        motors();
        arbitrate();
    }
}

Tenga en cuenta que hacer esto significa que se llamará a cada función desde el inicio en cada una de las interacciones, así que moví la inicialización de ir_hit al inicio de main para que solo se realice una vez y sea necesario cambiarla a una variable global.

También tenga cuidado al usar este método de cualquier llamada a función que bloquee la ejecución por un tiempo prolongado. Por ejemplo, si drive tuvo algún tipo de demora prolongada durante la conducción del motor, es posible que se requiera usar un temporizador para realizar un seguimiento de cuándo se debe encender y apagar el motor. En general, parece un ejemplo de pseudocódigo que requerirá un poco de trabajo adicional para implementarlo.

    
respondido por el PeterJ
0

La biblioteca de IC que está utilizando admite tareas múltiples.

La función start_process () crea una tarea. Las tareas son rutas de ejecución independientes que no se devuelven (en este caso, las funciones con los bucles while (1)). Un programador de round-robin ejecuta tareas para un valor predeterminado de 5 "tics" cada uno antes de cambiar al siguiente. Un solo tick es el tiempo que toma (predeterminado 1 ms) para que un contador (controlado por la biblioteca) produzca una interrupción.

Con un programador de round-robin, todas las tareas se ejecutan durante el mismo tiempo. Esto contrasta con una implementación normal de superloop en la que las tareas se ejecutan durante el tiempo que demore. Por ejemplo, si el proceso de toma de decisiones de su robot toma 1 segundo, el resto de las tareas (por ejemplo, el movimiento) tendrá que esperar tanto, mientras que con esta configuración de multitarea tomará un múltiplo de 5 tics, es decir, 5 ms.

Hay formas de crear, destruir y hacer varias otras cosas a las tareas creadas. Debe leer la documentación de multitarea que se encuentra aquí .

    
respondido por el Atuos

Lea otras preguntas en las etiquetas