Как стать автором
Обновить

Комментарии 13

Конечно есть, уйма их:


  1. Bucher, R., Misra, D., A Synthesizable VHDL Model of the Exact Solution for Three-dimensional Hyperbolic Positioning System, VLSI Design, Volume 15/2, 2002, pp. 507-520.
  2. Упомянутый вами Fang: B. T. Fang, «Simple solutions for hyperbolic and related position fixes,» in IEEE Transactions on Aerospace and Electronic Systems, vol. 26, no. 5, pp. 748-753, Sept. 1990.
  3. «An Algebraic Solution of the GPS Equations», Stephen Bancroft, IEEE Transactions on Aerospace and Electronic Systems, Volume: AES-21, Issue: 7 (Jan. 1985), pp 56–59.
  4. “A direct solution to GPS-type navigation equations”, L.O. Krause, IEEE Transactions on Aerospace and Electronic Systems, AES-23, 2 (1987), pp 225–232.

В реальной жизни только это особо не применимо, как я уже упомянул в статье, из-за зашумленных измерений.

1. Аналитика даст более точное первоначальное приближение.
2. Можно использовать рекомбинацию троек и найти тройку с минимальной невязкой за меньшую стоимость вычислений по сравнению численно-итеративным способом.

Вполне возможно, в некоторых случаях. Решение тогда будет более узкоспециализировано, конечно.

еще можно отбросить тройки дающие максимальную ошибку и переформировать функцию невязки без них. Это даст еще более точный ответ.
А как это все применить в координатах, которые использует Росреестр (МСКxx)?

Я этой темой специально не занимался. Если ничего не путаю, МСКхх это прямоугольные системы координат, построенные от разных географических точек. Собственно, применять это все в них наверное не нужно. Максимум — переводить из мск в мировую и назад. Но это скорее вопрос базы данных этих самых МСК

pub fn eps_tdoa3d(base_lines: &Vec<(f64, f64, f64, f64, f64, f64, f64)>, x: f64, y: f64, z: f64) -> f64

Я не эксперт в Расте, но это выглядит очень странно.
Во-первых, зачем ссылка на вектор, если есть слайс &[T]?
Во-вторых, зачем внутри вектора такой некрасивый кортеж, если это по сути просто двумерный массив (как в примере на других языках)?
Я тоже не эксперт в Rust — это мой hello world на нем =)
На самом деле массив только в матлабе передается, и я сказал об этом в статье. В C# передается массив структур. Кортеж в этом смысле гарантирует что в функцию не передадут массив 100х100 или что-то несуразное. Т.к. функция невязки вызывается часто, то не хочется внутри ничего проверять.
В любом случае, можете сделать форк и улучшить реализацию.

В расте есть массивы с фиксированным количеством элементов, т.е. более идиоматично было бы написать это, например, так:


pub fn eps_tdoa3d(base_lines: &[[f64; 4]], point: [f64; 3]) -> f64

Либо используя nalgebra вообще переписать как:


pub type Point = nalgebra::geometry::Point3<f64>;

pub struct BasePoint {
    point: Point,
    dist: f64,
}

pub fn eps_toa3d(base_points: &[BasePoint], point: Point) -> f64 {
    base_points.iter()
        .map(|bp| (bp.point - point).norm() - bp.dist)
        .sum()
}
Благодарю! Первая мысль выглядит очень дельной. На счет подцепить nalgebr-у — это то, от чего я изначально старался уйти — цеплять лишние зависимости. Объявить структуры я мог бы и сам (что и сделал в первичной реализации на C#). Теперь смотрю на это как на некий костыль. Дело в том, что базовая точка помимо координат не обязательно имеет свойством дальность, вместо нее может быть время прихода. По сути это такая же структура с полем f64, но с которым работа идет иначе. Поэтому я решил не притягивать за уши сущности.

Как с C# не знаю, но вот сравнение с Матлабом без использования специализированных матричных библиотек, вероятно, будет нечестным. Кроме того, в Расте умышленно используется достаточно маленькая стандартная библиотека, поэтому без использования внешних зависимостей вы далеко с ним не уйдёте. Благо подключение зависимостей и их использование в Расте это сущее удовольствие. Т.к. nalgebra (либо аналоги попроще) позволяет значительно сократить кол-во бойлерплейта, то называть данную зависимость лишней я бы не стал.


Про объявление структур советую внимательно подумать, их использование не только позволяет сокращать количество бойлерплейта как в моём примере, и тем самым сокращать вероятность ошибок (явные имена полей этому тоже способствуют), но и позволяет лучше и быстрее понимать код не только другим людям, но и вам после того как вы к нему вернётесь через какое-то время. Разумеется, тут нужно соблюдать меру, но лично мне разбираться в вашем коде было достаточно сложно.

Спасибо вам за участие и дельные советы. Я практически под каждым словом подпишусь и сам — про именованные поля, читаемость кода. Что до зависимостей — вы верно подметили про меру. Если я вас правильно понял, то вы говорите о балансе. Возможно, в ближайшем будущем я последую вашему совету и немного перепишу библиотеку.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории