[智能交通]step1:从原始GPS数据计算位置

本文详细介绍了GPS定位的基础知识,包括坐标系统的定义,如经纬度和ECEF坐标系,以及高度的不同定义。讨论了如何将大地坐标转换为平面坐标,并阐述了确定卫星位置和计算用户与卫星距离的方法。此外,还提到了伪距离的概念,以及在考虑卫星和用户时钟偏差的情况下估算用户位置的过程。

前言

以下内容来自以下网站
Calculating Position from Raw GPS Data

第一部分

坐标系统的定义

需要满足的条件:

  • 为了便于数学计算,需要坐标之间的单位差表示恒定的物理距离
  • 由于地球是旋转的,需要一个惯性坐标系统来表达加速度、位置和速度向量

下面介绍几种坐标系。

1、经纬度

两个经度之间的单位差表示的物理距离不是恒定的,取决于位置。例如,两个经度相距一度的距离在赤道最大,在两极接近0。
图1
2、ECEF(WGS 1984系统)

“ECEF”(地球中心,地球固定)。这些坐标系统能够很好地表达用户在与地球旋转时在地球上的位置,而固定用户在地球表面的位置是恒定的。

定义如下:

  • 地球质量中心的起源 z轴穿过CTP(常规陆地极)。CTP 是 1900 年至 1905
  • 年间地球极点位置的平均值。平均需要使用,因为极点的位置不是固定的,在半径约15米的圆圈中徘徊。 x 轴穿过 CTP
  • 赤道平面和参考子午线的交叉点,通常称为平均格林威治子午线
你遇到的错误: ``` error: 'int seqStack::top' is private within this context int sandwich = san.top(); ^~~ note: declared private here int top; ^~~ error: expression cannot be used as a function int sandwich = san.top(); ^ ``` --- ## ❌ 错误原因分析 这两个错误说明了一个关键问题: 你的 `seqStack.h` 中 **直接把 `top` 定义为一个私有的成员变量**,而不是提供一个名为 `top()` 的公共成员函数! ### 从报错信息看: ```cpp int top; // ← 这是一个私有变量!不是函数! ``` 而你在代码中写了: ```cpp san.top(); // ← 你以为这是调用函数,但实际上: // 1. top 是变量(不能加括号) // 2. 它是 private,无法访问 ``` 所以编译器报错: - `top` 是私有成员,不能在类外访问 → 第一个错误 - `top()` 被当作函数调用,但 `top` 不是函数 → 第二个错误:“expression cannot be used as a function” --- ## ✅ 正确设计方式:栈应提供 `Top()` 或 `top()` 成员函数 你应该通过一个 **公共成员函数** 来获取栈顶元素,比如: ```cpp int top() const { return data[topIndex]; } ``` --- ## ✅ 解决方案(两种情况) --- ### ✅ 情况一:你可以修改 `seqStack.h` > 如果你能编辑头文件,请将 `top` 变量改为私有,并添加 `top()` 函数。 #### ✅ 修改后的 `seqStack.h` 示例: ```cpp // seqStack.h #ifndef SEQSTACK_H #define SEQSTACK_H template<class T> class seqStack { private: T* data; // 存储数据 int maxSize; // 最大容量 int topIndex; // 栈顶索引 public: seqStack(int size = 100) { data = new T[size]; maxSize = size; topIndex = -1; } ~seqStack() { delete[] data; } void push(const T& x) { if (topIndex >= maxSize - 1) { // 可选:扩容或报错 throw "Stack overflow"; } data[++topIndex] = x; } void pop() { if (empty()) { throw "Stack underflow"; } --topIndex; } T top() const { // ✅ 公共函数返回栈顶值 if (empty()) { throw "Stack is empty"; } return data[topIndex]; } bool empty() const { return topIndex == -1; } int size() const { return topIndex + 1; } }; #endif ``` 然后你就可以安全使用: ```cpp int sandwich = san.top(); // ✅ 正确:调用的是函数 ``` --- ### ✅ 情况二:你不允许修改 `seqStack.h`(常见于实验平台) > 有些在线评测系统不让你改头文件,但提供了其他接口。 请检查原始 `seqStack.h` 是否有类似以下函数: - `getTop()`? - `peek()`? - 或者虽然有 `top` 变量,但有 `T TopElement()` 等函数? #### 🔍 常见替代写法(根据实际头文件调整): 例如,如果原 `seqStack.h` 提供了: ```cpp T getTop() const; // 获取栈顶元素 ``` 那你应该写成: ```cpp int sandwich = san.getTop(); // ✅ 而不是 san.top() ``` 或者如果是 `TopElement()`: ```cpp int sandwich = san.TopElement(); ``` --- ## 🚫 绝对不要这样写(错误示范): ```cpp int sandwich = san.top; // ❌ 即使改成点变量也不行,因为 top 是 private ``` 即使去掉括号,也违反封装原则,且仍是私有成员,无法访问。 --- ## ✅ 当前最可能正确的写法(假设你不能改头文件) 👉 你需要查看 `../seqStack.h` 文件内容,找到是否有以下函数之一: | 常见函数名 | 推荐写法 | |------------------|------------------------------| | `getTop()` | `san.getTop()` | | `TopElement()` | `san.TopElement()` | | `peek()` | `san.peek()` | | `front()` | 极少见 | --- ## ✅ 临时解决方案(如果你不知道函数名是什么) 打开 `../seqStack.h` 文件,查找类似下面的声明: ```cpp T getTop() const; ``` 或 ```cpp T TopElement() const { return data[topIndex]; } ``` 然后在主函数中使用它! --- ## ✅ 假设函数叫 `getTop()`,则正确代码片段如下: ```cpp /********** Begin *********/ while (!san.empty() && !stu.empty()) { int student = stu.getHead(); // 队列前端学生 int sandwich = san.getTop(); // ✅ 使用 getTop() 获取栈顶 if (student == sandwich) { stu.deQueue(); san.pop(); // pop 移除栈顶 } else { stu.enQueue(stu.deQueue()); } // 检查是否还有人能吃当前三明治 bool canEat = false; int sz = stu.size(); seqQueue<int> tempQueue; for (int i = 0; i < sz; ++i) { int s = stu.deQueue(); tempQueue.enQueue(s); if (s == sandwich) { canEat = true; } } while (!tempQueue.empty()) { stu.enQueue(tempQueue.deQueue()); } if (!canEat) { break; } } cout << stu.size() << endl; /********** End **********/ ``` --- ## ✅ 总结:你现在要做的事 1. ✅ 打开 `../seqStack.h` 文件 2. ✅ 查找是否有 `getTop`, `TopElement`, `peek` 等函数 3. ✅ 用那个函数代替 `san.top()` 4. ✅ 确保所有语句都在 `main()` 函数的大括号 `{}` 内部 5. ✅ 不要试图直接访问 `top` 成员(它是私有的) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值