diff options
author | HoodieJeansJordans <104365411+HoodieJeansJordans@users.noreply.github.com> | 2022-06-05 13:21:09 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-05 13:21:09 +0200 |
commit | bc283424c699effcfa84816c609ca7f00ed5259a (patch) | |
tree | ff67ced022120ae05997c1b1f3a49db992e4fcbf /robot | |
parent | 5692ca8c65f5f5617d6987b610e425a32c0d8e1d (diff) | |
parent | 38d71eb97dbd8f895ed483128b332f018a5ae1d4 (diff) |
Merge branch 'lonkaars:master' into master
Diffstat (limited to 'robot')
-rw-r--r-- | robot/- | 0 | ||||
-rw-r--r-- | robot/errcatch.h | 2 | ||||
-rw-r--r-- | robot/hypervisor.c | 21 | ||||
-rw-r--r-- | robot/hypervisor.h | 10 | ||||
-rw-r--r-- | robot/io.h | 8 | ||||
-rw-r--r-- | robot/main.h | 2 | ||||
-rw-r--r-- | robot/makefile | 17 | ||||
-rw-r--r-- | robot/mode_chrg.h | 2 | ||||
-rw-r--r-- | robot/mode_dirc.h | 2 | ||||
-rw-r--r-- | robot/mode_grid.h | 2 | ||||
-rw-r--r-- | robot/mode_halt.h | 2 | ||||
-rw-r--r-- | robot/mode_lcal.h | 2 | ||||
-rw-r--r-- | robot/mode_maze.h | 2 | ||||
-rw-r--r-- | robot/mode_scal.h | 2 | ||||
-rw-r--r-- | robot/mode_spin.h | 2 | ||||
-rw-r--r-- | robot/modes.h | 2 | ||||
-rw-r--r-- | robot/orangutan_shim.h | 2 | ||||
-rw-r--r-- | robot/readme.md | 49 | ||||
-rw-r--r-- | robot/sercomm.c | 56 | ||||
-rw-r--r-- | robot/sercomm.h | 2 | ||||
-rw-r--r-- | robot/setup.c | 3 | ||||
-rw-r--r-- | robot/setup.h | 2 | ||||
-rw-r--r-- | robot/sim.c | 16 | ||||
-rw-r--r-- | robot/sim.h | 2 | ||||
-rw-r--r-- | robot/tests/dirc.bin | bin | 6 -> 7 bytes | |||
-rw-r--r-- | robot/tests/ping.bin | bin | 3 -> 4 bytes |
26 files changed, 153 insertions, 57 deletions
diff --git a/robot/errcatch.h b/robot/errcatch.h index 836da1b..add4ece 100644 --- a/robot/errcatch.h +++ b/robot/errcatch.h @@ -1,5 +1,7 @@ #pragma once +/** @file errcatch.h */ + #include <stdint.h> #include "../shared/consts.h" diff --git a/robot/hypervisor.c b/robot/hypervisor.c index 0baa406..1fd3ac2 100644 --- a/robot/hypervisor.c +++ b/robot/hypervisor.c @@ -6,12 +6,13 @@ #include "orangutan_shim.h" #include "sercomm.h" -uint64_t g_w2_hypervisor_cycles = 0; -uint64_t g_w2_hypervisor_uptime_ms = 0; -unsigned long g_w2_hypervisor_ema_sercomm_ms = 0; -unsigned long g_w2_hypervisor_ema_errcatch_ms = 0; -unsigned long g_w2_hypervisor_ema_io_ms = 0; -unsigned long g_w2_hypervisor_ema_mode_ms = 0; +uint64_t g_w2_hypervisor_cycles = 0; +uint64_t g_w2_hypervisor_uptime_ms = 0; +unsigned long g_w2_hypervisor_ema_sercomm_ms = 0; +unsigned long g_w2_hypervisor_ema_errcatch_ms = 0; +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}; void w2_hypervisor_main() { #ifdef W2_SIM @@ -51,3 +52,11 @@ void w2_hypervisor_main() { g_w2_hypervisor_cycles++; } + +void w2_hypervisor_time_start(uint8_t label) { + g_w2_hypervisor_timers[label] = g_w2_hypervisor_uptime_ms; +} + +uint64_t w2_hypervisor_time_end(uint8_t label) { + return g_w2_hypervisor_uptime_ms - g_w2_hypervisor_timers[label]; +} diff --git a/robot/hypervisor.h b/robot/hypervisor.h index 5008c8f..589d324 100644 --- a/robot/hypervisor.h +++ b/robot/hypervisor.h @@ -1,7 +1,12 @@ #pragma once +/** @file hypervisor.h */ + #include <stdint.h> +/** amount of parallel timers */ +#define W2_HYPERVISOR_TIMER_COUNT (1) + extern uint64_t g_w2_hypervisor_cycles; extern uint64_t g_w2_hypervisor_uptime_ms; @@ -16,3 +21,8 @@ extern unsigned long g_w2_hypervisor_ema_mode_ms; * stores global variables and controls when other modules run */ void w2_hypervisor_main(); + +/** 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); @@ -1,9 +1,11 @@ #pragma once -#include "../shared/protocol.h" +/** @file io.h */ -/** i/o module main */ +#include "../shared/io.h" + +/** @brief i/o module main */ void w2_io_main(); -/** global struct containing all i/o */ +/** @brief global struct containing all i/o */ extern w2_s_io_all g_w2_io; diff --git a/robot/main.h b/robot/main.h index 5b0a1b2..58f849b 100644 --- a/robot/main.h +++ b/robot/main.h @@ -1,4 +1,6 @@ #pragma once +/** @file main.h */ + /** program entrypoint */ int main(); diff --git a/robot/makefile b/robot/makefile index 4039ae3..f65552a 100644 --- a/robot/makefile +++ b/robot/makefile @@ -6,18 +6,19 @@ MCU ?= atmega168 AVRDUDE_DEVICE ?= m168 PORT ?= /dev/ttyACM0 +# SIM = true CFLAGS=-g -Wall $(DEVICE_SPECIFIC_CFLAGS) -Os LDFLAGS=-Wl,-gc-sections -Wl,-relax -all: $(if $(SIM), a.out, out.hex) +include ../shared/os.mk +all: $(if $(SIM), $(TARGET), out.hex) SOURCES := $(filter-out sim.c, $(wildcard *.c)) HEADERS := $(filter-out sim.h, $(wildcard *.h)) include ../shared/makefile # simulation -# SIM = true CFLAGS += $(if $(SIM), -DW2_SIM, -mcall-prologues -mmcu=$(MCU)) LDFLAGS += $(if $(SIM), , -lpololu_$(DEVICE)) PREFIX := $(if $(SIM), , avr-) @@ -30,20 +31,16 @@ AVRDUDE=avrdude CC=$(PREFIX)gcc OBJ2HEX=$(PREFIX)objcopy -# debug build info string -BUILD_STR=$(shell git update-index -q --refresh; git describe --tags --dirty='*' --broken='x' | cut -c1-20) -CFLAGS += -DW2_BUILD_STR=\"$(BUILD_STR)\" - clean:: - rm -f *.o out.hex a.out + rm -f *.o out.hex $(TARGET) -a.out: $(OBJECTS) +$(TARGET): $(OBJECTS) $(CC) $(OBJECTS) $(CFLAGS) $(LDFLAGS) .o: $(CC) -c $(CFLAGS) $< -out.hex: a.out +out.hex: $(TARGET) $(OBJ2HEX) -R .eeprom -O ihex $< $@ $(info build $(BUILD_STR) complete) @@ -57,4 +54,4 @@ format: clang-tidy --fix-errors $(SOURCES) $(HEADERS) compile_commands: clean - bear -- make + compiledb make diff --git a/robot/mode_chrg.h b/robot/mode_chrg.h index d9b5cc0..a870e58 100644 --- a/robot/mode_chrg.h +++ b/robot/mode_chrg.h @@ -1,5 +1,7 @@ #pragma once +/** @file mode_chrg.h */ + /** * charge station mode * diff --git a/robot/mode_dirc.h b/robot/mode_dirc.h index 5b9bbf4..12c967a 100644 --- a/robot/mode_dirc.h +++ b/robot/mode_dirc.h @@ -1,5 +1,7 @@ #pragma once +/** @file mode_dirc.h */ + #include <stdint.h> extern int16_t g_w2_mode_dirc_motor_l; diff --git a/robot/mode_grid.h b/robot/mode_grid.h index fcf9100..55093ad 100644 --- a/robot/mode_grid.h +++ b/robot/mode_grid.h @@ -1,5 +1,7 @@ #pragma once +/** @file mode_grid.h */ + /** * warehouse mode * diff --git a/robot/mode_halt.h b/robot/mode_halt.h index d92905e..b5ac11f 100644 --- a/robot/mode_halt.h +++ b/robot/mode_halt.h @@ -1,5 +1,7 @@ #pragma once +/** @file mode_halt.h */ + /** * halt (emergency) mode * diff --git a/robot/mode_lcal.h b/robot/mode_lcal.h index dd373f0..5a43701 100644 --- a/robot/mode_lcal.h +++ b/robot/mode_lcal.h @@ -1,5 +1,7 @@ #pragma once +/** @file mode_lcal.h */ + /** * calibration mode * diff --git a/robot/mode_maze.h b/robot/mode_maze.h index b97ad5c..6d481c1 100644 --- a/robot/mode_maze.h +++ b/robot/mode_maze.h @@ -1,5 +1,7 @@ #pragma once +/** @file mode_maze.h */ + /** * maze mode * diff --git a/robot/mode_scal.h b/robot/mode_scal.h index 4f1f04d..c427d4b 100644 --- a/robot/mode_scal.h +++ b/robot/mode_scal.h @@ -1,5 +1,7 @@ #pragma once +/** @file mode_scal.h */ + /** * sensor calibration mode * diff --git a/robot/mode_spin.h b/robot/mode_spin.h index 926137e..1f721dc 100644 --- a/robot/mode_spin.h +++ b/robot/mode_spin.h @@ -1,5 +1,7 @@ #pragma once +/** @file mode_spin.h */ + /** * wet floor simulation * diff --git a/robot/modes.h b/robot/modes.h index 3423a0f..122be4a 100644 --- a/robot/modes.h +++ b/robot/modes.h @@ -1,5 +1,7 @@ #pragma once +/** @file modes.h */ + #include "../shared/consts.h" #include "mode_chrg.h" diff --git a/robot/orangutan_shim.h b/robot/orangutan_shim.h index 10420bd..cbb0995 100644 --- a/robot/orangutan_shim.h +++ b/robot/orangutan_shim.h @@ -1,5 +1,7 @@ #pragma once +/** @file orangutan_shim.h */ + #ifdef W2_SIM #include "sim.h" #else diff --git a/robot/readme.md b/robot/readme.md index b27c06f..e6ab294 100644 --- a/robot/readme.md +++ b/robot/readme.md @@ -39,10 +39,15 @@ organizational and form more of a software 'skeleton', while the 'maze' and ┌────────┴───────┐┌─────────┴────────┐┌────────┴─────────┐┌─────┴──────┐ │ Error handling ││ I/O Read & Write ││ PC communication ││ Mode logic │ └────────────────┘└──────────────────┘└──────────────────┘└─────┬──────┘ - ┌──────────┬──────────────┬───────────────┤ - ┌───┴──┐┌──────┴────┐┌────────┴───────┐┌──────┴──────┐ - *modes* -> │ Maze ││ Warehouse ││ Emergency stop ││ Calibration │ - └──────┘└───────────┘└────────────────┘└─────────────┘ + │ + Maze ─┤ + Warehouse ─┤ + Emergency stop ─┤ + *logic modes* -> Line finding ─┤ + Charge station ─┤ + Direct control ─┤ + Wet floor ─┤ + Sensor calibration ─┘ ``` this diagram roughly describes how different parts of the robot software are @@ -64,7 +69,7 @@ what they're supposed to do: |emergency stop |`mode_halt `|may 31|Fiona| stops all execution until emergency mode is reset by software or user| |line finding |`mode_lcal `|may 31|Fiona| find line by turning on own axis if lost| |charge station |`mode_chrg `|may 31|Fiona| go to the charging station transition in the grid, and continue until a black circle is found| -|direct control |`mode_dirc `|may 31|Loek| respond to [DIRC](../protocol.md#DIRC) commands| +|direct control |`mode_dirc `|done|Loek| respond to [DIRC](../protocol.md#DIRC) commands| |wet floor |`mode_spin `|may 31|Fiona| spin uncontrollably (simulating wet floor??)| |sensor calibration|`mode_scal `|may 31|Jorn & Abdullaahi| calibrate underside uv sensors| @@ -72,15 +77,15 @@ what they're supposed to do: this list will probably get updated from time to time: -- modules shouldn't create any global state variables, they should use `static` - variables instead. -- modules are run cyclically, so they shouldn't take more than +- logic modules shouldn't create any global state variables if possible, they + should use `static` variables instead +- logic modules are run cyclically, so they shouldn't take more than `W2_MAX_MODULE_CYCLE_MS` to execute (this is an arbitrary number, and may be - changed). + changed) - documentation comments should follow the [javadoc-style doxygen format](https://wiki.scilab.org/Doxygen%20documentation%20Examples) and be - placed in header (.h) files if possible. this only applies to public members - (e.g. no local variables or module-internal code). + placed in header (.h) files. this only applies to public members (e.g. no + local variables or module-internal code) - code style is mostly handled by `clang-format` and `clang-tidy`, but you should still follow these naming conventions (`<angle brackets>` indicate placeholders): @@ -93,32 +98,30 @@ this list will probably get updated from time to time: |enum|`w2_e_<name>`|`w2_e_errorcodes`; `w2_e_serial_commands`| this again only applies to public members. local variables should still have - short descriptive names, but shouldn't be prefixed with `w2_*`. + short descriptive names, but shouldn't be prefixed with `w2_*` - arbitrary numbers should be aliased to `#define` statements or `enum`s if - part of a series. + part of a series - general constants should be placed in `consts.h` - don't import `<pololu/orangutan.h>` directly, instead use `"orangutan_shim.h"` to keep code compatible with the simulator - don't use `<stdbool.h>`, instead use `"../shared/protocol.h"`. this makes sure that `bool` values are equal to `uint8_t`. they're functionally - identical. + identical ## todo global todo: -- [ ] start robot in calibration mode - [ ] assume robot starts in maze -- [ ] 'crosswalk' transition detection in seperate file (used by grid and maze - mode) +- [ ] 'crosswalk' transition detection and line following in seperate file + (used by grid, maze, and charge mode) - [ ] client software architecture -- [x] mode 'return' buffer -- [x] clear global timer at start of cycle instead of just for mode selection - module (for last ping time measurement) -- [ ] calibrate (line-detecting) light sensors in setup.c, or manually by - placing the robot and pressing a button (maybe make this a seperate mode) -- [ ] create labeled timer functions like nodejs `console.time()` and +- [ ] enter mode_scal by placing the robot on a white surface and pressing a + button +- [x] create labeled timer functions like nodejs `console.time()` and `console.timeEnd()` (use for serial read timeout constraint) +- [x] `serial_parse` doesn't properly handle escaped `0xff` bytes in listen + mode ### hypervisor diff --git a/robot/sercomm.c b/robot/sercomm.c index 2736030..07c4bd8 100644 --- a/robot/sercomm.c +++ b/robot/sercomm.c @@ -3,6 +3,7 @@ #include "../shared/bin.h" #include "../shared/serial_parse.h" +#include "errcatch.h" #include "hypervisor.h" #include "io.h" #include "mode_dirc.h" @@ -25,16 +26,22 @@ void w2_sercomm_main() { #endif // read and parse data while (serial_get_received_bytes() != g_w2_serial_buffer_index) { - w2_serial_parse(g_w2_serial_buffer[g_w2_serial_buffer_index]); + if (!w2_serial_parse(g_w2_serial_buffer[g_w2_serial_buffer_index])) + w2_errcatch_throw(W2_E_WARN_SERIAL_NOISY); g_w2_serial_buffer_index = (g_w2_serial_buffer_index + 1) % W2_SERIAL_READ_BUFFER_SIZE; } // send data while (g_w2_sercomm_offset != g_w2_sercomm_index) { - w2_s_bin *data = g_w2_sercomm_buffer[g_w2_sercomm_offset]; - char *data_cast = malloc(data->bytes); - memcpy(data_cast, data->data, data->bytes); - serial_send(data_cast, data->bytes); + w2_s_bin *data = g_w2_sercomm_buffer[g_w2_sercomm_offset]; +#ifdef W2_SIM + w2_sim_print_serial(data); +#endif + serial_send("\xff", 1); + for (uint8_t i = 0; i < data->bytes; i++) { + uint8_t byte = data->data[i]; + byte == 0xff ? serial_send("\xff\xff", 2) : serial_send((char *)&byte, 1); + } g_w2_sercomm_offset = (g_w2_sercomm_offset + 1) % W2_SERCOMM_BUFFER_SIZE; } } @@ -51,6 +58,26 @@ void w2_sercomm_append_msg(w2_s_bin *data) { g_w2_sercomm_index = next_index; } +void w2_cmd_handler(uint8_t data[W2_SERIAL_READ_BUFFER_SIZE], uint8_t data_length) { + w2_s_bin *copy = w2_bin_s_alloc(data_length, data); + void (*handler)(w2_s_bin *) = g_w2_cmd_handlers[data[0]]; + + if (handler == NULL) { +#ifdef W2_SIM + // TODO throw warning + simwarn("unknown serial message with code 0x%02x\n", data[0]); +#endif + w2_errcatch_throw(W2_E_WARN_SERIAL_NOISY); + } else { +#ifdef W2_SIM + w2_sim_print_serial(copy); +#endif + handler(copy); + } + + free(copy); +} + void w2_cmd_ping_rx(w2_s_bin *data) { w2_s_cmd_ping_rx *message = malloc(w2_cmd_sizeof(data->data, data->bytes)); memcpy(message, data->data, data->bytes); @@ -90,7 +117,24 @@ void w2_cmd_cord_rx(w2_s_bin *data) { return; } void w2_cmd_bomd_rx(w2_s_bin *data) { return; } -void w2_cmd_sres_rx(w2_s_bin *data) { return; } +void w2_cmd_sres_rx(w2_s_bin *data) { + w2_s_cmd_sres_rx *message = malloc(w2_cmd_sizeof(data->data, data->bytes)); + memcpy(message, data->data, data->bytes); + + switch (message->type) { + case W2_CMD_SRES_RX_TYPE_REINITGS: { + // TODO: soft-reset + break; + } + case W2_CMD_SRES_RX_TYPE_PREVMODE: { + w2_modes_call(W2_M_PREV); + break; + } + default: { + w2_errcatch_throw(W2_E_WARN_SERIAL_NOISY); + } + } +} void w2_cmd_mcfg_rx(w2_s_bin *data) { return; } diff --git a/robot/sercomm.h b/robot/sercomm.h index b1f69c7..13625c0 100644 --- a/robot/sercomm.h +++ b/robot/sercomm.h @@ -1,5 +1,7 @@ #pragma once +/** @file sercomm.h */ + #include "../shared/bin.h" #include "../shared/consts.h" #include "../shared/protocol.h" diff --git a/robot/setup.c b/robot/setup.c index 2c426a3..95b201e 100644 --- a/robot/setup.c +++ b/robot/setup.c @@ -28,7 +28,8 @@ void w2_setup_main() { time_reset(); // set default mode - w2_modes_swap(W2_M_HALT); + w2_modes_swap(W2_M_MAZE); + w2_modes_call(W2_M_HALT); // indicate startup done play("L50 c>c"); diff --git a/robot/setup.h b/robot/setup.h index 17ac78d..450e102 100644 --- a/robot/setup.h +++ b/robot/setup.h @@ -1,5 +1,7 @@ #pragma once +/** @file setup.h */ + /** * runs once at startup, plays beep when setup finishes * diff --git a/robot/sim.c b/robot/sim.c index 0f1c7e6..6283694 100644 --- a/robot/sim.c +++ b/robot/sim.c @@ -2,8 +2,8 @@ #include <time.h> #include <string.h> #include <stdint.h> -#include <termios.h> #include <unistd.h> +#include <termios.h> #include "sim.h" #include "../shared/consts.h" @@ -38,15 +38,20 @@ static const char* const W2_CMD_DIRECTIONS[] = { void time_reset() { simprintfunc("time_reset", ""); +#ifdef W2_HOST_LINUX clock_gettime(CLOCK_MONOTONIC, &reference_time); +#endif } unsigned long get_ms() { simprintfunc("get_ms", ""); +#ifdef W2_HOST_LINUX struct timespec elapsed; clock_gettime(CLOCK_MONOTONIC, &elapsed); return ((elapsed.tv_sec * 1000) + (elapsed.tv_nsec / 1000000)) - ((reference_time.tv_sec * 1000) + (reference_time.tv_nsec / 1000000)); +#endif + return 0; } void red_led(unsigned char on) { @@ -76,16 +81,11 @@ void serial_send(char* message, unsigned int length) { return; } - if (DBG_ENABLE_PRINTFUNC) simprintfunc("serial_send", "<see below>, %u", length); - - if (!DBG_ENABLE_SERIAL) return; - w2_s_bin *bin = w2_bin_s_alloc(length, (uint8_t*) message); - w2_sim_print_serial(bin); - free(bin); + if (DBG_ENABLE_PRINTFUNC) simprintfunc("serial_send", "<%u byte%s>", length, length == 1 ? "" : "s"); } void serial_receive_ring(char* buffer, unsigned char size) { - simprintfunc("serial_receive_ring", "0x%016lx, %u", (unsigned long) buffer, size); + simprintfunc("serial_receive_ring", "0x%016lx, %u", (uint64_t) buffer, size); } unsigned char serial_get_received_bytes() { diff --git a/robot/sim.h b/robot/sim.h index ab1cd77..249414d 100644 --- a/robot/sim.h +++ b/robot/sim.h @@ -1,5 +1,7 @@ #pragma once +/** @file sim.h */ + #include <stdio.h> #include <stdlib.h> #include <unistd.h> diff --git a/robot/tests/dirc.bin b/robot/tests/dirc.bin Binary files differindex 1aea35c..8d141e8 100644 --- a/robot/tests/dirc.bin +++ b/robot/tests/dirc.bin diff --git a/robot/tests/ping.bin b/robot/tests/ping.bin Binary files differindex 456804e..2bbe45e 100644 --- a/robot/tests/ping.bin +++ b/robot/tests/ping.bin |