summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/commands.h2
-rw-r--r--client/i18n/en_us.h3
-rw-r--r--client/main.c19
-rw-r--r--client/main.h1
-rw-r--r--client/serial.c11
-rw-r--r--client/setup.c7
-rw-r--r--client/ui.c6
-rw-r--r--client/ui_dirc.c2
-rw-r--r--protocol.md8
-rw-r--r--robot/hypervisor.h13
-rw-r--r--robot/makefile2
-rw-r--r--robot/sercomm.c43
-rw-r--r--robot/sim.h2
-rw-r--r--shared/consts.h5
-rw-r--r--shared/errcatch.h2
15 files changed, 103 insertions, 23 deletions
diff --git a/client/commands.h b/client/commands.h
index 5a12424..02ae313 100644
--- a/client/commands.h
+++ b/client/commands.h
@@ -4,6 +4,8 @@
#include "../shared/modes.h"
#include "serial.h"
+void w2_send_bin(w2_s_bin *data);
+
void w2_send_info();
void w2_send_ping();
void w2_send_mode(w2_e_mode mode);
diff --git a/client/i18n/en_us.h b/client/i18n/en_us.h
index 206e689..5547db5 100644
--- a/client/i18n/en_us.h
+++ b/client/i18n/en_us.h
@@ -1,5 +1,8 @@
#pragma once
+#define W2_UI_CLI_USAGE "usage: %s <serial port>\n"
+#define W2_UI_CLI_SERPORT_ERROR "serial port open fout\n"
+#define W2_UI_CLI_INITSCR_FAIL "ncurses initscr() failed\n"
#define W2_UI_CONN_STAT_CONNECTED "connected"
#define W2_UI_CONN_STAT_DISCONNECTED "disconnected"
#define W2_UI_CONN_STAT_PING "ping"
diff --git a/client/main.c b/client/main.c
index 8fe6d8e..00f686a 100644
--- a/client/main.c
+++ b/client/main.c
@@ -1,10 +1,15 @@
#include "main.h"
#include "../shared/errcatch.h"
+#include "../shared/consts.h"
#include "serial.h"
#include "setup.h"
#include "ui.h"
+#include "time.h"
+#include "commands.h"
-w2_s_client_state g_w2_state;
+w2_s_client_state g_w2_state = {
+ .ping_received = true
+};
int main(int argc, char **argv) {
w2_client_setup(argc, argv);
@@ -13,5 +18,17 @@ int main(int argc, char **argv) {
w2_serial_main();
w2_errcatch_main();
w2_ui_main();
+
+ if (!g_w2_state.ping_received && w2_timer_end(W2_TIMER_PING) > W2_PING_TIMEOUT) {
+ g_w2_state.ping_timeout = true;
+ g_w2_state.connected = false;
+ w2_errcatch_throw(W2_E_WARN_PING_TIMEOUT);
+ }
+
+ if ((g_w2_state.ping_received && w2_timer_end(W2_TIMER_PING) > W2_PING_FREQUENCY) || g_w2_state.ping_timeout) {
+ g_w2_state.ping_timeout = false;
+ g_w2_state.ping_received = false;
+ w2_send_ping();
+ }
}
}
diff --git a/client/main.h b/client/main.h
index e581b3c..cc4c728 100644
--- a/client/main.h
+++ b/client/main.h
@@ -6,6 +6,7 @@ typedef struct {
unsigned int ping;
uint8_t ping_id;
bool ping_received;
+ bool ping_timeout;
bool connected;
uint8_t battery_level;
diff --git a/client/serial.c b/client/serial.c
index e42bc0b..743fe76 100644
--- a/client/serial.c
+++ b/client/serial.c
@@ -5,19 +5,27 @@
#include "main.h"
#include "serial.h"
#include "time.h"
+#include "commands.h"
void w2_serial_main() {
int temp;
while ((temp = w2_serial_read()) != -1) w2_serial_parse(temp);
}
-void w2_cmd_ping_tx(w2_s_bin *data) {
+void w2_cmd_ping_rx(w2_s_bin *data) {
W2_CAST_BIN(w2_s_cmd_ping_tx, data, cast);
if (g_w2_state.ping_received) return;
if (g_w2_state.ping_id != cast->id) return;
+
g_w2_state.ping = w2_timer_end(W2_TIMER_PING);
g_w2_state.ping_received = true;
+ g_w2_state.ping_timeout = false;
+ g_w2_state.connected = true;
+}
+
+void w2_cmd_ping_tx(w2_s_bin *data) {
+ w2_send_bin(data);
}
void w2_cmd_expt_tx(w2_s_bin *data) {}
@@ -33,7 +41,6 @@ void w2_cmd_info_tx(w2_s_bin *data) {
memcpy(&g_w2_state.info, data->data, sizeof(w2_s_cmd_info_tx));
}
-void w2_cmd_ping_rx(w2_s_bin *data) { return; }
void w2_cmd_mode_rx(w2_s_bin *data) { return; }
void w2_cmd_sped_rx(w2_s_bin *data) { return; }
void w2_cmd_dirc_rx(w2_s_bin *data) { return; }
diff --git a/client/setup.c b/client/setup.c
index 50395e0..fd37c13 100644
--- a/client/setup.c
+++ b/client/setup.c
@@ -17,17 +17,17 @@ uint8_t g_w2_endianness;
void w2_client_setup(int argc, char **argv) {
if (argc < 2) {
- printf("usage: %s <serial port>\n", argv[0]);
+ printf(W2_UI_CLI_USAGE, argv[0]);
exit(1);
}
if (w2_serial_open(argv[1]) == 0) {
- printf("serial port open fout\n");
+ printf(W2_UI_CLI_SERPORT_ERROR);
exit(1);
}
if ((g_w2_ui_win = initscr()) == NULL) {
- printf("ncurses initscr() failed\n");
+ printf(W2_UI_CLI_INITSCR_FAIL);
exit(1);
}
noecho();
@@ -38,7 +38,6 @@ void w2_client_setup(int argc, char **argv) {
w2_cmd_setup_handlers();
w2_send_info();
- w2_send_ping();
// check endianness
g_w2_endianness = *_ptest;
diff --git a/client/ui.c b/client/ui.c
index e6e73f0..1cde52f 100644
--- a/client/ui.c
+++ b/client/ui.c
@@ -35,6 +35,12 @@ void w2_ui_paint() {
void w2_ui_paint_statusbar() {
char temp[g_w2_ui_width];
+
+ for (unsigned int i = 0; i < g_w2_ui_width; i++) temp[i] = ' ';
+ mvaddnstr(0, 0, temp, g_w2_ui_width);
+ mvaddnstr(1, 0, temp, g_w2_ui_width);
+ mvaddnstr(2, 0, temp, g_w2_ui_width);
+
sprintf(temp, "%s, %ims %s",
g_w2_state.connected ? W2_UI_CONN_STAT_CONNECTED : W2_UI_CONN_STAT_DISCONNECTED,
g_w2_state.ping, W2_UI_CONN_STAT_PING);
diff --git a/client/ui_dirc.c b/client/ui_dirc.c
index 2965169..675913a 100644
--- a/client/ui_dirc.c
+++ b/client/ui_dirc.c
@@ -104,6 +104,6 @@ void w2_ui_dirc(bool first) {
drive_l += drive_r * W2_DIRC_STP;
drive_r += drive_l * W2_DIRC_STP;
- w2_send_dirc(drive_l, drive_r);
+ // w2_send_dirc(drive_l, drive_r);
w2_ui_dirc_paint(drive_l, drive_r);
}
diff --git a/protocol.md b/protocol.md
index 95ef835..9c45f56 100644
--- a/protocol.md
+++ b/protocol.md
@@ -66,9 +66,11 @@ in *both* the robot and client code `r <-- c` is referred to as `rx` and `r
|`uint8_t`|opcode (`0x00 + 0` or `0x00 + 1`)|
|`uint8_t`|ping id|
-**ping** sends back an identical message either way with the direction bit
-toggled. _ping id_ is a random 8-bit value that makes sure the same ping
-doesn't keep bouncing back and forth indefinitely.
+**ping** sends back an identical message either way with the **same** direction
+bit. _ping id_ is a random 8-bit value that identifies the ping message. this
+is the only command that makes either the robot or client send a message with
+an opcode not matching the respective sender. the direction bit indicates which
+device initiated the ping message.
### EXPT
diff --git a/robot/hypervisor.h b/robot/hypervisor.h
index 589d324..59398c6 100644
--- a/robot/hypervisor.h
+++ b/robot/hypervisor.h
@@ -4,9 +4,13 @@
#include <stdint.h>
+#include "../shared/bool.h"
+
/** amount of parallel timers */
#define W2_HYPERVISOR_TIMER_COUNT (1)
+#define W2_TIMER_PING (0)
+
extern uint64_t g_w2_hypervisor_cycles;
extern uint64_t g_w2_hypervisor_uptime_ms;
@@ -15,10 +19,16 @@ extern unsigned long g_w2_hypervisor_ema_errcatch_ms;
extern unsigned long g_w2_hypervisor_ema_io_ms;
extern unsigned long g_w2_hypervisor_ema_mode_ms;
+extern unsigned int g_w2_ping_ms;
+extern uint8_t g_w2_ping_id;
+extern bool g_w2_ping_received;
+extern bool g_w2_ping_timeout;
+extern bool g_w2_connected;
+
/**
* backbone of all other modules
*
- * stores global variables and controls when other modules run
+ * stores global state and controls when other modules run
*/
void w2_hypervisor_main();
@@ -26,3 +36,4 @@ void w2_hypervisor_main();
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/makefile b/robot/makefile
index 11e8509..ed700ae 100644
--- a/robot/makefile
+++ b/robot/makefile
@@ -6,7 +6,7 @@ MCU ?= atmega168
AVRDUDE_DEVICE ?= m168
PORT ?= /dev/ttyACM0
-SIM = true
+# SIM = true
CFLAGS=-g -Wall $(DEVICE_SPECIFIC_CFLAGS) -Os
LDFLAGS=-Wl,-gc-sections -Wl,-relax
diff --git a/robot/sercomm.c b/robot/sercomm.c
index 519568d..afde48a 100644
--- a/robot/sercomm.c
+++ b/robot/sercomm.c
@@ -20,6 +20,12 @@ char g_w2_serial_buffer[W2_SERIAL_READ_BUFFER_SIZE] = {0};
uint8_t g_w2_serial_buffer_index = 0;
uint8_t g_w2_serial_buffer_head = 0;
+unsigned int g_w2_ping_ms = 0;
+uint8_t g_w2_ping_id = 0;
+bool g_w2_ping_received = true;
+bool g_w2_ping_timeout = false;
+bool g_w2_connected = false;
+
void w2_sercomm_main() {
#ifdef W2_SIM
simprintfunc("w2_sercomm_main", "");
@@ -31,6 +37,27 @@ void w2_sercomm_main() {
g_w2_serial_buffer_index = (g_w2_serial_buffer_index + 1) % W2_SERIAL_READ_BUFFER_SIZE;
}
+ // check time-out
+ if (!g_w2_ping_received && w2_hypervisor_time_end(W2_TIMER_PING) > W2_PING_TIMEOUT) {
+ g_w2_ping_timeout = true;
+ w2_errcatch_throw(W2_E_WARN_PING_TIMEOUT);
+ }
+ // send ping every W2_TIMER_PING ms
+ if ((g_w2_ping_received && w2_hypervisor_time_end(W2_TIMER_PING) > 1000) || g_w2_ping_timeout) {
+ g_w2_ping_timeout = false;
+ g_w2_ping_received = false;
+ g_w2_ping_id = (uint8_t) rand();
+
+ W2_CREATE_MSG_BIN(w2_s_cmd_ping_tx, msg, bin);
+ msg->opcode = W2_CMD_PING | W2_CMDDIR_TX;
+ msg->id = g_w2_ping_id;
+
+ w2_sercomm_append_msg(bin);
+ free(bin);
+
+ w2_hypervisor_time_start(W2_TIMER_PING);
+ }
+
// send data
while (g_w2_sercomm_offset != g_w2_sercomm_index) {
w2_s_bin *data = g_w2_sercomm_buffer[g_w2_sercomm_offset];
@@ -62,15 +89,14 @@ void w2_sercomm_append_msg(w2_s_bin *data) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warray-bounds"
-void w2_cmd_ping_rx(w2_s_bin *data) {
- W2_CAST_BIN(w2_s_cmd_ping_rx, data, req);
-
- W2_CREATE_MSG_BIN(w2_s_cmd_ping_tx, res_msg, res_bin);
- res_msg->opcode = W2_CMD_PING | W2_CMDDIR_TX;
- res_msg->id = req->id;
+void w2_cmd_ping_tx(w2_s_bin *data) {
+ g_w2_ping_ms = w2_hypervisor_time_end(W2_TIMER_PING);
+ g_w2_ping_received = true;
+ g_w2_ping_timeout = false;
+}
- w2_sercomm_append_msg(res_bin);
- free(res_bin);
+void w2_cmd_ping_rx(w2_s_bin *data) {
+ w2_sercomm_append_msg(data);
}
void w2_cmd_mode_rx(w2_s_bin *data) {
@@ -150,7 +176,6 @@ void w2_cmd_cled_rx(w2_s_bin *data) { return; }
#pragma GCC diagnostic pop
-void w2_cmd_ping_tx(w2_s_bin *data) {}
void w2_cmd_expt_tx(w2_s_bin *data) {}
void w2_cmd_mode_tx(w2_s_bin *data) {}
void w2_cmd_cord_tx(w2_s_bin *data) {}
diff --git a/robot/sim.h b/robot/sim.h
index 9d73585..14f0f74 100644
--- a/robot/sim.h
+++ b/robot/sim.h
@@ -16,7 +16,7 @@
#define DBG_ENABLE_CYCLEINFO (0)
#define DBG_ENABLE_SERIAL (1)
-#define DBG_CYCLE_DELAY (100e3)
+#define DBG_CYCLE_DELAY (1e3)
#define DBG_MAX_CYCLES (-1)
// debug print options
diff --git a/shared/consts.h b/shared/consts.h
index cdd96b3..3f792b4 100644
--- a/shared/consts.h
+++ b/shared/consts.h
@@ -30,6 +30,11 @@
/** exponential moving average new measurement weight (double 0-1) */
#define W2_EMA_WEIGHT (0.10)
+/** minimal time between pings */
+#define W2_PING_FREQUENCY (1e3)
+/** max time between ping and answer */
+#define W2_PING_TIMEOUT (5e3)
+
/** front-facing distance sensor pinout */
#define W2_FRONT_SENSOR_PIN 5
/** battery voltage sensor pinout */
diff --git a/shared/errcatch.h b/shared/errcatch.h
index 7f298c1..a56bc00 100644
--- a/shared/errcatch.h
+++ b/shared/errcatch.h
@@ -52,6 +52,8 @@ typedef enum {
W2_E_WARN_SERIAL_NOISY = 0x09 | W2_E_TYPE_WARN,
/** mode history index out of bounds */
W2_E_WARN_MODE_HISTORY_BUFFER_IOB = 0x0a | W2_E_TYPE_WARN,
+ /** ping timeout reached */
+ W2_E_WARN_PING_TIMEOUT = 0x0b | W2_E_TYPE_WARN,
} w2_e_errorcode;
/**