summaryrefslogtreecommitdiff
path: root/robot
diff options
context:
space:
mode:
Diffstat (limited to 'robot')
-rw-r--r--robot/-0
-rw-r--r--robot/errcatch.h2
-rw-r--r--robot/hypervisor.c21
-rw-r--r--robot/hypervisor.h10
-rw-r--r--robot/io.h8
-rw-r--r--robot/main.h2
-rw-r--r--robot/makefile17
-rw-r--r--robot/mode_chrg.h2
-rw-r--r--robot/mode_dirc.h2
-rw-r--r--robot/mode_grid.h2
-rw-r--r--robot/mode_halt.h2
-rw-r--r--robot/mode_lcal.h2
-rw-r--r--robot/mode_maze.h2
-rw-r--r--robot/mode_scal.h2
-rw-r--r--robot/mode_spin.h2
-rw-r--r--robot/modes.h2
-rw-r--r--robot/orangutan_shim.h2
-rw-r--r--robot/readme.md49
-rw-r--r--robot/sercomm.c56
-rw-r--r--robot/sercomm.h2
-rw-r--r--robot/setup.c3
-rw-r--r--robot/setup.h2
-rw-r--r--robot/sim.c16
-rw-r--r--robot/sim.h2
-rw-r--r--robot/tests/dirc.binbin6 -> 7 bytes
-rw-r--r--robot/tests/ping.binbin3 -> 4 bytes
26 files changed, 153 insertions, 57 deletions
diff --git a/robot/- b/robot/-
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/robot/-
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);
diff --git a/robot/io.h b/robot/io.h
index 3d91799..64ce293 100644
--- a/robot/io.h
+++ b/robot/io.h
@@ -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
index 1aea35c..8d141e8 100644
--- a/robot/tests/dirc.bin
+++ b/robot/tests/dirc.bin
Binary files differ
diff --git a/robot/tests/ping.bin b/robot/tests/ping.bin
index 456804e..2bbe45e 100644
--- a/robot/tests/ping.bin
+++ b/robot/tests/ping.bin
Binary files differ