Sun, 11 Dec 2011 17:34:40 +0100
finished live CLI, BB firmware improvements and fixes
blackbox/main.c | file | annotate | diff | comparison | revisions | |
slotUI/SlotCli.py | file | annotate | diff | comparison | revisions | |
slotUI/freeslot.py | file | annotate | diff | comparison | revisions |
--- a/blackbox/main.c Sun Dec 11 13:54:14 2011 +0100 +++ b/blackbox/main.c Sun Dec 11 17:34:40 2011 +0100 @@ -102,7 +102,7 @@ 16 stopbit */ - /* PITLANE STATUS DEFINITION + /* PITLANE/TRACKSWITCH STATUS DEFINITION 1 = AA 2 = AB 3 = BB @@ -113,6 +113,8 @@ #define STARTSTOP 0b1000000000000001 void decode_responsewire(void) { + // ATTENTION: THIS IS CALLED IN AN INTERRUPT, KEEP AS SHORT AS POSSIBLE + uint16_t data = responsewire_data; // first check if start + stopbit are set // todo future: unsure but last bit doesnt get set?! @@ -123,27 +125,32 @@ } */ // now extract the car id, track change status - uint8_t car = ((data >> 1) & 0b111); - uint8_t status = ((data >> 4) & 0b1111); - uint8_t sender = ((data >> 8) & 0b1111); - uint8_t type = ((data >> 12) & 0b111); + data >>= 1; + uint8_t car = (data & 0b111); + data >>= 3; + uint8_t status = (data & 0b1111); + data >>= 4; + uint8_t sender = (data & 0b1111); + data >>= 4; + uint8_t type = (data & 0b111); if (type == 4) { // pitlane response if (status == 5) slot[car].canrefuel = 1; if (status == 6) for (data=0; data<MAX_SLOTS; data++) slot[data].canrefuel = 0; } RS232_puts("RW:"); - itoa(car, s, 16); - RS232_puts(s); + RS232_putc(car + '0'); RS232_putc(':'); - itoa(type, s, 16); - RS232_puts(s); + RS232_putc(type + '0'); RS232_putc(':'); itoa(sender, s, 16); RS232_puts(s); RS232_putc(':'); itoa(status, s, 16); RS232_puts(s); + RS232_putc(':'); + ultoa(sysclk.value, s, 16); + RS232_puts(s); RS232_putc('\n'); } @@ -429,6 +436,8 @@ slot[i].seccnt = 0; slot[i].accel = 15; // full acceleration per default - TODO slot[i].canrefuel = 0; + slot[i].lap_time_start.value = 0; + slot[i].lap_time.value = 0; } sysclk.value = 0; } @@ -468,10 +477,7 @@ if (slot[car0-1].lap_time_start.value != 0) { slot[car0-1].lap_time.value = diff.value; slot[car0-1].laps++; - RS232_putc('L'); - RS232_putc(':'); - RS232_putc('B'); - RS232_putc(':'); + RS232_puts("L:3:"); // 3 = BB itoa(slot[car0-1].laps, s, 16); RS232_puts(s); RS232_putc(':'); @@ -479,6 +485,9 @@ RS232_putc(':'); ultoa(diff.value, s, 16); RS232_puts(s); + RS232_putc(':'); + ultoa(clk.value, s, 16); + RS232_puts(s); RS232_putc('\n'); } slot[car0-1].lap_time_start.value = clk.value; @@ -494,10 +503,7 @@ if (slot[car1-1].lap_time_start.value != 0) { slot[car1-1].lap_time.value = diff.value; slot[car1-1].laps++; - RS232_putc('L'); - RS232_putc(':'); - RS232_putc('A'); - RS232_putc(':'); + RS232_puts("L:1:"); // 1 = AA itoa(slot[car1-1].laps, s, 16); RS232_puts(s); RS232_putc(':'); @@ -505,6 +511,9 @@ RS232_putc(':'); ultoa(diff.value, s, 16); RS232_puts(s); + RS232_putc(':'); + ultoa(clk.value, s, 16); + RS232_puts(s); RS232_putc('\n'); } slot[car1-1].lap_time_start.value = clk.value; @@ -524,6 +533,9 @@ RS232_putc(':'); itoa(slot[idx].fuel, s, 16); RS232_puts(s); + RS232_putc(':'); + ultoa(sysclk.value, s, 16); + RS232_puts(s); RS232_putc('\n'); slot[idx].seccnt = 0; @@ -554,9 +566,9 @@ if (response_len > 0) { itoa(response, s, 2); response_len = 0; - RS232_puts("ANSWER RX: "); - RS232_puts(s); - RS232_putc('\n'); + //RS232_puts("ANSWER RX: "); + //RS232_puts(s); + //RS232_putc('\n'); }
--- a/slotUI/SlotCli.py Sun Dec 11 13:54:14 2011 +0100 +++ b/slotUI/SlotCli.py Sun Dec 11 17:34:40 2011 +0100 @@ -4,19 +4,23 @@ Command line interface """ -from freeslot import Blackbox +from freeslot import Blackbox, LOGLEVEL from optparse import OptionParser +from operator import itemgetter import sys from copy import copy import curses -VERSION = "1.2" +VERSION = "1.3" MAXSLOTS = 6 TERM = { "caption": "\033[1;37m\033[1;44m", "text": "\033[1;30m", } +# disable debug log output +LOGLEVEL = 10 + class SlotCli(): def __init__(self): self.box = Blackbox() @@ -29,6 +33,9 @@ "fuel": 0, "position": 0, "drive": 0, + "status": "Idle", + "clk": 0, + "car": 0, } self.slot = [ @@ -36,26 +43,47 @@ copy(self.slot_dummy), copy(self.slot_dummy), copy(self.slot_dummy), copy(self.slot_dummy), ] + self.reset_slots() + self.sysclk = 0.00 + + def reset_slots(self): + idx = 0 + for slt in self.slot: + slt["laps"] = 0 + slt["last"] = 0.00 + slt["best"] = 0.00 + slt["fuel"] = 0 + slt["position"] = idx + slt["car"] = idx # used for sort order calculation + slt["status"] = self.slot_dummy["status"] + slt["clk"] = 0 + idx += 1 def update_positions(self): - for idx in range(MAXSLOTS): - self.slot[idx]["position"] = idx + 1 - # TODO + order1 = sorted(self.slot, key=itemgetter( + "clk")) + order2 = sorted(self.slot, key=itemgetter( + "laps"), reverse=True) + idx = 1 + for tst in order2: + self.slot[tst["car"]]["position"] = idx + idx += 1 def render_slots(self): self.update_positions() self.scr.addstr(3,0, - "Pos | #/Name | Laps | Best | Last | Fuel |", + "Pos | #/Name | Laps | Best | Last | Fuel | Status ", curses.color_pair(2)) for idx in range(MAXSLOTS): self.scr.addstr((3 + self.slot[idx]["position"]), 0, - "%3i | %15s | %4i | %5.2fs | %5.2fs | %3i%% |" % ( + "%3i | %i %15s | %4i | %7.2fs | %7.2fs | %3i%% | %10s" % ( self.slot[idx]["position"], - self.slot[idx]["name"], + self.slot[idx]["car"] + 1, self.slot[idx]["name"], self.slot[idx]["laps"], self.slot[idx]["best"], self.slot[idx]["last"], self.slot[idx]["fuel"], + self.slot[idx]["status"], ) ) def cleartop(self): @@ -90,6 +118,9 @@ Live Monitor on the console Keyboard loop to control it??? """ + # clear garbage in UART rx buffer + while self.box.com.readline() != "": pass + self.monitor_init() self.scr = curses.initscr() curses.start_color() @@ -132,17 +163,22 @@ # is there something in the rx buffer? rx = self.box.com.readline() if rx != "": + self.scr.addstr(10,0, + "Last RX: %19s" % rx, curses.color_pair(2)) + self.scr.refresh() # we have received something data = rx.split(":") if rx[:2] == "L:": # update lap time info + l = int(data[2], 16) slot = int(data[3]) - 1 - t = int(data[4], 16) - l = int(data[2], 16) - t /= 2000.00 + t = int(data[4], 16) / 2000.00 + self.sysclk = int(data[5], 16) / 2000.00 self.slot[slot]["laps"] = l self.slot[slot]["last"] = t + self.slot[slot]["clk"] = self.sysclk if (self.slot[slot]["best"] > t) or (self.slot[slot]["best"] == 0): self.slot[slot]["best"] = t + self.slot[slot]["status"] = "IN-RACE" self.render_slots() if rx[:2] == "F:": @@ -150,9 +186,51 @@ slot = int(data[1]) f = int(data[2], 16) f = f / 100 # fuel in percent + self.sysclk = int(data[3], 16) / 2000.00 self.slot[slot]["fuel"] = f self.render_slots() + if rx[:1] == "~": + # jumpstart occured + slot = int(rx[1:2]) + t = int(data[1], 16) / 2000.00 + self.slot[slot]["jumpstart"] = t + self.slot[slot]["status"] = "Jumpstart!" + + if rx[:3] == "RW:": + # ResponseWire packet, do nothing at the moment, just decode + slot = int(data[1]) + devtype = int(data[2]) + sender = int(data[3], 16) + status = int(data[4], 16) + self.sysclk = int(data[5], 16) + if (devtype == 4): + # pitlane sent something + if (status == 5): self.slot[slot]["status"] = "PITLANE" + if (status == 6): self.slot[slot]["status"] = "IN-RACE" + + self.render_slots() + + if rx == "!RACE PREPARE": + # reset current race status + # and display PREPARE PHASE + for slot in range(MAXSLOTS): + self.slot[slot]["status"] = "Prepare" + + if rx == "!RACE START": + for slot in range(MAXSLOTS): + if self.slot[slot]["status"] == "~~~~~~~~~~": + self.slot[slot]["status"] = "Idle" + + if rx == "!COUNTDOWN": + # countdown initiated + for slot in range(MAXSLOTS): + self.slot[slot]["status"] = "~~~~~~~~~~" + + self.scr.addstr(10,31, + "Race Timer: %7.3f min" % (self.sysclk / 60), + curses.color_pair(2)) + self.scr.refresh() # terminate
--- a/slotUI/freeslot.py Sun Dec 11 13:54:14 2011 +0100 +++ b/slotUI/freeslot.py Sun Dec 11 17:34:40 2011 +0100 @@ -10,11 +10,12 @@ # define loglevels DEBUG = 20 +LOGLEVEL = 20 def log(level, msg): """ Logging output function """ - print msg + if level <= LOGLEVEL: print msg class SerialCommunicator(): def __init__(self, device, speed):