This library is designed to create and run state graphs. It supports hierarchical states and parallel states execution.
utt_foobar.h@3:d4d69d0d8381, 2019-02-12 (annotated)
- Committer:
- martin13
- Date:
- Tue Feb 12 08:56:43 2019 +0000
- Revision:
- 3:d4d69d0d8381
- Parent:
- 2:5e2336b52d0a
- Child:
- 4:22b4462fcb26
Added README.md
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
martin13 | 0:f4fdca2c4c67 | 1 | #ifndef __UTT_FOOBAR_H__ |
martin13 | 0:f4fdca2c4c67 | 2 | #define __UTT_FOOBAR_H__ |
martin13 | 0:f4fdca2c4c67 | 3 | |
martin13 | 0:f4fdca2c4c67 | 4 | #include "StateMachine.h" |
martin13 | 2:5e2336b52d0a | 5 | #include "Logger.h" |
martin13 | 2:5e2336b52d0a | 6 | |
martin13 | 2:5e2336b52d0a | 7 | |
martin13 | 2:5e2336b52d0a | 8 | // different commands to set the update rate from once a second (1 Hz) to 10 times a second (10Hz) |
martin13 | 2:5e2336b52d0a | 9 | // Note that these only control the rate at which the position is echoed, to actually speed up the |
martin13 | 2:5e2336b52d0a | 10 | // position fix you must also send one of the position fix rate commands below too. |
martin13 | 2:5e2336b52d0a | 11 | #define PMTK_SET_NMEA_UPDATE_100_MILLIHERTZ "$PMTK220,10000*2F" // Once every 10 seconds, 100 millihertz. |
martin13 | 2:5e2336b52d0a | 12 | #define PMTK_SET_NMEA_UPDATE_200_MILLIHERTZ "$PMTK220,5000*1B" // Once every 5 seconds, 200 millihertz. |
martin13 | 2:5e2336b52d0a | 13 | #define PMTK_SET_NMEA_UPDATE_1HZ "$PMTK220,1000*1F" |
martin13 | 2:5e2336b52d0a | 14 | #define PMTK_SET_NMEA_UPDATE_5HZ "$PMTK220,200*2C" |
martin13 | 2:5e2336b52d0a | 15 | #define PMTK_SET_NMEA_UPDATE_10HZ "$PMTK220,100*2F" |
martin13 | 2:5e2336b52d0a | 16 | // Position fix update rate commands. |
martin13 | 2:5e2336b52d0a | 17 | #define PMTK_API_SET_FIX_CTL_100_MILLIHERTZ "$PMTK300,10000,0,0,0,0*2C" // Once every 10 seconds, 100 millihertz. |
martin13 | 2:5e2336b52d0a | 18 | #define PMTK_API_SET_FIX_CTL_200_MILLIHERTZ "$PMTK300,5000,0,0,0,0*18" // Once every 5 seconds, 200 millihertz. |
martin13 | 2:5e2336b52d0a | 19 | #define PMTK_API_SET_FIX_CTL_1HZ "$PMTK300,1000,0,0,0,0*1C" |
martin13 | 2:5e2336b52d0a | 20 | #define PMTK_API_SET_FIX_CTL_5HZ "$PMTK300,200,0,0,0,0*2F" |
martin13 | 2:5e2336b52d0a | 21 | // Can't fix position faster than 5 times a second! |
martin13 | 2:5e2336b52d0a | 22 | |
martin13 | 2:5e2336b52d0a | 23 | |
martin13 | 2:5e2336b52d0a | 24 | #define PMTK_SET_BAUD_57600 "$PMTK251,57600*2C" |
martin13 | 2:5e2336b52d0a | 25 | #define PMTK_SET_BAUD_9600 "$PMTK251,9600*17" |
martin13 | 2:5e2336b52d0a | 26 | |
martin13 | 2:5e2336b52d0a | 27 | // turn on only the second sentence (GPRMC) |
martin13 | 2:5e2336b52d0a | 28 | #define PMTK_SET_NMEA_OUTPUT_RMCONLY "$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29" |
martin13 | 2:5e2336b52d0a | 29 | // turn on GPRMC and GGA |
martin13 | 2:5e2336b52d0a | 30 | #define PMTK_SET_NMEA_OUTPUT_RMCGGA "$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28" |
martin13 | 2:5e2336b52d0a | 31 | // turn on ALL THE DATA |
martin13 | 2:5e2336b52d0a | 32 | #define PMTK_SET_NMEA_OUTPUT_ALLDATA "$PMTK314,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0*28" |
martin13 | 2:5e2336b52d0a | 33 | // turn off output |
martin13 | 2:5e2336b52d0a | 34 | #define PMTK_SET_NMEA_OUTPUT_OFF "$PMTK314,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28" |
martin13 | 2:5e2336b52d0a | 35 | |
martin13 | 2:5e2336b52d0a | 36 | // to generate your own sentences, check out the MTK command datasheet and use a checksum calculator |
martin13 | 2:5e2336b52d0a | 37 | // such as the awesome http://www.hhhh.org/wiml/proj/nmeaxor.html |
martin13 | 2:5e2336b52d0a | 38 | |
martin13 | 2:5e2336b52d0a | 39 | #define PMTK_LOCUS_STARTLOG "$PMTK185,0*22" |
martin13 | 2:5e2336b52d0a | 40 | #define PMTK_LOCUS_STOPLOG "$PMTK185,1*23" |
martin13 | 2:5e2336b52d0a | 41 | #define PMTK_LOCUS_STARTSTOPACK "$PMTK001,185,3*3C" |
martin13 | 2:5e2336b52d0a | 42 | #define PMTK_LOCUS_QUERY_STATUS "$PMTK183*38" |
martin13 | 2:5e2336b52d0a | 43 | #define PMTK_LOCUS_ERASE_FLASH "$PMTK184,1*22" |
martin13 | 2:5e2336b52d0a | 44 | #define LOCUS_OVERLAP 0 |
martin13 | 2:5e2336b52d0a | 45 | #define LOCUS_FULLSTOP 1 |
martin13 | 2:5e2336b52d0a | 46 | |
martin13 | 2:5e2336b52d0a | 47 | #define PMTK_ENABLE_SBAS "$PMTK313,1*2E" |
martin13 | 2:5e2336b52d0a | 48 | #define PMTK_ENABLE_WAAS "$PMTK301,2*2E" |
martin13 | 2:5e2336b52d0a | 49 | |
martin13 | 2:5e2336b52d0a | 50 | // standby command & boot successful message |
martin13 | 2:5e2336b52d0a | 51 | #define PMTK_STANDBY "$PMTK161,0*28" |
martin13 | 2:5e2336b52d0a | 52 | #define PMTK_STANDBY_SUCCESS "$PMTK001,161,3*36" // Not needed currently |
martin13 | 2:5e2336b52d0a | 53 | #define PMTK_AWAKE "$PMTK010,002*2D" |
martin13 | 2:5e2336b52d0a | 54 | |
martin13 | 2:5e2336b52d0a | 55 | // ask for the release and version |
martin13 | 2:5e2336b52d0a | 56 | #define PMTK_Q_RELEASE "$PMTK605*31" |
martin13 | 2:5e2336b52d0a | 57 | |
martin13 | 2:5e2336b52d0a | 58 | // request for updates on antenna status |
martin13 | 2:5e2336b52d0a | 59 | #define PGCMD_ANTENNA "$PGCMD,33,1*6C" |
martin13 | 2:5e2336b52d0a | 60 | #define PGCMD_NOANTENNA "$PGCMD,33,0*6D" |
martin13 | 2:5e2336b52d0a | 61 | |
martin13 | 2:5e2336b52d0a | 62 | // how long to wait when we're looking for a response |
martin13 | 2:5e2336b52d0a | 63 | #define MAXWAITSENTENCE 5 |
martin13 | 0:f4fdca2c4c67 | 64 | |
martin13 | 0:f4fdca2c4c67 | 65 | class Foo : public State{ |
martin13 | 0:f4fdca2c4c67 | 66 | |
martin13 | 0:f4fdca2c4c67 | 67 | public: |
martin13 | 0:f4fdca2c4c67 | 68 | |
martin13 | 0:f4fdca2c4c67 | 69 | static const char* OUTCOME_BAR; |
martin13 | 0:f4fdca2c4c67 | 70 | |
martin13 | 0:f4fdca2c4c67 | 71 | Foo(const char* uuid, UserData *ud): |
martin13 | 0:f4fdca2c4c67 | 72 | State(uuid){ |
martin13 | 0:f4fdca2c4c67 | 73 | /* Capture UserData, see in utt_foobar_with_ud.h example. */ |
martin13 | 2:5e2336b52d0a | 74 | |
martin13 | 2:5e2336b52d0a | 75 | gps_Serial = new RawSerial(D10, D2); |
martin13 | 2:5e2336b52d0a | 76 | gps_Serial->baud(9600); |
martin13 | 2:5e2336b52d0a | 77 | nnema = new char[129]; |
martin13 | 2:5e2336b52d0a | 78 | |
martin13 | 2:5e2336b52d0a | 79 | sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); |
martin13 | 2:5e2336b52d0a | 80 | sendCommand(PMTK_SET_NMEA_UPDATE_5HZ); |
martin13 | 2:5e2336b52d0a | 81 | sendCommand(PMTK_API_SET_FIX_CTL_5HZ); |
martin13 | 2:5e2336b52d0a | 82 | sendCommand(PGCMD_ANTENNA); |
martin13 | 2:5e2336b52d0a | 83 | } |
martin13 | 2:5e2336b52d0a | 84 | |
martin13 | 2:5e2336b52d0a | 85 | void sendCommand(const char *str) { |
martin13 | 2:5e2336b52d0a | 86 | gps_Serial->printf(str); |
martin13 | 0:f4fdca2c4c67 | 87 | } |
martin13 | 0:f4fdca2c4c67 | 88 | |
martin13 | 0:f4fdca2c4c67 | 89 | virtual void onEntry(){ |
martin13 | 0:f4fdca2c4c67 | 90 | /* Do something before onExecute() */ |
martin13 | 0:f4fdca2c4c67 | 91 | } |
martin13 | 0:f4fdca2c4c67 | 92 | |
martin13 | 0:f4fdca2c4c67 | 93 | virtual const char* onExecute(){ |
martin13 | 0:f4fdca2c4c67 | 94 | /* Do something */ |
martin13 | 2:5e2336b52d0a | 95 | |
martin13 | 2:5e2336b52d0a | 96 | int offset = 0; |
martin13 | 2:5e2336b52d0a | 97 | memset(nnema,'x',129); |
martin13 | 2:5e2336b52d0a | 98 | |
martin13 | 2:5e2336b52d0a | 99 | |
martin13 | 2:5e2336b52d0a | 100 | while(gps_Serial->readable()){ |
martin13 | 2:5e2336b52d0a | 101 | |
martin13 | 2:5e2336b52d0a | 102 | char c = gps_Serial->getc(); |
martin13 | 2:5e2336b52d0a | 103 | //Logger::info("%c",c); |
martin13 | 2:5e2336b52d0a | 104 | nnema[offset++] = c; |
martin13 | 2:5e2336b52d0a | 105 | } |
martin13 | 2:5e2336b52d0a | 106 | //nnema[++offset] = '\0'; |
martin13 | 2:5e2336b52d0a | 107 | |
martin13 | 2:5e2336b52d0a | 108 | Logger::info("%i = %s",offset, nnema); |
martin13 | 2:5e2336b52d0a | 109 | |
martin13 | 0:f4fdca2c4c67 | 110 | return OUTCOME_BAR; |
martin13 | 0:f4fdca2c4c67 | 111 | } |
martin13 | 0:f4fdca2c4c67 | 112 | |
martin13 | 0:f4fdca2c4c67 | 113 | virtual void onExit(){ |
martin13 | 0:f4fdca2c4c67 | 114 | /* Do something before exit state */ |
martin13 | 0:f4fdca2c4c67 | 115 | } |
martin13 | 2:5e2336b52d0a | 116 | |
martin13 | 2:5e2336b52d0a | 117 | private: |
martin13 | 2:5e2336b52d0a | 118 | RawSerial *gps_Serial; |
martin13 | 2:5e2336b52d0a | 119 | char* nnema; |
martin13 | 0:f4fdca2c4c67 | 120 | }; |
martin13 | 0:f4fdca2c4c67 | 121 | |
martin13 | 0:f4fdca2c4c67 | 122 | const char* Foo::OUTCOME_BAR = "OUTCOME_BAR"; |
martin13 | 0:f4fdca2c4c67 | 123 | |
martin13 | 0:f4fdca2c4c67 | 124 | class Bar : public State{ |
martin13 | 0:f4fdca2c4c67 | 125 | |
martin13 | 0:f4fdca2c4c67 | 126 | public: |
martin13 | 0:f4fdca2c4c67 | 127 | |
martin13 | 0:f4fdca2c4c67 | 128 | static const char* OUTCOME_FOO; |
martin13 | 0:f4fdca2c4c67 | 129 | |
martin13 | 0:f4fdca2c4c67 | 130 | Bar(const char* uuid, UserData *ud): |
martin13 | 0:f4fdca2c4c67 | 131 | State(uuid){ |
martin13 | 0:f4fdca2c4c67 | 132 | /* Capture UserData, see in utt_foobar_with_ud.h example. */ |
martin13 | 0:f4fdca2c4c67 | 133 | } |
martin13 | 0:f4fdca2c4c67 | 134 | |
martin13 | 0:f4fdca2c4c67 | 135 | virtual void onEntry(){ |
martin13 | 0:f4fdca2c4c67 | 136 | /* Do something before onExecute() */ |
martin13 | 0:f4fdca2c4c67 | 137 | } |
martin13 | 0:f4fdca2c4c67 | 138 | |
martin13 | 0:f4fdca2c4c67 | 139 | virtual const char* onExecute(){ |
martin13 | 0:f4fdca2c4c67 | 140 | /* Do something */ |
martin13 | 2:5e2336b52d0a | 141 | wait(1); |
martin13 | 0:f4fdca2c4c67 | 142 | return OUTCOME_FOO; |
martin13 | 0:f4fdca2c4c67 | 143 | } |
martin13 | 0:f4fdca2c4c67 | 144 | |
martin13 | 0:f4fdca2c4c67 | 145 | virtual void onExit(){ |
martin13 | 0:f4fdca2c4c67 | 146 | /* Do something before exit state */ |
martin13 | 0:f4fdca2c4c67 | 147 | } |
martin13 | 0:f4fdca2c4c67 | 148 | }; |
martin13 | 0:f4fdca2c4c67 | 149 | |
martin13 | 0:f4fdca2c4c67 | 150 | const char* Bar::OUTCOME_FOO = "OUTCOME_FOO"; |
martin13 | 0:f4fdca2c4c67 | 151 | |
martin13 | 0:f4fdca2c4c67 | 152 | class FooBar : public StateMachine{ |
martin13 | 0:f4fdca2c4c67 | 153 | |
martin13 | 0:f4fdca2c4c67 | 154 | public: |
martin13 | 0:f4fdca2c4c67 | 155 | |
martin13 | 0:f4fdca2c4c67 | 156 | FooBar(const char* uuid): |
martin13 | 0:f4fdca2c4c67 | 157 | StateMachine(uuid), |
martin13 | 0:f4fdca2c4c67 | 158 | foo(NULL), bar(NULL) |
martin13 | 0:f4fdca2c4c67 | 159 | { |
martin13 | 0:f4fdca2c4c67 | 160 | // States instance with StateMachine context |
martin13 | 0:f4fdca2c4c67 | 161 | foo = this->Instance<Foo>("FOO"); |
martin13 | 0:f4fdca2c4c67 | 162 | bar = this->Instance<Bar>("BAR"); |
martin13 | 0:f4fdca2c4c67 | 163 | |
martin13 | 0:f4fdca2c4c67 | 164 | // Connect Foo to Bar |
martin13 | 0:f4fdca2c4c67 | 165 | this->connect(STATE(foo), Foo::OUTCOME_BAR, STATE(bar)); |
martin13 | 0:f4fdca2c4c67 | 166 | |
martin13 | 0:f4fdca2c4c67 | 167 | // Connect Bar to Foo |
martin13 | 0:f4fdca2c4c67 | 168 | this->connect(STATE(bar), Bar::OUTCOME_FOO, STATE(foo)); |
martin13 | 0:f4fdca2c4c67 | 169 | |
martin13 | 0:f4fdca2c4c67 | 170 | // Set the first state calling when the state machine starts |
martin13 | 0:f4fdca2c4c67 | 171 | this->setInitialState(STATE(foo)); |
martin13 | 0:f4fdca2c4c67 | 172 | } |
martin13 | 0:f4fdca2c4c67 | 173 | |
martin13 | 0:f4fdca2c4c67 | 174 | private: |
martin13 | 0:f4fdca2c4c67 | 175 | Foo *foo; |
martin13 | 0:f4fdca2c4c67 | 176 | Bar *bar; |
martin13 | 0:f4fdca2c4c67 | 177 | }; |
martin13 | 0:f4fdca2c4c67 | 178 | |
martin13 | 0:f4fdca2c4c67 | 179 | // Preempt state mahine button |
martin13 | 0:f4fdca2c4c67 | 180 | InterruptIn button(PC_13); |
martin13 | 0:f4fdca2c4c67 | 181 | |
martin13 | 0:f4fdca2c4c67 | 182 | void unit_test(){ |
martin13 | 0:f4fdca2c4c67 | 183 | |
martin13 | 0:f4fdca2c4c67 | 184 | FooBar foobar("FOOBAR_SM"); |
martin13 | 0:f4fdca2c4c67 | 185 | |
martin13 | 0:f4fdca2c4c67 | 186 | button.rise(&foobar, &FooBar::preempt); |
martin13 | 0:f4fdca2c4c67 | 187 | |
martin13 | 0:f4fdca2c4c67 | 188 | foobar.printGraph(); |
martin13 | 0:f4fdca2c4c67 | 189 | |
martin13 | 0:f4fdca2c4c67 | 190 | Logger::info("STATE MACHINE FINISHED WITH OUTCOME \"%s\"",foobar.execute()); |
martin13 | 0:f4fdca2c4c67 | 191 | } |
martin13 | 0:f4fdca2c4c67 | 192 | |
martin13 | 0:f4fdca2c4c67 | 193 | |
martin13 | 0:f4fdca2c4c67 | 194 | #endif /* #ifndef __UTT_FOOBAR_H__*/ |