From 43f91324965ed76e44d6fca868c9f5a8f760d194 Mon Sep 17 00:00:00 2001 From: Roman Baur Date: Tue, 24 Aug 2021 08:54:03 +0000 Subject: [PATCH] Added warmup state --- setup.cfg | 2 +- src/raepy/vacmod/ipc/ipc.c | 3 ++ src/raepy/vacmod/statemachine/statemachine.c | 53 ++++++++++++++++--- src/raepy/vacmod/statemachine/statemachine.h | 2 +- src/raepy/vacmod/vacmod | Bin 15808 -> 19976 bytes src/raepy/vacmod/vacuummodule.py | 8 +++ 6 files changed, 59 insertions(+), 9 deletions(-) diff --git a/setup.cfg b/setup.cfg index 03bcb5a..c254e58 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,7 +1,7 @@ [metadata] # replace with your username: name = raepy -version = 0.0.25 +version = 0.0.26 author = Roman Baur author_email = romanbaur.engineering@gmail.com description = Software drivers for the robot autonomy effector diff --git a/src/raepy/vacmod/ipc/ipc.c b/src/raepy/vacmod/ipc/ipc.c index 56a30ab..88af5c4 100644 --- a/src/raepy/vacmod/ipc/ipc.c +++ b/src/raepy/vacmod/ipc/ipc.c @@ -31,6 +31,9 @@ void * read_cmd_from_pipe(){ void write_state_to_pipe(state_t state){ char statestr[10]; switch(state) { + case WARMUP: + strcpy(statestr, "WARMUP"); + break; case OFF: strcpy(statestr, "OFF"); break; diff --git a/src/raepy/vacmod/statemachine/statemachine.c b/src/raepy/vacmod/statemachine/statemachine.c index 46c7780..08e734d 100644 --- a/src/raepy/vacmod/statemachine/statemachine.c +++ b/src/raepy/vacmod/statemachine/statemachine.c @@ -3,6 +3,7 @@ #include #include "../ipc/ipc.h" #include +#include static state_t state = OFF; static state_t prev_state = INIT; @@ -14,8 +15,13 @@ static int diff2 = 0; static int maxdiff = 0; static int maxdiffprev = 0; static int lost_cnt = 0; +static int warumup_cnt = 0; + +char current_cmd[20]; void transition_function(int * encoder_count, int * diff1){ + strcpy(current_cmd, get_actual_cmd()); + maxdiff = max_encoder_count - *encoder_count; diff2 = *diff1 - prevdiff; prevdiff = *diff1; @@ -24,8 +30,34 @@ void transition_function(int * encoder_count, int * diff1){ printf("enc-cnt: %d\t diff1: %d \t diff2: %d \t %d\n", *encoder_count, *diff1, diff2, (maxdiff) ); switch(state) { + + + case WARMUP: + printf("Warmup Counter: %d\n",warumup_cnt); + if (actual_cmd_is("START")) { + state = ON; + warumup_cnt = 0; + return; + } + if (actual_cmd_is("STOP")) { + state = OFF; + warumup_cnt = 0; + return; + } + if (warumup_cnt > 120*5) { + state = OFF; + warumup_cnt = 0; + return; + } + break; + case OFF: + if (actual_cmd_is("WARMUP")) + { + state = WARMUP; + return; + } if (actual_cmd_is("START")) { state = ON; return; @@ -42,7 +74,7 @@ void transition_function(int * encoder_count, int * diff1){ max_encoder_count = *encoder_count; } - if (maxdiff >= 4) { + if (maxdiff + maxdiffprev >= 5 || maxdiff >= 4) { state = SUCKED; } break; @@ -50,7 +82,7 @@ void transition_function(int * encoder_count, int * diff1){ case SUCKED: if (actual_cmd_is("STOP")) { state = OFF; - } else if (maxdiff <= 0 && abs(*diff1) < 1) { + } else if (maxdiff <= 1 && abs(*diff1) < 1) { state = LOST; } break; @@ -75,6 +107,16 @@ void transition_function(int * encoder_count, int * diff1){ void output_function() { switch(state) { + case WARMUP: + if (prev_state != state) { + write_state_to_pipe(state); + printf("WARMUP\n"); + write_pwm(100); + } + + warumup_cnt++; + break; + case OFF: if (prev_state != state) { max_encoder_count = 0; @@ -95,7 +137,6 @@ void output_function() { case SUCKED: if (prev_state != state) { - write_state_to_pipe(state); printf("SUCKED\n"); } @@ -118,8 +159,6 @@ void state_machine(int * encoder_count, int * diff1){ } int actual_cmd_is(char * statestr) { - char state[20]; - strcpy(state, get_actual_cmd()); - strtok(state, "\n"); - return (strcmp(state,statestr) == 0); + strtok(current_cmd, "\n"); + return (strcmp(current_cmd,statestr) == 0); } \ No newline at end of file diff --git a/src/raepy/vacmod/statemachine/statemachine.h b/src/raepy/vacmod/statemachine/statemachine.h index b7d269d..28f1900 100644 --- a/src/raepy/vacmod/statemachine/statemachine.h +++ b/src/raepy/vacmod/statemachine/statemachine.h @@ -1,6 +1,6 @@ #ifndef STATEMACHINE_H #define STATEMACHINE_H -typedef enum {INIT, OFF, ON, SUCKED, LOST} state_t; +typedef enum {INIT, WARMUP, OFF, ON, SUCKED, LOST} state_t; static int max_encoder_count; diff --git a/src/raepy/vacmod/vacmod b/src/raepy/vacmod/vacmod index 0450168083d83ad2d7874affd43b1b3274b4f7a5..19445c0de81afc0a45ce38ebf40355886d623ff8 100755 GIT binary patch literal 19976 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