This repository contains a submodule. To clone with all submodules:
git clone --recurse-submodules https://github.com/DrPickle3/cleaned_spatial_pedagogy.gitIf you already cloned without submodules, initialize them with:
git submodule update --init --recursiveTo pull the latest changes from submodules:
git submodule update --remoteInstall the required Python packages:
pip install -r requirements.txt- ESP32 with DW1000 UWB module (Makerfabs ESP32 UWB)
- At least 2-3 anchors for positioning (3+ recommended for accuracy)
- 1 tag device
pio runpio run --target uploadpio device monitorAll Python scripts are located in the scripts/ directory.
To go in the directory :
cd scriptsTo go back a folder :
cd ..Receives UWB data from the Tag via TCP, computes positions using trilateration, and writes results to a CSV file.
cd scripts
python server.pyOptions:
| Flag | Description |
|---|---|
--display |
Show real-time turtle graphics visualization |
Example with display:
python server.py --displayNote: Requires a config.json file in the parent directory with anchor positions. The server uses mDNS (Zeroconf) for discovery on port 5000. The computer has to be connected to the same mobile hotspot the Tag is trying to connect. You will need a secrets.h file in src/ containing :
#pragma once
const char* WIFI_PASS = "spatial123";
const char* WIFI_NAME = "Spatial_Pedagogy";Change those credentials to whatever your hotspot is before pushing code in the Tag.
Runs the calibration GUI only.
Input: CSV + image
Output: experiment folder containing calibration artifacts (calibration_results.json, anchors_calibrated.json, processed_image.png, calibrated_points.csv)
cd scripts
python calibrer.py --csv ../logs/positions.csv --image ../images/Classe_Boisjoli.pngThe experiment folder is automatically created and stored at the root of the project under experiments/.
Applies an existing calibration to another CSV file without opening calibration GUI.
Input: CSV + calibration_results.json
Output: new experiment folder containing calibrated_points.csv and transform_metadata.json
cd scripts
python transformer.py --csv ../logs/positions.csv --experiment ../experiments/experiment_name/Displays trajectory visualization from recorded CSV data with various analysis options.
cd scripts
python visualiser.pyOptions:
| Flag | Description |
|---|---|
--csv <path> |
Path to CSV file (default: ../logs/positions.csv) |
--image <path> |
Path to background image in the viewer |
--heatmap |
Display heatmap of position density |
--stops |
Detect and display stops in the trajectory |
--precision |
Show precision statistics (for stationary measurements) |
--trail <n> |
Number of past positions to show (default: 10) |
--max_time_diff <s> |
Max time between positions in seconds (default: 0.2) |
--experiment <path> |
Use an existing experiment folder for visualization |
When --experiment is used, the viewer automatically uses calibrated_points.csv, processed_image.png, and anchors_calibrated.json from that folder when they exist.
Examples:
# Basic visualization
python visualiser.py --csv ../logs/positions.csv
# Visualization with background image and stop detection (Not calibrated)
python visualiser.py --csv ../logs/positions.csv --image ../images/Classe_Boisjoli.png --heatmap --stops
# Visualization directly from an experiment folder (calibrated points)
python visualiser.py --experiment ../experiments/experiment_name_transformed/ --heatmap --stops
# IMPORTANT !!!! If pressing tab do not autocomplete the experiment name, enter
cd scriptsCalculates and displays the mean measured range for each anchor from a CSV file.
cd scripts
python meanRange.pyOptions:
| Flag | Description |
|---|---|
--csv <path> |
Path to CSV file (default: ../logs/positions.csv) |
Example:
python meanRange.py --csv ../logs/positions.csvComputes antenna delay corrections for 3 devices (1 tag + 2 anchors) using triangle measurements.
cd scripts
python antDelayTriangle.pyBefore running: Edit the script to set your measured and true distances:
true_distances = {
('Tag', 'Anchor1'): 3.6068, # meters
('Tag', 'Anchor4'): 3.8608,
('Anchor1', 'Anchor4'): 2.5400
}
measured_distances = {
('Tag', 'Anchor1'): 4.092,
('Tag', 'Anchor4'): 4.262,
('Anchor1', 'Anchor4'): 2.664
}true_distances are the distances measured using a measuring tape in the real world. measured_distances are ranges measured by the sensors (mean value of stationary system).
Note When all of your sensors are not calibrated, you have to put a Tag and 2 anchors in a triangle and keep the mean range of both distances. Then push Tag code in one of the anchor to get the 3rd side of the triangle. Try to not move at all the position of the anchor that will temporarily be a tag. When you have those 3 devices calibrated, just use the tag and a non-calibrated anchor at a time using the single line method right under.
Computes antenna delay for a single anchor using one known distance.
cd scripts
python antDelaySingleLine.pyBefore running: Edit the script with your measurements:
true_distance = 3.37 # real distance in meters
measured_distance = 3.181 # measured distanceMain configuration file with anchor positions (x, y, z in meters):
{
"anchors": {
"AAA1": [6.8834, 0.635, 0.0],
"AAA2": [10.9982, 4.9784, 0.0],
"AAA3": [10.9982, 0.0, 0.0]
}
}Alternative configs available:
config_boisjoli.jsonconfig_brin_univers.jsonconfig_square.json
In the DW1000 original library, it does not support having a 5th anchor connected to a tag. We have to manually change the library code to adapt it to our case. We need to modify 2 different files :
At the line 172, there is this line
#ifndef ESP8266I changed it to (to support esp32)
#ifdef ESP8266Added a check if we can add the new device in the array before doing it. (line 243)
if(_networkDevicesNumber + 1 <= MAX_DEVICES && addDevice)- Setup anchors - Place anchors and measure their positions
- Configure - Update
config.jsonwith anchor coordinates - Start server - Run
python server.py - Collect data - Move the tag around
- Visualize - Use
python visualiser.pyto analyze results
- Calibrate antennas - Use
antDelayTriangle.pyorantDelaySingleLine.py - Flash devices - Use
pio run --target uploadwhile the anchor/tag is plugged in a USB port
Note You really have to put the credentials in a new file named secrets.h in src/ before pushing any code to any hardware. There is an example above.
1545
When I did my precision 1d, the server goes timeout because it doesn't receive anything from the Tag but it's because there are no anchors not because we lost connection to the Tag. We probably want to investigate this further... For now I just put the timeout to 800 seconds instead of 8 seconds.
Maybe we want to specify a certain configuration file to choose which group of anchor positions we want to display using the visualizer.
Next step of this project would be to develop a real GUI application to be really user friendly. With this current setup, we need to understand a little bit of python and be able to use the terminal with common bash commands.