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 | |
| parent | 5692ca8c65f5f5617d6987b610e425a32c0d8e1d (diff) | |
| parent | 38d71eb97dbd8f895ed483128b332f018a5ae1d4 (diff) | |
Merge branch 'lonkaars:master' into master
53 files changed, 547 insertions, 344 deletions
| @@ -8,3 +8,4 @@ client/main  .cache  *.log  scripts/InstallationLog.txt +docs/ diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..0415e98 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,21 @@ +{ +    "configurations": [ +        { +            "name": "Win32", +            "includePath": [ +                "${workspaceFolder}/**", +                "C:/msys64/mingw64/avr/include" +            ], +            "defines": [ +                "_DEBUG", +                "UNICODE", +                "_UNICODE" +            ], +            "compilerPath": "C:\\msys64\\mingw64\\bin\\gcc.exe", +            "cStandard": "gnu17", +            "cppStandard": "gnu++17", +            "intelliSenseMode": "windows-gcc-x64" +        } +    ], +    "version": 4 +}
\ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 251c67d..52ccd17 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,8 +1,12 @@  {  	"version": "2.0.0", -	"command": "C:/msys64/usr/bin/sh.exe", -	"options": { "cwd": "${workspaceFolder}" }, -	"args": [ "-c" ], +	"options": { +		"cwd": "${workspaceFolder}", +		"shell": { +			"executable": "C:/msys64/msys2_shell.cmd", +			"args": [ "-defterm", "-no-start", "-mingw64", "-shell", "sh", "-here", "-c" ], +		} +	},  	"tasks": [  		{  			"label": "build client", @@ -10,8 +14,9 @@  				"isDefault": false,  				"kind": "build"  			}, -			"args": [ "make", "-C", "client" ], -			"command": "", +			"command": "make", +			"args": [ "" ], +			"options": { "cwd": "${workspaceFolder}/client" },  			"type": "shell"  		},  		{ @@ -20,8 +25,9 @@  				"isDefault": false,  				"kind": "build"  			}, -			"args": [ "make", "-C", "robot" ], -			"command": "", +			"options": { "cwd": "${workspaceFolder}/robot" }, +			"command": "make", +			"args": [ "" ],  			"type": "shell"  		},  		{ @@ -30,8 +36,9 @@  				"isDefault": false,  				"kind": "test"  			}, -			"args": [ "make", "flash", "-C", "robot" ], -			"command": "", +			"options": { "cwd": "${workspaceFolder}/robot" }, +			"command": "make flash", +			"args": [ "" ],  			"type": "shell"  		},  		{ @@ -40,8 +47,8 @@  				"isDefault": false,  				"kind": "none"  			}, -			"args": [ "make", "clean" ], -			"command": "", +			"command": "make clean", +			"args": [ "" ],  			"type": "shell"  		},  		{ @@ -50,8 +57,18 @@  				"isDefault": false,  				"kind": "none"  			}, -			"args": [ "make", "format" ], -			"command": "", +			"command": "make format", +			"args": [ "" ], +			"type": "shell" +		}, +		{ +			"label": "generate compilation db (needed for autocomplete)", +			"group": { +				"isDefault": false, +				"kind": "build" +			}, +			"command": "make compile_commands", +			"args": [ "" ],  			"type": "shell"  		},  	] diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 0000000..8c225e9 --- /dev/null +++ b/Doxyfile @@ -0,0 +1,21 @@ +DOXYFILE_ENCODING      = UTF-8 +PROJECT_NAME           = "wall-e2" +# PROJECT_NUMBER         = +PROJECT_BRIEF          = Project RobotRun software +OUTPUT_DIRECTORY       = docs/ +CREATE_SUBDIRS         = NO +ALLOW_UNICODE_NAMES    = NO +OUTPUT_LANGUAGE        = English +TAB_SIZE               = 4 +FILE_PATTERNS          = *.c \ +                         *.h \ +                         *.md +RECURSIVE              = YES +USE_MDFILE_AS_MAINPAGE = ./readme.md +SOURCE_BROWSER         = YES +INLINE_SOURCES         = YES +STRIP_CODE_COMMENTS    = NO +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION    = YES +CALL_GRAPH             = YES +# INPUT                  = robot/ diff --git a/client/makefile b/client/makefile index 4cca15a..f79dd11 100644 --- a/client/makefile +++ b/client/makefile @@ -25,5 +25,5 @@ format:  	clang-tidy --fix-errors $(SOURCES) $(HEADERS)  compile_commands: clean -	bear -- make +	compiledb make diff --git a/client/readme.md b/client/readme.md index 990504d..8b4baee 100644 --- a/client/readme.md +++ b/client/readme.md @@ -10,46 +10,50 @@ this page is WIP  |-|-|-|-|-|  |view warnings / errors|  |direct control| +|configure map| +|input orders|  |enable/disable emergency mode| - - - - +|enable/disable sensor calibration mode| +|enable/disable wet floor mode| +|read sensor values| +|set display contents|optional +|play music|optional +|control leds|optional  ## interface  the client is a user-facing application that allows control and monitoring of -the robot in various ways. it primarily works in a command-line way, with the -user typing commands that get translated to protocol messages, and sent to the -robot. to start the interface, the user should run `./main <com-port> [command] -[args]`. by not specifying a command, the interactive shell is launched which -looks like this (and it's supposed to be in dutch): +the robot in various ways. it primarily works in a bios-like way, with the user +having access to multiple tabs containing options or custom interface elements. + +to start the interface, the user should run `./main <com-port>`. the interface +could look something like this (with colored text for element seperation):  ```  verbonden, 2ms ping           (0.0.2-11-g92c394b)                  batterij 100%  [huidige logica-modus]                         0 waarschuwingen, 0 foutmeldingen + [info]  logs   direct aansturen   kaart   orders   modus instellen   sensor...  -------------------------------------------------------------------------------- - - - - - - - - - - - - -  welkom in de wall-e2 console applicatie! deze client is versie  0.0.2-11-g92c394b -typ 'help' om alle commando's te zien in een lijst, of 'doei' om deze -applicatie weer te sluiten. +deze applicatie functioneert op een soortgelijke manier als een BIOS. hier is +een lijst met besturingscommando's: + +<links>/<rechts>, <h>/<l>     tabblad wisselen +<omlaag>/<omhoog>, <j>/<k>    optie selecteren +<enter>, <i>                  optie aanpassen +<home>, <g>                   terug naar boven scrollen +<end>, <G>                    naar einde van pagina scrollen +<escape>                      terug +<q>                           console applicatie sluiten + +sneltoetsen: +<N>  info                   <o>  orders +<S>  logs                   <M>  modus instellen +<d>  direct aansturen       <m>  kaart               -w2>  ```  the top status bar is always supposed to be visible, and is sort of inspired by @@ -59,10 +63,13 @@ though it doesn't matter if it's very primitive.  going from top-left in reading order the status bar contains: connection  status, ping time, robot version number, robot battery info, current logic -mode, warnings and critical exceptions. the version number is aligned to the -terminal center, and the battery and warning counters are aligned right. when a -connection hasn't been established between the robot and client, the fields -containing robot info should dissapear. +mode, warnings and critical exceptions, and lastly a tab bar. the version +number is aligned to the terminal center, and the battery and warning counters +are aligned right. when a connection hasn't been established between the robot +and client, the fields containing robot info should dissapear. the tab bar +scrolls horizontally, and tab names should in addition to a single space +seperator, keep spaces before and after to fit square brackets indicating tab +selection status.  ## code structure @@ -71,12 +78,13 @@ modules are executed after each other:  - serial read  - stdin read (user input) -- optional control mode handling +- status bar paint +- current tab paint  ## notes on ascii escape codes  - color codes  - terminal echo codes  - how to read terminal (re)size -- cursor movement +- cursor movement(?) @@ -5,4 +5,7 @@ all clean format compile_commands: $(SUBDIRS) FORCE  $(SUBDIRS): FORCE  	$(MAKE) -C $@ $(MAKECMDGOALS) -FORCE:
\ No newline at end of file +FORCE: + +docs: +	doxygen diff --git a/noob_hoek.md b/noob_hoek.md new file mode 100644 index 0000000..ea02bb2 --- /dev/null +++ b/noob_hoek.md @@ -0,0 +1,72 @@ +## noob hoek + +hier wat korte uitleg over dingen die niet zijn uitgelegd in vorige blokken van +de opleiding: + +### make + +make is een los build-systeem. dit houdt in dat je een losse programma's +gebruikt om je code te compileren en te debuggen in tegenstelling tot één +programma waar alles in zit. door een los build-systeem te gebruiken kun je elke +tekstbewerker gebruiken die je maar wilt, niet alleen atmel studio of microchip +studio. + +make wordt geconfigureerd via een _makefile_. hier staat in hoe je code +gecompileerd moet worden. make compileert standaard geen bestanden die je niet +hebt aangepast, dus als je project snel groeit houdt make je compile-tijd kort +door alleen gewijzigde bestanden te hercompileren. hier zijn wat standaard make +commando's die voor dit project in zowel de robot map als de client map zullen +werken: + +```sh +make            # alle (gewijzigde) bestanden compileren +make clean      # rommel opschonen uit je werkmap (.o bestanden, etc.) +make format     # alle bronbestanden (.c, .h) formatten +``` + +als je deze commando's niet wil onthouden heb ik (loek) ook een visual studio +configuratie gemaakt die automatisch laadt wanneer je de projectmap opent. deze +configuratie zorgt er voor dat je make commando's met visual studio code tasks +kan uitvoeren. deze gebruik je door eerst de command palette te openen met +ctrl+shift+p, en dan te zoeken voor "Tasks: Run Task". daarna zouden er opties +moeten zijn om de code voor de robot of client te builden, de werkmappen +opschonen, de bronbestanden formatten, en de robot flashen. + +### git + +git is het versiebeheersysteem dat we in dit project gaan gebruiken. een project +in git wordt ook soms een _repository_ genoemd. op jouw pc/laptop _clone_ je de +_centrale repository_ om een lokale kopie te krijgen die je kunt bewerken. git +houdt elke 'versie' bij van je project in zogehete _commits_. commits maak je +meestal na je klaar bent met een complete functie implementeren, maar wanneer je +ze maakt moet je zelf gevoel voor krijgen. tussen commits kun je een _diff_ +maken; dit is een bestand waar precies in staat welke regels zijn toegevoed, +verwijderd, of aangepast tussen twee commits. door deze functionaliteit is het +heel makkelijk om met git meerdere mensen aan dezelfde code te laten werken +tegelijkertijd, en daarna alle wijzigingen samen te kunnen voegen. + +voor gemak werkt iedereen op zijn eigen _branch_, met hun eigen naam. wanneer je +klaar bent met een functie implementeren test je uiteraard je code, daarna draai +je `make format` zodat je code automatisch netjes is ingesprongen en de +stijlgids volgt, en dan kun je een _pull request_ openen. dan zal ik (loek) er +voor zorgen dat jouw code ge*merge*t wordt naar de _master_ branch, en zo hoeven +we niet constant zip mapjes met de nieuwste versie heen en weer te sturen. + +wanneer je een commit maakt, staat deze alleen op je eigen laptop/pc. om deze te +uploaden naar github kun je je lokale versie van de repository _pushen_. +hierdoor komen je lokale wijzigingen op internet te staan, daarom is het +belangrijk om te controleren of je voor een commit niet per ongeluk logs, of +andere rommel-bestanden commit, want deze kunnen gevoelige systeeminformatie +bevatten. + +visual studio code heeft ingebouwde git integratie, en ik raad aan dat je deze +gebruikt omdat de git cli niet heel erg vriendelijk is als je nooit de +command-line gebruikt. +[hier](https://docs.microsoft.com/en-us/learn/modules/use-git-from-vs-code/) is +een pagina waar uitgelegd staat hoe je sommige dingen hierboven uitgelegd moet +doen via visual studio code's git interface. + +[dit](https://www.youtube.com/watch?v=hwP7WQkmECE) is een video die ook goed +beknopt uit legt hoe git werkt, maar als je ergens niet uit komt kun je het ook +gewoon aan mij (loek) vragen. + diff --git a/protocol.md b/protocol.md index 7c7c843..bc6a8c0 100644 --- a/protocol.md +++ b/protocol.md @@ -39,7 +39,7 @@ readability.  |`0x08`|[DIRC](#dirc)|yes|`r <-- c`|<u>dir</u>ect <u>c</u>ontrol  |`0x0a`|[CORD](#cord)|no|`r <=> c`|<u>co</u>o<u>rd</u>inate  |`0x0c`|[BOMD](#bomd)|no|`r <=> c`|<u>b</u>ack<u>o</u>rder <u>m</u>o<u>d</u>ify -|`0x0e`|[SRES](#sres)|no|`r <-- c`|<u>s</u>oft <u>res</u>et +|`0x0e`|[SRES](#sres)|yes|`r <-- c`|<u>s</u>oft <u>res</u>et  |`0x10`|[MCFG](#mcfg)|no|`r <-- c`|<u>m</u>ap <u>c</u>on<u>f</u>i<u>g</u>  |`0x12`|[SENS](#sens)|yes|`r <-> c`|<u>sens</u>or data  |`0x14`|[INFO](#info)|yes|`r <-> c`|<u>info</u> @@ -223,7 +223,7 @@ _status_ is one of:  _type_ is one of:  - 0: reinitialize all global state -- 1: reset emergency mode +- 1: go to previous mode  ### MCFG @@ -1,151 +1,55 @@  # project robotrun software -- [link naar robot productpagina](https://www.pololu.com/product/975/resources) -- [link naar wixel productpagina](https://www.pololu.com/product/1336/resources) +- [robot product page](https://www.pololu.com/product/975/resources) +- [wixel product page](https://www.pololu.com/product/1336/resources) -het project is opgedeeld in twee submappen, een voor de code die op de robot -zelf draait, en een programma dat op een computer draait en de robot kan -aansturen. +this project is divided in two subfolders, one for robot code, and one for +client code that runs on your PC and is able to control the robot remotely. -voor de client worden sommige externe libraries gebruikt, hier is een lijst met -gebruikte externe libraries: +## toolchain installation on windows -|naam|doel| -|-|-| -|[yan9a/serial](https://github.com/yan9a/serial)|cross-compatibiliteit voor seriële poorten lezen/schrijven voor windows en linux| +> look in the scripts/ subdirectory if you're concerned about what these +> commands do -## samenvatting werking - -hoop onder constructie - -~Globaal gezien draait de robot altijd in een van twee 'standen'. De eerste -stand is voor het doolhof-gedeelte van de kaart, en de tweede is voor het -warenhuis-gedeelte. Tijdens de assessment kan het zijn dat de robot opgetild -wordt en ergens anders wordt neergezet in het doolhof gedeelte, en hier moet de -robot tegen kunnen. Om het doolhof op te lossen wordt of de rechterhandregel of -de linkerhandregel gebruikt, zodat de robot altijd een uitgang van het doolhof -kan vinden, zonder dat de robot zijn eigen positie binnen het doolhof hoeft te -weten, of überhaupt bewust hoeft te zijn van de lay-out van het doolhof zelf. -De overgang tussen het doolhof en het warenhuis wordt aangegeven met een soort -zebrapad die dezelfde breedte als de rest van de lijnen heeft.~ Vooraf wordt -via de client aangegeven aan de robot hoe groot het warenhuis is, en waar de -in- en uitgangen van het warenhuis zitten, zodat de robot zelfstandig naar het -afleverpunt en het oplaadstation kan rijden zodra alle bestellingen opgehaald -zijn. De volgende specificaties moeten nog exact afgesproken worden voordat er -een kaart gemaakt kan worden: - -- breedte van de lijn -- tegelgrootte (binnen warenhuis) -- exacte afmetingen van, en de hoeveelheid van de strepen in het zebrapad - -De lijnen van het doolhof hoeven niet te voldoen aan de tegelgrootte, maar de -in- en uitgangen moeten wel een rechte overloop hebben op het -warenhuis-gedeelte. - -## de kaart - -voor de kaart worden de volgende afmetingen aangehouden: - -- 3/4" (~19mm) breedte -- gebogen lijnen niet scherper dan een radius van 3" (~750mm) -- het oplaadstation is een zwarte stip met een diameter van 3" (~750mm) -- paginamarge en minimale ruimte tussen lijnen van 3" (~750mm) -- (binnen grid) tegelgrootte van 8" (~20cm) - -## noob hoek - -hier wat korte uitleg over dingen die niet zijn uitgelegd in vorige blokken van -de opleiding: - -### make - -make is een los build-systeem. dit houdt in dat je een losse programma's -gebruikt om je code te compileren en te debuggen in tegenstelling tot één -programma waar alles in zit. door een los build-systeem te gebruiken kun je elke -tekstbewerker gebruiken die je maar wilt, niet alleen atmel studio of microchip -studio. - -make wordt geconfigureerd via een _makefile_. hier staat in hoe je code -gecompileerd moet worden. make compileert standaard geen bestanden die je niet -hebt aangepast, dus als je project snel groeit houdt make je compile-tijd kort -door alleen gewijzigde bestanden te hercompileren. hier zijn wat standaard make -commando's die voor dit project in zowel de robot map als de client map zullen -werken: - -```sh -make            # alle (gewijzigde) bestanden compileren -make clean      # rommel opschonen uit je werkmap (.o bestanden, etc.) -make format     # alle bronbestanden (.c, .h) formatten -``` - -als je deze commando's niet wil onthouden heb ik (loek) ook een visual studio -configuratie gemaakt die automatisch laadt wanneer je de projectmap opent. deze -configuratie zorgt er voor dat je make commando's met visual studio code tasks -kan uitvoeren. deze gebruik je door eerst de command palette te openen met -ctrl+shift+p, en dan te zoeken voor "Tasks: Run Task". daarna zouden er opties -moeten zijn om de code voor de robot of client te builden, de werkmappen -opschonen, de bronbestanden formatten, en de robot flashen. - -### git - -git is het versiebeheersysteem dat we in dit project gaan gebruiken. een project -in git wordt ook soms een _repository_ genoemd. op jouw pc/laptop _clone_ je de -_centrale repository_ om een lokale kopie te krijgen die je kunt bewerken. git -houdt elke 'versie' bij van je project in zogehete _commits_. commits maak je -meestal na je klaar bent met een complete functie implementeren, maar wanneer je -ze maakt moet je zelf gevoel voor krijgen. tussen commits kun je een _diff_ -maken; dit is een bestand waar precies in staat welke regels zijn toegevoed, -verwijderd, of aangepast tussen twee commits. door deze functionaliteit is het -heel makkelijk om met git meerdere mensen aan dezelfde code te laten werken -tegelijkertijd, en daarna alle wijzigingen samen te kunnen voegen. - -voor gemak werkt iedereen op zijn eigen _branch_, met hun eigen naam. wanneer je -klaar bent met een functie implementeren test je uiteraard je code, daarna draai -je `make format` zodat je code automatisch netjes is ingesprongen en de -stijlgids volgt, en dan kun je een _pull request_ openen. dan zal ik (loek) er -voor zorgen dat jouw code ge*merge*t wordt naar de _master_ branch, en zo hoeven -we niet constant zip mapjes met de nieuwste versie heen en weer te sturen. - -wanneer je een commit maakt, staat deze alleen op je eigen laptop/pc. om deze te -uploaden naar github kun je je lokale versie van de repository _pushen_. -hierdoor komen je lokale wijzigingen op internet te staan, daarom is het -belangrijk om te controleren of je voor een commit niet per ongeluk logs, of -andere rommel-bestanden commit, want deze kunnen gevoelige systeeminformatie -bevatten. - -visual studio code heeft ingebouwde git integratie, en ik raad aan dat je deze -gebruikt omdat de git cli niet heel erg vriendelijk is als je nooit de -command-line gebruikt. -[hier](https://docs.microsoft.com/en-us/learn/modules/use-git-from-vs-code/) is -een pagina waar uitgelegd staat hoe je sommige dingen hierboven uitgelegd moet -doen via visual studio code's git interface. - -[dit](https://www.youtube.com/watch?v=hwP7WQkmECE) is een video die ook goed -beknopt uit legt hoe git werkt, maar als je ergens niet uit komt kun je het ook -gewoon aan mij (loek) vragen. - -## installatie programmeer dingen op windows - -1. open een normaal powershell venster (geen administrator!) -2. kopiëer het volgende commando (druk op het kopiëer-icoontje rechts als je -   met je muis over het commando staat): +1. open een regular powershell window (no administrator!) +2. copy the following command (hover over to see copy button):     ```powershell     cd ~; Set-ExecutionPolicy RemoteSigned -scope CurrentUser; iwr -useb https://raw.githubusercontent.com/lonkaars/wall-e2/master/scripts/bootstrap.ps1 | iex     ``` -3. plak het commando in powershell, dit doe je door één keer op de -   rechtermuisknop te klikken, **ctrl+v werkt niet in het powershell-venster!** -4. ram op enter -5. typ een letter 'y' en druk daarna weer op enter -6. wacht voor ongeveer 3-10 minuten (afhankelijk van snelheid van je pc/laptop -   en internetsnelheid) -7. het is klaar wanneer er een windows verkenner venster opent met de -   projectbestanden er in, nu kun je het powershell-venster weer sluiten - -nu ben je klaar om aan het project te werken! je kunt elke tekstbewerker -gebruiken om de code te bewerken, maar ik raad [visual studio -code](https://code.visualstudio.com) aan als je geen voorkeur hebt. +3. paste the command by right-clicking or pressing +   <kbd>shift</kbd>+<kbd>insert</kbd> **ctrl+v doesn't work in the powershell +   window** +4. press <kbd>enter</kbd>, then <kbd>y</kbd>, then <kbd>enter</kbd> again. +5. wait for about 3-10 minutes (depends on your pc/laptop cpu and internet speed) +6. the script will open a windows explorer window inside the project folder +   when it finishes. the powershell window can be closed when it's done. + +now you're ready to edit this project! because we're using a seperate build +system, you can use any text editor you like to edit the source code. i +recommend [visual studio code](https://code.visualstudio.com) if you don't have +a preferred text editor. + +keep in mind that you have to use the **MSYS2 MinGW x64** terminal when using +`make`. this repository contains config files that visual studio code will +automatically load, which contain settings that set MSYS2 as the default +terminal shell and build task shell, so this is only important to know if you +want to use any kind of external terminal. + +## map + +[link to the map design file (figma)](https://www.figma.com/file/fPlfOqtEvQYVA9TYWNjz1i/kaart) + +the map uses the following dimensions: + +- a0 paper size +- 3/4" (~19mm) line width +- curved lines may not have a corner radius tighter than 3" (~750mm) +- the charging station is a black dot with a diameter of 3" (~750mm) +- page margin and minimum line margin of 3" (~750mm) +- (in grid) tile size of 8" (~20cm) +- 'crosswalk' has 2 dashes with a length of 3/8" (~10mm) +- 'crosswalk' dashes have a margin of 3/8" (~10mm) + +the lines inside the maze don't have to conform to the grid tile size, but the +entrance(s)/exit(s) have to connect in a straight line to the grid. -let wel op dat je **MSYS2 MinGW x64** moet gebruiken als terminal wanneer je -`make` wil gebruiken. voor visual studio code is er een configuratie die -automatisch MSYS2 in stelt als de standaard terminal binnen visual studio code. -als je een losse terminal wil gebruiken moet je hier dus wel op letten 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.binBinary files differ index 1aea35c..8d141e8 100644 --- a/robot/tests/dirc.bin +++ b/robot/tests/dirc.bin diff --git a/robot/tests/ping.bin b/robot/tests/ping.binBinary files differ index 456804e..2bbe45e 100644 --- a/robot/tests/ping.bin +++ b/robot/tests/ping.bin diff --git a/scripts/install-mingw-packages.sh b/scripts/install-mingw-packages.sh index c847e4e..fd82909 100644 --- a/scripts/install-mingw-packages.sh +++ b/scripts/install-mingw-packages.sh @@ -1,2 +1,2 @@  #!/bin/sh -pacman --noconfirm -Sy make git unzip mingw-w64-x86_64-avr-toolchain mingw-w64-x86_64-toolchain mingw-w64-clang-x86_64-clang mingw-w64-x86_64-avrdude +pacman --noconfirm -Sy make git unzip mingw-w64-x86_64-avr-toolchain mingw-w64-x86_64-toolchain mingw-w64-clang-x86_64-clang mingw-w64-x86_64-avrdude python3 python3-pip diff --git a/scripts/install-sdk.sh b/scripts/install-sdk.sh index 4773186..0cc651a 100755 --- a/scripts/install-sdk.sh +++ b/scripts/install-sdk.sh @@ -36,3 +36,5 @@ fi  cd ..  rm -rf temp + +pip3 install compiledb diff --git a/scripts/patch-may-26.sh b/scripts/patch-may-26.sh new file mode 100644 index 0000000..d5b41c7 --- /dev/null +++ b/scripts/patch-may-26.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +pacman --noconfirm -Sy python3 python3-pip +pip3 install compiledb diff --git a/scripts/readme.md b/scripts/readme.md new file mode 100644 index 0000000..58f0a2c --- /dev/null +++ b/scripts/readme.md @@ -0,0 +1,14 @@ +# scripts + +this directory contains scripts for installing necessary build tools for +compiling and uploading code to the robot/client. + +|file|description| +|-|-| +|`bootstrap.ps1`|download msys2 installer, install msys2, download and run `install-mingw-packages.sh`, clone the repository using git, run `install-sdk.sh`, start windows explorer in the project folder.| +|`install-mingw-packages.sh`|install required packages (`make`, `git`, `avr-gcc-toolchain`, `python3`, `pip3`, `avrdude`, `clangd`, `clang-tidy`, `clang-format`)| +|`install-sdk.sh`|install pololu c/c++ sdk, install wixel command-line tools (if on linux), install `compiledb` using `pip3`| +|`patch-may-26.sh`|patch| + +i'm aware the powershell script is ugly, i don't like windows + diff --git a/shared/bin.h b/shared/bin.h index af3a249..48485c8 100644 --- a/shared/bin.h +++ b/shared/bin.h @@ -1,4 +1,7 @@  #pragma once + +/** @file bin.h */ +  /**   * helper file for binary data   * diff --git a/shared/bool.h b/shared/bool.h new file mode 100644 index 0000000..9ea97f7 --- /dev/null +++ b/shared/bool.h @@ -0,0 +1,9 @@ +#pragma once + +#include <stdint.h> + +/** @file bool.h */ + +typedef uint8_t bool; +#define false 0 /* NOLINT */ +#define true 1	/* NOLINT */ diff --git a/shared/consts.h b/shared/consts.h index c65e50f..cdd96b3 100644 --- a/shared/consts.h +++ b/shared/consts.h @@ -1,28 +1,38 @@  #pragma once +/** @file consts.h */ +  #ifndef W2_BUILD_STR  // is defined by CFLAGS += -DW2_BUILD_STR in makefile  #define W2_BUILD_STR ("????????")  #endif -/** max logic module execution time in milliseconds */ -#define W2_MAX_MODULE_CYCLE_MS (20) +#if !defined W2_HOST_WIN32 && !defined W2_HOST_LINUX +#define W2_HOST_UNKNOWN +#warning "host operating system unknown" +#endif +  /** serial baud rate (bit/s) */  #define W2_SERIAL_BAUD (9600) +/** size of input (receive) buffer (in bytes) */ +#define W2_SERIAL_READ_BUFFER_SIZE (255) +  /** size of the error handling buffer (in errors, not bytes) */  #define W2_ERROR_BUFFER_SIZE (16)  /** size of the serial communication buffer (in messages, not bytes) */  #define W2_SERCOMM_BUFFER_SIZE (16) -/** size of input (receive) buffer (in bytes) */ -#define W2_SERIAL_READ_BUFFER_SIZE (255) -/** exponential moving average new measurement weight (double 0-1) */ -#define W2_EMA_WEIGHT (0.10)  /** size of mode history buffer */  #define W2_MODE_HISTORY_BUFFER_SIZE (4) +/** max logic module execution time in milliseconds */ +#define W2_MAX_MODULE_CYCLE_MS (20) + +/** exponential moving average new measurement weight (double 0-1) */ +#define W2_EMA_WEIGHT (0.10) +  /** front-facing distance sensor pinout */  #define W2_FRONT_SENSOR_PIN 5  /** battery voltage sensor pinout */  #define W2_BATTERY_PIN 6  /** side-facing distance sensor pinout */ -#define W2_SIDE_SENSOR_PIN 7
\ No newline at end of file +#define W2_SIDE_SENSOR_PIN 7 diff --git a/shared/errors.h b/shared/errors.h index ac8e95f..344a506 100644 --- a/shared/errors.h +++ b/shared/errors.h @@ -1,5 +1,7 @@  #pragma once +/** @file errors.h */ +  #include <stdint.h>  #define W2_E_TYPE_MASK (0b11 << 6) @@ -43,8 +45,6 @@ typedef enum {  	W2_E_WARN_SERCOMM_BUFFER_FULL = 0x06 | W2_E_TYPE_WARN,  	/** semver minor version doesn't match */  	W2_E_WARN_VERSION_INCOMPATIBLE = 0x07 | W2_E_TYPE_WARN, -	/** serial byte took to long to receive */ -	W2_E_WARN_SERIAL_TIMEOUT = 0x08 | W2_E_TYPE_WARN,  	/** unknown message encountered (noisy channel?) */  	W2_E_WARN_SERIAL_NOISY = 0x09 | W2_E_TYPE_WARN,  	/** mode history index out of bounds */ diff --git a/shared/io.h b/shared/io.h new file mode 100644 index 0000000..584ad1e --- /dev/null +++ b/shared/io.h @@ -0,0 +1,59 @@ +#pragma once + +#include <stdio.h> + +#include "bool.h" + +#pragma pack(push, 1) + +/** momentary button input struct */ +typedef struct { +	bool pressed; +} w2_s_i_push; + +/** qtr contrast sensor input struct */ +typedef struct { +	uint16_t range; +} w2_s_i_contrast; + +/** distance sensor input struct */ +typedef struct { +	uint16_t detection; +} w2_s_i_distance; + +/** battery input struct */ +typedef struct { +	uint16_t charge_level; +} w2_s_i_battery; + +/** motor output struct */ +typedef struct { +	int16_t speed; +} w2_s_o_motor; + +/** underside led output struct */ +typedef struct { +	bool on; +} w2_s_o_led; + +/** lcd output struct */ +typedef struct { +	char text[16]; +} w2_s_o_display; + +/** struct containing all i/o */ +typedef struct { +	w2_s_i_push button[5]; +	w2_s_i_contrast qtr[5]; +	w2_s_i_distance front_distance; +	w2_s_i_distance side_distance; +	w2_s_i_battery battery; + +	w2_s_o_motor motor_left; +	w2_s_o_motor motor_right; +	w2_s_o_led led_red; +	w2_s_o_led led_green; +	w2_s_o_display lcd; +} w2_s_io_all; + +#pragma pack(pop) diff --git a/shared/makefile b/shared/makefile index cfdf8ac..e5a6ff6 100644 --- a/shared/makefile +++ b/shared/makefile @@ -1,5 +1,9 @@  SOURCES += $(wildcard ../shared/*.c)  HEADERS += $(wildcard ../shared/*.h) +# 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 ../shared/*.o diff --git a/shared/os.mk b/shared/os.mk new file mode 100644 index 0000000..e4ede42 --- /dev/null +++ b/shared/os.mk @@ -0,0 +1,12 @@ +# os info
 +OS=$(strip $(shell uname -o))
 +ifeq ($(OS),GNU/Linux)
 +CFLAGS += -DW2_HOST_LINUX
 +LINUX := true
 +TARGET := a.out
 +endif
 +ifeq ($(OS),Msys)
 +CFLAGS += -DW2_HOST_WIN32
 +WIN32 := true
 +TARGET := a.exe
 +endif
\ No newline at end of file diff --git a/shared/protocol.c b/shared/protocol.c index fcc9fa4..9be1d31 100644 --- a/shared/protocol.c +++ b/shared/protocol.c @@ -74,22 +74,3 @@ size_t w2_cmd_expt_tx_sizeof(w2_s_bin *data) {  size_t w2_cmd_mcfg_rx_sizeof(w2_s_bin *data) {  	return W2_DYN_MEMBER_SIZEOF(w2_s_cmd_mcfg_rx, 3, w2_s_cmd_mcfg_feature);  } - -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 -	} else { -#ifdef W2_SIM -		w2_sim_print_serial(copy); -#endif -		handler(copy); -	} - -	free(copy); -} diff --git a/shared/protocol.h b/shared/protocol.h index 7aa5e9f..93e53f4 100644 --- a/shared/protocol.h +++ b/shared/protocol.h @@ -1,14 +1,14 @@  #pragma once +/** @file protocol.h */ +  #include <stdint.h>  #include <stdlib.h>  #include "bin.h" +#include "bool.h"  #include "consts.h" - -typedef uint8_t bool; -#define false 0 /* NOLINT */ -#define true 1	/* NOLINT */ +#include "io.h"  #define W2_SERIAL_START_BYTE 0xff @@ -52,56 +52,6 @@ typedef enum {  #pragma pack(push, 1) -/** momentary button input struct */ -typedef struct { -	bool pressed; -} w2_s_i_push; - -/** qtr contrast sensor input struct */ -typedef struct { -	uint16_t range; -} w2_s_i_contrast; - -/** distance sensor input struct */ -typedef struct { -	uint16_t detection; -} w2_s_i_distance; - -/** battery input struct */ -typedef struct { -	uint16_t charge_level; -} w2_s_i_battery; - -/** motor output struct */ -typedef struct { -	int16_t speed; -} w2_s_o_motor; - -/** underside led output struct */ -typedef struct { -	bool on; -} w2_s_o_led; - -/** lcd output struct */ -typedef struct { -	char text[16]; -} w2_s_o_display; - -/** struct containing all i/o */ -typedef struct { -	w2_s_i_push button[5]; -	w2_s_i_contrast qtr[5]; -	w2_s_i_distance front_distance; -	w2_s_i_distance side_distance; -	w2_s_i_battery battery; - -	w2_s_o_motor motor_left; -	w2_s_o_motor motor_right; -	w2_s_o_led led_red; -	w2_s_o_led led_green; -	w2_s_o_display lcd; -} w2_s_io_all; -  typedef struct {  	uint8_t opcode;  	uint8_t id; @@ -164,6 +114,8 @@ typedef struct {  	uint8_t status;  } w2_s_cmd_bomd_tx; +#define W2_CMD_SRES_RX_TYPE_REINITGS 0 +#define W2_CMD_SRES_RX_TYPE_PREVMODE 1  typedef struct {  	uint8_t opcode;  	uint8_t type; diff --git a/shared/semver.h b/shared/semver.h index a99ae61..6a1da79 100644 --- a/shared/semver.h +++ b/shared/semver.h @@ -1,5 +1,7 @@  #pragma once +/** @file semver.h */ +  #include <stdint.h>  typedef struct { diff --git a/shared/serial_parse.c b/shared/serial_parse.c index 3bc8e3b..b1b4f50 100644 --- a/shared/serial_parse.c +++ b/shared/serial_parse.c @@ -3,8 +3,7 @@  #include "consts.h"  #include "serial_parse.h" -// TODO: give this function last time of byte, and measure if >5ms, throw warning -void w2_serial_parse(uint8_t byte) { +bool w2_serial_parse(uint8_t byte) {  	static uint8_t current_message[W2_SERIAL_READ_BUFFER_SIZE] = {0};  	static uint8_t current_message_index					   = 0;  	static uint8_t complete_message_length					   = 2; @@ -14,18 +13,14 @@ void w2_serial_parse(uint8_t byte) {  	if (byte == W2_SERIAL_START_BYTE) {  		attentive = !attentive; -		// if (attentive && listening) { -		// 	current_message[current_message_index++] = byte; -		// } -	} else { -		// activate listen after non-0xff byte after 0xff -		if (attentive && !listening) { -			attentive = false; -			listening = true; -		} +		if (attentive && listening) return W2_SERIAL_READ_SUCCESS; +	} else if (attentive) { +		attentive = false; +		listening = !listening; +		if (!listening) return W2_SERIAL_READ_FAILURE;  	} -	if (!listening) return; +	if (!listening) return W2_SERIAL_READ_SUCCESS;  	current_message[current_message_index++] = byte;  	complete_message_length = w2_cmd_sizeof(current_message, current_message_index); @@ -38,6 +33,8 @@ void w2_serial_parse(uint8_t byte) {  		complete_message_length = 1;  		attentive				= false;  		listening				= false; -		return; +		return W2_SERIAL_READ_SUCCESS;  	} + +	return W2_SERIAL_READ_SUCCESS;  } diff --git a/shared/serial_parse.h b/shared/serial_parse.h index a1c8fb9..0816ea1 100644 --- a/shared/serial_parse.h +++ b/shared/serial_parse.h @@ -1,8 +1,17 @@  #pragma once +/** @file serial_parse.h */ +  #include <stdint.h> +#include "bool.h"  #include "protocol.h" -/** parse serial data byte by byte */ -void w2_serial_parse(uint8_t byte); +#define W2_SERIAL_READ_SUCCESS true +#define W2_SERIAL_READ_FAILURE false + +/** + * parse serial data byte by byte + * @return true if read success, false if read fails + */ +bool w2_serial_parse(uint8_t byte); diff --git a/shared/util.h b/shared/util.h index 9e4d8ac..465e043 100644 --- a/shared/util.h +++ b/shared/util.h @@ -1,5 +1,7 @@  #pragma once +/** @file util.h */ +  #define W2_MIN(a, b) (((a) < (b)) ? (a) : (b))  #define W2_MAX(a, b) (((a) > (b)) ? (a) : (b))  #define W2_RANGE(min, val, max) W2_MIN(max, W2_MAX(val, min)) |