我正在通过串行读取传感器的值(加速度计值),循环类似于:
while( 1 ) {
vector values = getAccelerometerValues();
// Calculate velocity
// Calculate total displacement
if ( displacement == 0 )
print("Back at origin");
}
我知道每个样本所需的时间,这在getAccelerometerValues()
中得到了处理,所以我有一段时间来计算速度、位移等。我以大约120个样本/秒的速度采样。
这是可行的,但也存在缺陷(非精确的加速度计值、浮点误差等),并且校准和补偿以获得合理准确的位移值被证明是困难的。
我很难找到调试循环的进程。如果我使用调试器(我的代码恰好是用C++编写的,而且我正在慢慢学习使用gdb
而不是print
语句),那么在调试器执行行的时间点,我会遇到遍历和推动传感器以获取加速度计读数的问题。也就是说,很难确定"继续下一行"one_answers"推动传感器使其加速"的时间。
我可以使用很多print
语句,这些语句往往会在屏幕上掠过,但由于样本数量的原因,这会变得乏味,很难推导出问题所在,尤其是如果每个循环有多个print
语句。
我可以减少样本数量,这提高了程序输出的可读性,但大大降低了我从传感器轮询的加速度值的可靠性;如果我以1Hz进行轮询,在加速度计进行加速时轮询加速度计值的几率会显著下降。
总的来说,我在执行代码和使用实际数据时遇到了问题;我可以用无用的数据来完成它,或者我不能用更好的数据来真正完成它。
我假设print
语句不是该场景的最佳调试方法。什么是更好的选择?有没有我觉得有用的资源(gdb
是我遗漏了什么,还是我可以使用其他工具)?我正在努力开发一种方法来调试它。
一种明智的方法是为getAccelerometerValues()
使用一些可以在运行时或构建时替换的接口,例如在具体派生类中传递带有虚拟方法的基类指针来覆盖。
如果你需要的话,我可以更详细地描述这个机制,但理想的情况是能够对运行相同的循环
- 实时数据
- 真实的实时数据(并将其保存到文件中)
- 从上次运行中保存的罐装真实数据
- 你编造的虚假数据作为测试用例
特别要注意的是,如果每次调用只返回文件中的下一个数据,那么"重播"版本应该很容易调试。
为要调试的确切条件创建if块。例如,如果你只关心加速度计何时显示你正在向左移动:
if(movingLeft(values) {
print("left");
}
这个问题的常见解决方案是录制。您的以实时方式从传感器捕获样本序列,并将其存储到文件中。然后使用记录的数据训练系统、调试代码等。最后,您将工作代码连接到真实的数据流,该数据流立即从传感器流出。
我会先用假(即:随机)值调试代码,然后再做其他事情。如果计算工作如预期,那么我将使用从端口读取的值。
此外,难道没有一种方法可以以回调/推送的方式读取这些值吗?也就是说,当有新的可靠数据时,只调用函数?
edit:我不知道您使用的是什么库,但在.NET框架中,您可以将SerialPort
类与EventDataReceived
一起使用。这样,您就可以确保使用最实际、最可靠的数据。