AWOL Box: Difference between revisions
(→Format) |
(→Format) |
||
Line 63: | Line 63: | ||
| 8-11 || Radius || Radius - The intended distance between the box and the target coordinates. For example, the box can be programmed such that if the true distance between the box and the target is less than the radius, success is achieved. | | 8-11 || Radius || Radius - The intended distance between the box and the target coordinates. For example, the box can be programmed such that if the true distance between the box and the target is less than the radius, success is achieved. | ||
|- | |- | ||
| 12 || frametime || Number of seconds to display information when success ''is not'' met. If success is reached within this time, the box executes the desired success routine. Otherwise, the attempt ends.<br>If frametime== | | 12 || frametime || Number of seconds to display information when success ''is not'' met. If success is reached within this time, the box executes the desired success routine. Otherwise, the attempt ends.<br>If frametime==0, then the attempt lasts forever. | ||
|- | |- | ||
| 13 || tgtmode || Target mode - defines what to do when the success condition is met. Valid values are:<br>0 - Do nothing<br>1 - Open the box, then load the target specified by nxtgt<br>2 - Load the target specified by nxtgt | | 13 || tgtmode || Target mode - defines what to do when the success condition is met. Valid values are:<br>0 - Do nothing<br>1 - Open the box, then load the target specified by nxtgt<br>2 - Load the target specified by nxtgt | ||
Line 75: | Line 75: | ||
| 17 || cost || Number of credits it costs to begin an attempt. | | 17 || cost || Number of credits it costs to begin an attempt. | ||
|- | |- | ||
| 18 || susmode || Success mode - Defines ''what is'' success. Valid values are<br>0 - Success is never met<br>1 - Success is always met<br>2 - If distance between box and target coordinates is less than radius<br>3 - If distance between box and target is greater than radius<br>4 - if current block is solved inside radius (block states changes to solved when condition is met, and target is solved when all enabled block points are solved.)<br>5 - no achievable criteria, but calculates distance as closest distance to gpoints path | | 18 || susmode || Success mode - Defines ''what is'' success. Valid values are<br>0 - Success is never met<br>1 - Success is always met<br>2 - If distance between box and target coordinates is less than radius<br>3 - If distance between box and target is greater than radius<br>4 - if current block is solved inside radius (block states changes to solved when condition is met, and target is solved when all enabled block points are solved.)<br>5 - no achievable criteria, but calculates distance as closest distance to gpoints path<br>255 - Uses the box as a GPS logger, with frametime as the time interval between taking data. | ||
|- | |- | ||
| 19 || miscB || Miscellaneous variable. Not presently used. | | 19 || miscB || Miscellaneous variable. Not presently used. |
Revision as of 00:05, 9 December 2018
The AWOL boxes are a type of reverse-geocache type device. The boxes consist of a motorized latch, GPS receiver, card reader, display, and a single exterior button. The device has several different modes, such as opening when the box reaches a target. Current version is 2.5.
Overview
Hardware
The boxes use an ESP8266 as the main processor, which has just enough pins to do what I need it to do. This chip was picked mostly because of it's more powerful processor, larger amount of RAM, and more storage space compared to some of the smaller Arduino micros I've been using. As a side effect of this, the boxes have Wifi capability, allowing me to program the boxes even while still closed, with no physical connection between them. The filesystem means that I can store settings inside files inside the device, and don't need to re-upload firmware every time I want to change the target location. I have provided a web interface when the box's Wifi is turned on, so that all I need to program the box is a computer with a web browser, no special programs are required.
Settings
The boxes are programmed by a few configuration files stored on the device, so that one does not need to upload an entire new firmware if you need to change just one thing. Any item that might need to be changed is stored in a configuration file.
The boxes have three main nonvolatile variables that control the game.
- A "status" or "lock" variable that keeps track of whether the box is either locked closed or can be opened freely.
- A "credits" variable that tracks the number of credits
- A "target" variable, which stores settings such as what the objective is, where the target location is, what to display during an attempt, how many credits the attempt costs, etc.
There are also a few other "read only" files that store things like the box's ID number, the conversion from meters to whatever units you want, the open/close values for the latch servo, and the wifi password.
Files
Below is a table listing all files on the device. "Read only" files are files that are never written to by the box in operation, they can of course be changed when configuring it.
Filename | Read/Write | Discription |
---|---|---|
aconf.bin | R | Stores the servo open/close setting, ID number of the box, group bit of the box, and unit name and conversion from meters (Eg. "Tads" , 0.35486913 - Multiplying a value in meters by this will convert it to tads.) |
bconf.bin | RW | Stores the current "solveMode" (whether the box is locked closed or it can be opened freely), the current target file number, and the number of credits. |
targetn.bin | RW | Stores everything you need to know about the box's current objective. Only written to when settings are loaded from a card. |
blockn.bin | RW | Addition to targetn.bin for using multiple sets or coordinates. Stores 10 lat/long coordinates and enable/disable bytes. |
wifi.asc | R | Stores the Wifi SSID and password to connect to. When in Wifi mode, the box tries to connect to this AP, and if it can't find it, it will make it's own. This is so your computer can stay connected to the internet while still accessing the box on the same network. |
splash.asc | R | Contains text that is shown on the LCD on boot, like "Wintercamp XLI" |
log.bin | RW | When an attempt is begun, the box stores the GPS location of the box in this file. It also serves as the attempt counter, by measuring the size of the file. |
rlog.bin | W | Similar to log.bin, but stores location and time when a target is reached. Also stores the target number, for identification. |
log.kml | W | In the web-config page, you can generate this KML file from the targetn.bin files and the log.bin file, which can then be viewed in google earth. |
Targetn.bin
The targetn.bin file is a configuration file that stores information about what the objective is, and what you need to do to reach that objective. When the objective is reached, it tells the box what to do next also. Each targetn.bin files has one objective, and it is in use only when working on that part of the puzzle. If the box is currently using target #15, it will load "target15.bin" and so forth.
Organization
The target files have four main variable types:
- Variables that define a reference quantity/location; eg. "15 tads", "3 credits", geo-coordinates of a location, etc.
- Variables that define what the objective is; eg. "When box is within [15 tads] of [a location], then success"
- Variables that define what to do when the objective criteria is not met; eg. what information to display on the screen and for how long
- Variables that define what to do after the criteria is met; eg. "Display a message for 15 seconds, then load target #12" or "Open the box, and say `You win` for 10 seconds"
Format
The format of the physical file is designed to closely follow the format of the cards, so I don't accidentally store more variables than the card can hold. The table below shows what is stored.
Location (bytes) | Variable name | Desciption |
---|---|---|
0-3 | Latitude coordinate | IEEE 754 float of latitude. |
4-7 | Longitude coordinate | IEEE 754 float of longitude. |
8-11 | Radius | Radius - The intended distance between the box and the target coordinates. For example, the box can be programmed such that if the true distance between the box and the target is less than the radius, success is achieved. |
12 | frametime | Number of seconds to display information when success is not met. If success is reached within this time, the box executes the desired success routine. Otherwise, the attempt ends. If frametime==0, then the attempt lasts forever. |
13 | tgtmode | Target mode - defines what to do when the success condition is met. Valid values are: 0 - Do nothing 1 - Open the box, then load the target specified by nxtgt 2 - Load the target specified by nxtgt |
14 | nxtgt | Stores the number of the next target to be loaded. Used only when success is defined to do this by tgtmode. |
15 | dispmode | Display mode - defines what to display when the success condition is not met. Valid values are 0 - Display nothing (too evil to use) 1 - Display distance to target 2 - Display angle between direction of travel and vector to target, in degrees. An angle of 0 means you are heading right towards the target coordinates; positive angles means the target is counterclockwise of your direction of travel; negative angles mean the target is clockwise of your direction of travel.) 3 - Distance and angle to target coordinates 4 - Radius minus distance. Used in susmode 3 when inside circle. |
16 | wmsgTime | Time to display the win message. This operates independently of tgtmode or the success definition. |
17 | cost | Number of credits it costs to begin an attempt. |
18 | susmode | Success mode - Defines what is success. Valid values are 0 - Success is never met 1 - Success is always met 2 - If distance between box and target coordinates is less than radius 3 - If distance between box and target is greater than radius 4 - if current block is solved inside radius (block states changes to solved when condition is met, and target is solved when all enabled block points are solved.) 5 - no achievable criteria, but calculates distance as closest distance to gpoints path 255 - Uses the box as a GPS logger, with frametime as the time interval between taking data. |
19 | miscB | Miscellaneous variable. Not presently used. |
20 | miscC | Miscellaneous variable. Not presently used. |
21 - 24 | bspeed | IEEE 754 float not presently used. Could be used for storing speed. |
25 - 57 | wmsg | Win message. If wmsgTime is greater than zero, display this message for wmsgTime seconds. |
blockn.bin
This file stores 10 extra sets of lat/lon coordinates, and enabled/disabled status for each of the 10 sets. This is used in conjunction with targetn.bin, with susmode=4. This behaves essentially the same as susmode=2, where the objective is to get within a certain distance of the coordinates, but in this mode, the physically nearest coordinate set is auto-selected and displayed to the user. Reaching the currently selected coordinates (by getting closer than the radius value in targetn.bin) will end the attempt and disable those coordinates in blockn.bin. The next attempt continues with the remaining enabled coordinates, and this continues until all coordinates are disabled, at which point the target is marked as solved.
Format
The storage of the lat/lon sets is essentially the same as in targetn.bin. The important part is the enable byte, which defines which coordinate sets are to be used. To enable a coordinate set, set enable to 1. Any other value will deactivate the set. In practice, when an active set is solved during an attempt, the system will change the enable byte to '2'. If you set unused slots to enable=0, you will know which slots have been used in the game because they will all have an enable value of 2. making it easy to reset the game.
log.bin
This file logs the GPS location and GPS time whenever the user begins an attempt. A couple other administrator test functions will log the GPS location to a file, turning the box into a GPS logger.
Data appears as a series of these
Location (bytes) | Name | Description |
---|---|---|
0-3 | Latitude | IEEE 754 float - latitude coordinate |
4-7 | Longitude | IEEE 754 float - longitude coordinate |
8 | hour | Hours - GPS time |
9 | minutes | Minutes - GPS time |
10 | seconds | Seconds - GPS time |
gpoint.csv
The file contains a list of 128 lat/lng points, for general purpose modes that need a lot of points (like a path). This is a CSV file with 2 fields. The first field is longitude, and the second field is latitude. This matches Google Earth KML order. The end of the line must be terminated with a newline (/n), and there must be at least 128 lines. If you don't have that many points, just use points that are outside the limits of normal lat/lon ranges, and they will be ignored (but they will be loaded). An example of what the file looks like is shown below.
-83.27916731446868,42.89518328167484 -83.21280764912211,42.92421565018912 -83.175404748997,42.8843681112614 -83.16637918496383,42.92545538497605 -83.18245634824469,42.94563851558142
Functions (internal)
Shortest distance to a path (v2.5)
- Working on new custom library (EarthCC - Earth Coordinate Calculator) which does great circle distance and some other stuff.
- Added three new features to the main program for WC XLII:
gpoints[2][128]
A float which stores 128 lat/long coords. This uses up exactly 1K of space. This is general purpose for anything that needs a lot of lat/lng points.
loadgpoint()
Function which loads a CSV file which contains 128 lat/long coords, called "/gpoint.csv", into the gpoints[][] variable. This is the first time I have used any kind of CSV file on esp8266. The file needs to be formatted with 2 fields per line, terminated with a newline, like -83.18245278167166,42.8644903150357\n. Format places longitude first, then latitude, which is the same order that Google Earth KML files have, so you can easily copy data between them. This means that gpoints[0][] will get the lng coord, and gpoints[1][] will get the lat coord. The file also needs to be 128 lines long or longer, because the program expects to load all 128 sets, with no error checking (yet).
gpointPathClosest()
Function which returns the distance from the GPS receiver to the nearest point on a path. The path is defined by the series of points in gpoints[][], with gpoints[][0] as the first point. This was created for the WC XLII perimeter hike. The easiest way to make a path using is the path tool in Google Earth, saving the KML, and extracting the points into the gpoint.csv file. If you have less than 128 points in the path, just fill the rest of the file with 500,500\n, because points outside the range for lat/lng points are ignored.
How it works
First, I use a function of EarthCC, which calculates a point (D) on a line segment (AB) which is closest to a third point that is not on the line segment (C). This process works by scaling the lat/lng points onto a square grid (this is an approximation), where it draws a tangent line on the line segment, which goes through the third point, and then finds the location of the other end of the tangent line (which is on or in line with the original line segment). Then, we undo the scaling to get the geo-coordinates of point D. The function can also tell if the point found is actually still contained within the original line segment, or is off of it.
I use this function stepping through all the line segments of the path. For those that generate a D point that is on the line segment, I calculate the distance between D and the GPS receiver with the great circle distance (also in EarthCC). The smallest of these distances is taken as a candidate for the shortest distance to the path.
Finally, I calculate the distances between the GPS receiver and every endpoint of the path line segments. If the smallest of these distances is smaller than the candidate point from earlier, then we know that this point is actually the closest on the path to the GPS receiver.
Operation
Home screen
The box is turned on, and it loads the current targetn.bin file. A "home" screen is shown to the user, which displays the current target number and the number of credits.
Attempts
When the user begins an attempt (by pressing the button once), the box checks if a GPS signal is available. If isn't, it will display a message and wait The user can cancel by pressing the button again, and no credits will be used. If it is, the box updates the credits value given the current credit cost defined by the current target. Then, it checks the success condition once a second, as often as the GPS data comes in. If the success condition is met, it does the success action. If it is not met, it displays something specified by the not-success action. If the success condition is not met within a certain amount of time, the attempt ends, and the box returns to home. However, if the box loses GPS signal during the attempt, it will pause the timeout timer and wait for a GPS signal. If the button is pressed at any time after the attempt has started, it will end it and return to the home screen.
If the box's number of credits is less than the cost for one attempt, the box will display "Not Enough Credits"