1
0
Fork 0

gipy: v007

master
frederic wagner 2022-07-20 15:09:25 +02:00
parent f1c204c77a
commit e6b76cde31
4 changed files with 49 additions and 18 deletions

View File

@ -10,3 +10,8 @@
* Special display for points with steep turns * Special display for points with steep turns
* Buzz on points with steep turns and unlock * Buzz on points with steep turns and unlock
* Losing gps is now displayed * Losing gps is now displayed
0.07:
* We now use orientation to detect current segment
when segments overlap going in both directions.
* File format is now versioned.

View File

@ -1,12 +1,11 @@
- nearest_segment : use direction to disambiguate
- gps direction is weak when speed is low - gps direction is weak when speed is low
- add a version number to gpc files
- water points - water points
---> we group them following path by groups of cst_size and record segments ids marking limits ---> we group them following path by groups of cst_size and record segments ids marking limits
- store several tracks
- turn off gps when moving to next waypoint - turn off gps when moving to next waypoint
- store several tracks
- display average speed - display average speed
- dynamic map rescale - dynamic map rescale
- display scale (100m) - display scale (100m)

View File

@ -1,5 +1,7 @@
let simulated = false; let simulated = true;
let code_version = 7;
let code_key = 47490;
class Status { class Status {
constructor(path) { constructor(path) {
@ -36,11 +38,11 @@ class Status {
this.position = new_position; this.position = new_position;
// detect segment we are on now // detect segment we are on now
let next_segment = this.path.nearest_segment(this.position, Math.max(0, this.current_segment-1), Math.min(this.current_segment+2, path.len - 1)); let next_segment = this.path.nearest_segment(this.position, Math.max(0, this.current_segment-1), Math.min(this.current_segment+2, path.len - 1), this.cos_direction, this.sin_direction);
if (this.is_lost(next_segment)) { if (this.is_lost(next_segment)) {
// it did not work, try anywhere // it did not work, try anywhere
next_segment = this.path.nearest_segment(this.position, 0, path.len - 1); next_segment = this.path.nearest_segment(this.position, 0, path.len - 1, this.cos_direction, this.sin_direction);
} }
// now check if we strayed away from path or back to it // now check if we strayed away from path or back to it
let lost = this.is_lost(next_segment); let lost = this.is_lost(next_segment);
@ -147,7 +149,15 @@ class Status {
class Path { class Path {
constructor(filename) { constructor(filename) {
let buffer = require("Storage").readArrayBuffer(filename); let buffer = require("Storage").readArrayBuffer(filename);
this.points = Float64Array(buffer); let header = Uint16Array(buffer, 0, 3);
let key = header[0];
let version = header[1];
let points_number = header[2];
if ((key != code_key)||(version>code_version)) {
E.showMessage("Invalid gpc file");
return;
}
this.points = Float64Array(buffer, 3*2, points_number*2);
} }
// if start, end or steep direction change // if start, end or steep direction change
@ -189,18 +199,32 @@ class Path {
return new Point(lon, lat); return new Point(lon, lat);
} }
// return index of segment which is nearest from point // return index of segment which is nearest from point.
nearest_segment(point, start, end) { // we need a direction because we need there is an ambiguity
let min_index = 0; // for overlapping segments which are taken once to go and once to come back.
let min_distance = Number.MAX_VALUE; // (in the other direction).
nearest_segment(point, start, end, cos_direction, sin_direction) {
// we are going to compute two min distances, one for each direction.
let indices = [0, 0];
let mins = [Number.MAX_VALUE, Number.MAX_VALUE];
this.on_segments(function(p1, p2, i) { this.on_segments(function(p1, p2, i) {
// we use the dot product to figure out if oriented correctly
let distance = point.fake_distance_to_segment(p1, p2); let distance = point.fake_distance_to_segment(p1, p2);
if (distance <= min_distance) { let diff = p2.minus(p1);
min_distance = distance; let dot = cos_direction * diff.lon + sin_direction * diff.lat;
min_index = i - 1; let orientation = + (dot < 0); // index 0 is good orientation
if (distance <= mins[orientation]) {
mins[orientation] = distance;
indices[orientation] = i - 1;
} }
}, start, end); }, start, end);
return min_index; // by default correct orientation (0) wins
// but if other one is really closer, return other one
if (mins[1] < mins[0] / 10.0) {
return indices[1];
} else {
return indices[0];
}
} }
get len() { get len() {
return this.points.length / 2; return this.points.length / 2;

View File

@ -10,6 +10,9 @@ use gpx::Gpx;
mod osm; mod osm;
use osm::InterestPoint; use osm::InterestPoint;
const KEY: u16 = 47490;
const VERSION: u16 = 7;
#[derive(Debug, PartialEq, Clone, Copy)] #[derive(Debug, PartialEq, Clone, Copy)]
pub struct Point { pub struct Point {
x: f64, x: f64,
@ -328,8 +331,9 @@ fn save_coordinates<P: AsRef<Path>>(path: P, points: &[Point]) -> std::io::Resul
let mut writer = BufWriter::new(File::create(path)?); let mut writer = BufWriter::new(File::create(path)?);
eprintln!("saving {} points", points.len()); eprintln!("saving {} points", points.len());
// writer.write_all(&xmin.to_be_bytes())?; writer.write_all(&KEY.to_le_bytes())?;
// writer.write_all(&ymin.to_be_bytes())?; writer.write_all(&VERSION.to_le_bytes())?;
writer.write_all(&(points.len() as u16).to_le_bytes())?;
points points
.iter() .iter()
.flat_map(|p| [p.x, p.y]) .flat_map(|p| [p.x, p.y])
@ -502,7 +506,6 @@ fn detect_waypoints(points: &[Point]) -> HashSet<Point> {
if a <= std::f64::consts::PI / 3.0 || a >= std::f64::consts::PI * 5.0 / 3.0 { if a <= std::f64::consts::PI / 3.0 || a >= std::f64::consts::PI * 5.0 / 3.0 {
None None
} else { } else {
eprintln!("we have {}", (a2 - a1).abs());
Some(p2) Some(p2)
} }
})) }))