Sun, 28 Oct 2012 16:18:53 +0100
added learn and teach modes for intelligent ghostcars
blackbox/Makefile | file | annotate | diff | comparison | revisions | |
blackbox/driver/rs232.c | file | annotate | diff | comparison | revisions | |
blackbox/driver/rs232.h | file | annotate | diff | comparison | revisions | |
blackbox/main.c | file | annotate | diff | comparison | revisions | |
blackbox/main.h | file | annotate | diff | comparison | revisions | |
slotUI/SlotCli.py | file | annotate | diff | comparison | revisions |
--- a/blackbox/Makefile Sun Oct 28 11:23:18 2012 +0100 +++ b/blackbox/Makefile Sun Oct 28 16:18:53 2012 +0100 @@ -81,6 +81,9 @@ program: code $(AVRDUDE) -P $(PORT) -c stk500v2 -b $(ISP_BAUD) -i 1 -p $(MCU) -V -U flash:w:$(PRG).hex:i +backup: + $(AVRDUDE) -P $(PORT) -c stk500v2 -b $(ISP_BAUD) -i 1 -p $(MCU) -V -U flash:r:$(PRG)_backup.hex:i + fuse: $(AVRDUDE) -P $(PORT) -c stk500v2 -p $(MCU) -V $(FUSES)
--- a/blackbox/driver/rs232.c Sun Oct 28 11:23:18 2012 +0100 +++ b/blackbox/driver/rs232.c Sun Oct 28 16:18:53 2012 +0100 @@ -48,7 +48,7 @@ //RS232_txc(); } -void RS232_puts_p(char* s) { +void RS232_puts_p(const char* s) { char c=pgm_read_byte(s); while (c != 0) { // send char
--- a/blackbox/driver/rs232.h Sun Oct 28 11:23:18 2012 +0100 +++ b/blackbox/driver/rs232.h Sun Oct 28 16:18:53 2012 +0100 @@ -6,7 +6,7 @@ extern void RS232_init(void); extern void RS232_putc(char c); extern void RS232_puts(char* s); -extern void RS232_puts_p(char* s); +extern void RS232_puts_p(const char* s); #endif \ No newline at end of file
--- a/blackbox/main.c Sun Oct 28 11:23:18 2012 +0100 +++ b/blackbox/main.c Sun Oct 28 16:18:53 2012 +0100 @@ -13,15 +13,15 @@ #include "main.h" #include "lowlevel.h" -char ok[] PROGMEM="OK\n"; -char busy[] PROGMEM="BUSY\n"; -char prepare[] PROGMEM="!RACE PREPARE\n"; -char countdownstart[] PROGMEM="!COUNTDOWN\n"; -char racestart[] PROGMEM="!RACE START\n"; +const char ok[] PROGMEM="OK\n"; +const char busy[] PROGMEM="BUSY\n"; +const char prepare[] PROGMEM="!RACE PREPARE\n"; +const char countdownstart[] PROGMEM="!COUNTDOWN\n"; +const char racestart[] PROGMEM="!RACE START\n"; -char SHORTCUT[] PROGMEM="!SHORTCUT\n"; -char PANIC[] PROGMEM="!PANIC\n"; -char RESUME[] PROGMEM="!RESUME\n"; +const char SHORTCUT[] PROGMEM="!SHORTCUT\n"; +const char PANIC[] PROGMEM="!PANIC\n"; +const char RESUME[] PROGMEM="!RESUME\n"; typedef union { uint32_t value; @@ -40,9 +40,11 @@ unsigned speedminimum:4; // 4bits speedminimum unsigned seccnt:4; // 4 bits tenth seconds counter unsigned accel:4; // 4 bits last configured acceleration + unsigned speed:4; // 4 bits last speed unsigned trackswitch:1; // 1bit bool unsigned canrefuel:1; // 1bit bool unsigned unlimitedfuel:1; // 1bit bool + unsigned trackchange:1; // 1bit bool uint16_t jumpstart_time, laps, fuel; u32 lap_time_start, lap_time; } cardata; @@ -371,6 +373,8 @@ } } speed = tmp; + slot[controller].speed = tmp; + slot[controller].trackchange = (trackchange != 0); tmp = tmp << 1; if (trackchange != 0) tmp |= (1<<5); @@ -577,22 +581,35 @@ void slot_liveinfo(uint8_t idx) { if (liveinfo == 0) return; - // increment packet counter, if == 10 output some live info - if (slot[idx].seccnt == 10) { - // output current fuel status - RS232_putc('F'); - RS232_putc(':'); - RS232_putc(idx + '0'); - 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; - } else slot[idx].seccnt++; + if (liveinfo == 1) { + // increment packet counter, if == 10 output some live info + if (slot[idx].seccnt == 10) { + // output current fuel status + RS232_putc('F'); + RS232_putc(':'); + RS232_putc(idx + '0'); + 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; + } else slot[idx].seccnt++; + } else if ( (liveinfo - 2) == idx ) { + // output controller status LIVEINFO-2 for remote learning + RS232_putc('L'); + RS232_putc('N'); + RS232_putc(':'); + itoa(slot[idx].speed, s, 16); + RS232_puts(s); + RS232_putc(':'); + if (slot[idx].trackchange) + RS232_putc('X'); + RS232_putc('\n'); + } }
--- a/blackbox/main.h Sun Oct 28 11:23:18 2012 +0100 +++ b/blackbox/main.h Sun Oct 28 16:18:53 2012 +0100 @@ -100,9 +100,9 @@ extern uint8_t mode; extern uint8_t btn_start; extern uint8_t old_start; -extern char SHORTCUT[]; -extern char PANIC[]; -extern char RESUME[]; +extern const char SHORTCUT[]; +extern const char PANIC[]; +extern const char RESUME[]; // function prototypes void reset_vars(void);
--- a/slotUI/SlotCli.py Sun Oct 28 11:23:18 2012 +0100 +++ b/slotUI/SlotCli.py Sun Oct 28 16:18:53 2012 +0100 @@ -11,8 +11,9 @@ import sys, os from copy import copy import curses +from time import sleep -VERSION = "1.6" +VERSION = "1.7" MAXSLOTS = 6 TERM = { "caption": "\033[1;37m\033[1;44m", @@ -212,12 +213,104 @@ return inp - def monitor_init(self): + def monitor_init(self, live = 1): """ Send initializing commands for live monitoring """ self.box.query("F1\n") # set fuel logic enabled - self.box.query("*1\n") # set live fuel info + self.box.query("*%i\n" % live) # set live fuel info + + def monitor_learn(self, slot): + # clear garbage in UART rx buffer + self.box.query("*0\n") # set live fuel info + self.box.query("*0\n") # set live fuel info + while self.box.readline() != "": pass + + trk = False + spd = 0 + trk_old = False + spd_old = 0 + clock = -1 + + self.monitor_init(slot + 2) + while 1: + #key = self.scr.getch() + #if key == ord('c'): break + + # is there something in the rx buffer? + rx = self.box.readline() + if (rx != ""): + try: + data = rx.split(":") + if rx[:3] == "LN:": + if clock >= 0: + clock += 1 + spd = int(data[1], 16) + trk = (data[2] != 'X') + if (spd != spd_old) or (trk != trk_old): + if clock < 0: + clock = 0 + print "%i,%i,%s" % (clock, spd, trk) + trk_old = trk + spd_old = spd * 1 + if rx[:2] == "L:": + # update lap time info + l = int(data[2], 16) + s = int(data[3]) - 1 + t = int(data[4], 16) / 2000.00 + if (slot == s): + print "# lap %i complete: %3.2f seconds" % (l, t) + clock = 0 + print "%i,%i,%s" % (clock, spd, trk) + except: + print "RX ERROR: " % rx + + def monitor_playback(self, slot, filename): + # clear garbage in UART rx buffer + self.box.query("*0\n") # set live fuel info + self.box.query("*0\n") # set live fuel info + sleep(1) + cli.box.speedminimum(slot, 0 ) + while self.box.readline() != "": pass + + clock = -5 + trkfile = open(filename, "r").readlines() + print "Loading %s..." % filename + + while 1: + try: + for l in trkfile: + l = l.strip() + if (l != "") and (l[:1] != "#"): + print "Line: %s" % repr(l) + data = l.split(",") + speed = int(data[1]) + while (clock < int(data[0]) and (int(data[0]) > 0)): + clock += 1 + sleep(0.07) + print "CLK %i/%i -> set: %i" % (clock, int(data[0]), speed) + cli.box.speedminimum(slot, speed ) + # now wait for lap sync :) + while self.box.readline() != "": pass + rx = "" + while rx[:2] != "L:": + rx = self.box.readline() + data = rx.split(":") + l = int(data[2], 16) + s = int(data[3]) - 1 + t = int(data[4], 16) / 2000.00 + print "# lap %i complete: %3.2f seconds" % (l, t) + clock = -3 + except Exception, e: + print repr(e) + sys.exit(1) + except KeyboardInterrupt: + print "resetting" + cli.box.speedminimum(slot, 0 ) + cli.box.speedminimum(slot, 0 ) + sys.exit(0) + + def monitor(self): """ @@ -450,6 +543,10 @@ parser = OptionParser(version="%prog " + VERSION) parser.add_option("--live", dest="live", action="store_true", default=False, help="Run Live monitor on console", metavar="[0-5]") + parser.add_option("--learn", dest="learn", action="store_true", default=False, + help="Run Learning mode for [slot]", metavar="[0-5]") + parser.add_option("--teach", dest="playback", + help="Playback teach file", metavar="[filename]") parser.add_option("--slot", dest="carid", help="Required for programming a car directly", metavar="[1-6]") @@ -487,6 +584,16 @@ print "Error: Invalid slot selected" sys.exit(1) + if options.learn: + # start the learn monitor + cli.monitor_learn(options.carid) + sys.exit(0) + + if options.playback: + # start the playback monitor + cli.monitor_playback(options.carid, options.playback) + sys.exit(0) + if options.fuel: print "setFuel: " + cli.box.progcar(int(options.carid), "fuel", int(options.fuel))