From 0d3c52e49dc34344f335fd6d7b214592723cbc93 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Tue, 7 Jun 2022 23:46:48 +0200 Subject: implemented obstacle detection --- robot/errcatch.c | 3 +++ robot/hypervisor.c | 25 ++++++++++++++++++------- robot/hypervisor.h | 15 +++++++++++++-- robot/io.c | 51 ++++++++++++++++++++++++++------------------------- robot/io.h | 6 +++--- robot/mode_dirc.c | 11 +---------- robot/sercomm.c | 16 ---------------- 7 files changed, 64 insertions(+), 63 deletions(-) (limited to 'robot') diff --git a/robot/errcatch.c b/robot/errcatch.c index 17c96fa..9aeae9e 100644 --- a/robot/errcatch.c +++ b/robot/errcatch.c @@ -16,6 +16,9 @@ void w2_errcatch_handle_error(w2_s_error *error) { case W2_E_WARN_UNCAUGHT_ERROR: { break; } + case W2_E_WARN_OBSTACLE_DETECTED: break; + case W2_E_CRIT_OBSTACLE_STUCK: break; + case W2_E_WARN_MODE_HISTORY_BUFFER_IOB: break; default: { g_w2_error_uncaught = true; #ifdef W2_SIM diff --git a/robot/hypervisor.c b/robot/hypervisor.c index 2a6120b..8b9d727 100644 --- a/robot/hypervisor.c +++ b/robot/hypervisor.c @@ -14,6 +14,9 @@ unsigned long g_w2_hypervisor_ema_io_ms = 0; unsigned long g_w2_hypervisor_ema_mode_ms = 0; uint64_t g_w2_hypervisor_timers[W2_HYPERVISOR_TIMER_COUNT] = {0}; +uint64_t g_w2_hypervisor_ms_timer_offset = 0; +uint64_t g_w2_hypervisor_ms_timer_cpu_ticks = 0; + unsigned int g_w2_ping_ms = 0; uint8_t g_w2_ping_id = 0; bool g_w2_ping_received = true; @@ -26,17 +29,17 @@ void w2_hypervisor_main() { if (DBG_ENABLE_CYCLEINFO) siminfo("cycle start\n"); #endif - g_w2_hypervisor_uptime_ms += get_ms(); - time_reset(); + g_w2_hypervisor_uptime_ms += w2_get_ms(); + w2_time_reset(); w2_sercomm_main(); - unsigned long sercomm_time = get_ms(); + unsigned long sercomm_time = w2_get_ms(); w2_errcatch_main(); - unsigned long errcatch_time = get_ms() - sercomm_time; - // w2_io_main(); - unsigned long io_time = get_ms() - errcatch_time; + unsigned long errcatch_time = w2_get_ms() - sercomm_time; + w2_io_main(); + unsigned long io_time = w2_get_ms() - errcatch_time; w2_modes_main(); - unsigned long mode_time = get_ms() - io_time; + unsigned long mode_time = w2_get_ms() - io_time; // calculate exponential moving averages g_w2_hypervisor_ema_sercomm_ms = @@ -58,6 +61,14 @@ void w2_hypervisor_main() { g_w2_hypervisor_cycles++; } +uint64_t w2_get_ms() { + return ticks_to_microseconds(get_ticks() - g_w2_hypervisor_ms_timer_offset) / 1e3; +} + +void w2_time_reset() { + g_w2_hypervisor_ms_timer_offset = get_ticks(); +} + void w2_hypervisor_time_start(uint8_t label) { g_w2_hypervisor_timers[label] = g_w2_hypervisor_uptime_ms; } diff --git a/robot/hypervisor.h b/robot/hypervisor.h index 4b1ed9b..fe9dbea 100644 --- a/robot/hypervisor.h +++ b/robot/hypervisor.h @@ -7,9 +7,10 @@ #include "../shared/bool.h" /** amount of parallel timers */ -#define W2_HYPERVISOR_TIMER_COUNT (1) +#define W2_HYPERVISOR_TIMER_COUNT 2 -#define W2_TIMER_PING (0) +#define W2_TIMER_PING 0 +#define W2_TIMER_OBJECT_DETECTION 1 extern uint64_t g_w2_hypervisor_cycles; extern uint64_t g_w2_hypervisor_uptime_ms; @@ -32,7 +33,17 @@ extern bool g_w2_connected; */ void w2_hypervisor_main(); +/** + * pololu's `get_ms()` estimates run time by only adding the CPU time taken up + * by pololu library functions. this function uses the `get_ticks()` function + * to calculate elapsed milliseconds, and should therefore be more accurate. + */ +uint64_t w2_get_ms(); +/** reset time returned by `w2_get_ms()` */ +void w2_time_reset(); + /** start timer with label `label` */ void w2_hypervisor_time_start(uint8_t label); /** stop timer with label `label` */ uint64_t w2_hypervisor_time_end(uint8_t label); + diff --git a/robot/io.c b/robot/io.c index 8b34aba..9e0eae1 100644 --- a/robot/io.c +++ b/robot/io.c @@ -1,35 +1,36 @@ -#include - -#include "../shared/consts.h" #include "io.h" +#include "../shared/consts.h" +#include "../shared/errcatch.h" #include "modes.h" #include "orangutan_shim.h" +#include "hypervisor.h" + +#include -w2_s_io_all g_w2_io; +bool g_w2_io_object_detected = false; void w2_io_main() { - g_w2_io.button[0].pressed = get_single_debounced_button_press(BUTTON_A); - g_w2_io.button[1].pressed = get_single_debounced_button_press(BUTTON_B); - g_w2_io.button[2].pressed = get_single_debounced_button_press(BUTTON_C); - g_w2_io.button[3].pressed = get_single_debounced_button_press(TOP_BUTTON); - g_w2_io.button[4].pressed = get_single_debounced_button_press(BOTTOM_BUTTON); + unsigned int front_distance = analog_read(W2_FRONT_SENSOR_PIN); - unsigned int sensor_values[5]; - qtr_read(sensor_values, QTR_EMITTERS_ON); - for (int i = 0; i < 5; i++) g_w2_io.qtr[i].range = sensor_values[i]; + if (g_w2_mode_history[g_w2_mode_history_index] == W2_M_HALT) return; - // TODO average voltage over mutiple samples sensor - g_w2_io.battery.charge_level = analog_read(W2_BATTERY_PIN); - g_w2_io.front_distance.detection = analog_read(W2_FRONT_SENSOR_PIN); - g_w2_io.side_distance.detection = analog_read(W2_SIDE_SENSOR_PIN); + if (!g_w2_io_object_detected && front_distance >= W2_IO_DISTANCE_CLOSE_THRESHOLD) { + g_w2_io_object_detected = true; + w2_hypervisor_time_start(W2_TIMER_OBJECT_DETECTION); + w2_errcatch_throw(W2_E_WARN_OBSTACLE_DETECTED); + } - set_motors(g_w2_io.motor_left.speed, g_w2_io.motor_right.speed); - red_led(g_w2_io.led_red.on); - green_led(g_w2_io.led_green.on); + if (g_w2_io_object_detected) { + if (front_distance <= W2_IO_DISTANCE_FAR_THRESHOLD) { + w2_errcatch_throw(0x55); + g_w2_io_object_detected = false; + } + if (w2_hypervisor_time_end(W2_TIMER_OBJECT_DETECTION) >= W2_IO_DISTANCE_TOO_CLOSE_TIMEOUT) { + w2_errcatch_throw(0x56); + w2_errcatch_throw(W2_E_CRIT_OBSTACLE_STUCK); + } + set_motors(0, 0); + } - // TODO don't do this every cycle - char text_copy[17]; - memcpy((char *)text_copy, g_w2_io.lcd.text, 16); - text_copy[16] = 0x00; - print(text_copy); -}; + return; +} diff --git a/robot/io.h b/robot/io.h index 64ce293..14ffb38 100644 --- a/robot/io.h +++ b/robot/io.h @@ -1,11 +1,11 @@ #pragma once +#include "../shared/bool.h" + /** @file io.h */ -#include "../shared/io.h" +extern bool g_w2_io_object_detected; /** @brief i/o module main */ void w2_io_main(); -/** @brief global struct containing all i/o */ -extern w2_s_io_all g_w2_io; diff --git a/robot/mode_dirc.c b/robot/mode_dirc.c index 7021721..429d1e1 100644 --- a/robot/mode_dirc.c +++ b/robot/mode_dirc.c @@ -10,16 +10,7 @@ int16_t g_w2_mode_dirc_motor_l = 0; int16_t g_w2_mode_dirc_motor_r = 0; -uint8_t g_w2_mode_dirc_power = 100; void w2_mode_dirc() { - if (g_w2_connected == 1) - g_w2_mode_dirc_power = 100; - else - g_w2_mode_dirc_power = W2_MAX(0, g_w2_mode_dirc_power - 1); - - if (g_w2_mode_dirc_power == 0) w2_modes_call(W2_M_HALT); - - set_motors(g_w2_mode_dirc_motor_l * g_w2_mode_dirc_power / 100, - g_w2_mode_dirc_motor_r * g_w2_mode_dirc_power / 100); + set_motors(g_w2_mode_dirc_motor_l, g_w2_mode_dirc_motor_r); } diff --git a/robot/sercomm.c b/robot/sercomm.c index f52eb7e..efad449 100644 --- a/robot/sercomm.c +++ b/robot/sercomm.c @@ -139,22 +139,6 @@ void w2_cmd_sres_rx(w2_s_bin *data) { void w2_cmd_mcfg_rx(w2_s_bin *data) { return; } -void w2_cmd_sens_rx(w2_s_bin *data) { - W2_CREATE_MSG_BIN(w2_s_cmd_sens_tx, res_msg, res_bin); - res_msg->opcode = W2_CMD_SENS | W2_CMDDIR_TX; - memcpy((uint8_t *)&res_msg->io, (uint8_t *)&g_w2_io, sizeof(w2_s_io_all)); - - for (int i = 0; i < 5; i++) w2_bin_repl_hton16(&res_msg->io.qtr[i].range); - w2_bin_repl_hton16(&res_msg->io.front_distance.detection); - w2_bin_repl_hton16(&res_msg->io.side_distance.detection); - w2_bin_repl_hton16(&res_msg->io.battery.charge_level); - w2_bin_repl_hton16((uint16_t *)&res_msg->io.motor_left.speed); - w2_bin_repl_hton16((uint16_t *)&res_msg->io.motor_right.speed); - - w2_sercomm_append_msg(res_bin); - free(res_bin); -} - void w2_cmd_info_rx(w2_s_bin *data) { W2_CREATE_MSG_BIN(w2_s_cmd_info_tx, res_msg, res_bin); res_msg->opcode = W2_CMD_INFO | W2_CMDDIR_TX; -- cgit v1.2.3