平滑 运行 系统中的噪声同时收敛于初始未知常数的算法
Algorithm to smooth out noise in a running system while converging on an initially unknown constant
我正在尝试消除稍微异常情况下的噪音。可能有一个通用算法可以解决我的问题,但我不知道它是什么。
我目前正在建造一个机器人 telescope 坐骑。为了跟踪天空的运动,坐骑每秒拍摄一次天空照片,并跟踪它能看到的星星的 X、Y 和旋转的变化。
如果我只使用原始测量值来跟踪旋转,输出会不稳定且嘈杂,如下所示:
使用原始旋转测量值进行指导:
如果我使用低通滤波器,安装座会过冲并且永远不会完全稳定下来。较低的 Beta 值对此有帮助,但修正速度太慢且误差会累积。
使用低通滤波器进行引导:
(两张图中,紫色为天空和坐骑旋转的差异,红色为坐骑的修正旋转。)
移动平均线与低通滤波器有同样的问题。
关于问题的更多信息:
- 对于给定的天空区域,星星的旋转将是恒定的。然而,我们不知道我们在哪里,并且由于大气抖动,天空旋转的测量非常嘈杂,因此算法必须在引导时朝着这个最初未知的常数值努力。
- 坐骑可以在一秒内移动到需要的距离,并且有自己的控制系统。所以我不认为这是PID回路控制系统的问题。
- 前 30 秒左右引导不佳(或根本不引导)是可以的。
我写了一个 Python 小程序来模拟这个问题 - 我想也可以把它包括在这里。这个目前正在使用低通滤波器。
#!/usr/bin/env python3
import random
import matplotlib.pyplot as plt
ROTATION_CONSTANT = 0.1
TIME_WINDOW = 300
skyRotation = 0
mountRotation = 0
error = 0
errorList = []
rotationList = []
measurementList = []
smoothData = 0
LPF_Beta = 0.08
for step in range(TIME_WINDOW):
skyRotation += ROTATION_CONSTANT
randomNoise = random.random() - random.random()
rotationMeasurement = skyRotation - mountRotation + randomNoise
# Lowpass filter
smoothData = smoothData - (LPF_Beta * (smoothData - rotationMeasurement));
mountRotation += smoothData
rotationList.append(smoothData)
errorList.append(skyRotation - mountRotation)
measurementList.append(rotationMeasurement)
plt.plot([0, TIME_WINDOW], [ROTATION_CONSTANT, ROTATION_CONSTANT], color='black', linestyle='-', linewidth=2)
plt.plot(errorList, color="purple")
plt.plot(rotationList, color="red")
plt.plot(measurementList, color="blue", alpha=0.2)
plt.axis([0, TIME_WINDOW, -1.5, 1.5])
plt.xlabel("Time (seconds)")
plt.ylabel("Rotation (degrees)")
plt.show()
有谁知道如何使这个收敛的比较顺利(或者可以推荐相关的学习资源),不胜感激。我很乐意阅读有关该主题的内容,但到目前为止还没有弄清楚要寻找什么!
我会首先尝试通过使您的控制输出 PID 的结果,然后按照例如https://robotics.stackexchange.com/questions/167/what-are-good-strategies-for-tuning-pid-loops 或来自您最喜欢的网络搜索。
大多数其他方法都要求您对情况有一个准确的模型,包括受控硬件对您的控制输入的响应,因此您的下一步可能是通过实验来尝试解决这个问题,例如通过尝试计算出对简单测试输入(例如脉冲或阶跃)的响应。有了模拟器后,您至少可以在模拟器上比在真实硬件上更快速、更安全地调整建议方法的参数。
如果您的模拟器是准确的,并且如果您在前 30 秒内看到的问题比之后多,我建议使用卡尔曼滤波器来估计当前误差,然后将(根据模型您构建的)将最小化控制操作时间和下一次观察时间之间的均方误差。使用卡尔曼滤波器至少会考虑到系统启动时增加的观测误差。
警告:上述卡尔曼滤波器的使用是短视的,在某些与动量相对应的情况下会显着失败:它会过度校正并最终从一个极端疯狂地摆动到另一个极端。更好地使用卡尔曼滤波器结果是计算多个控制输入,最小化此输入序列末尾的预测误差(例如使用动态规划),然后在执行第一个控制输入后重新审视问题。在我发现过度校正的简单示例中,如果您计算持续两个时间段的最小化误差的单个控制动作,您可以获得稳定的行为,但重新审视问题并在一个时间段结束时重新计算控制动作。 YMMV.
如果这不起作用,也许是时候进行准确的模拟,将其线性化以获得微分方程,并应用经典控制理论。如果它不能在整个范围内合理地线性化,您可以尝试打破该范围,也许对大错误和小错误使用不同的策略。
我从控制回路中获得的(很少)经验表明,最大限度地减少传感器传感和控制执行之间的回路中的延迟和抖动非常重要。如果在输入和控制之间存在任何不必要的抖动或延迟源,请在修复该问题时忘记控制理论。
我正在尝试消除稍微异常情况下的噪音。可能有一个通用算法可以解决我的问题,但我不知道它是什么。
我目前正在建造一个机器人 telescope 坐骑。为了跟踪天空的运动,坐骑每秒拍摄一次天空照片,并跟踪它能看到的星星的 X、Y 和旋转的变化。
如果我只使用原始测量值来跟踪旋转,输出会不稳定且嘈杂,如下所示:
使用原始旋转测量值进行指导:
如果我使用低通滤波器,安装座会过冲并且永远不会完全稳定下来。较低的 Beta 值对此有帮助,但修正速度太慢且误差会累积。
使用低通滤波器进行引导:
(两张图中,紫色为天空和坐骑旋转的差异,红色为坐骑的修正旋转。)
移动平均线与低通滤波器有同样的问题。
关于问题的更多信息:
- 对于给定的天空区域,星星的旋转将是恒定的。然而,我们不知道我们在哪里,并且由于大气抖动,天空旋转的测量非常嘈杂,因此算法必须在引导时朝着这个最初未知的常数值努力。
- 坐骑可以在一秒内移动到需要的距离,并且有自己的控制系统。所以我不认为这是PID回路控制系统的问题。
- 前 30 秒左右引导不佳(或根本不引导)是可以的。
我写了一个 Python 小程序来模拟这个问题 - 我想也可以把它包括在这里。这个目前正在使用低通滤波器。
#!/usr/bin/env python3
import random
import matplotlib.pyplot as plt
ROTATION_CONSTANT = 0.1
TIME_WINDOW = 300
skyRotation = 0
mountRotation = 0
error = 0
errorList = []
rotationList = []
measurementList = []
smoothData = 0
LPF_Beta = 0.08
for step in range(TIME_WINDOW):
skyRotation += ROTATION_CONSTANT
randomNoise = random.random() - random.random()
rotationMeasurement = skyRotation - mountRotation + randomNoise
# Lowpass filter
smoothData = smoothData - (LPF_Beta * (smoothData - rotationMeasurement));
mountRotation += smoothData
rotationList.append(smoothData)
errorList.append(skyRotation - mountRotation)
measurementList.append(rotationMeasurement)
plt.plot([0, TIME_WINDOW], [ROTATION_CONSTANT, ROTATION_CONSTANT], color='black', linestyle='-', linewidth=2)
plt.plot(errorList, color="purple")
plt.plot(rotationList, color="red")
plt.plot(measurementList, color="blue", alpha=0.2)
plt.axis([0, TIME_WINDOW, -1.5, 1.5])
plt.xlabel("Time (seconds)")
plt.ylabel("Rotation (degrees)")
plt.show()
有谁知道如何使这个收敛的比较顺利(或者可以推荐相关的学习资源),不胜感激。我很乐意阅读有关该主题的内容,但到目前为止还没有弄清楚要寻找什么!
我会首先尝试通过使您的控制输出 PID 的结果,然后按照例如https://robotics.stackexchange.com/questions/167/what-are-good-strategies-for-tuning-pid-loops 或来自您最喜欢的网络搜索。
大多数其他方法都要求您对情况有一个准确的模型,包括受控硬件对您的控制输入的响应,因此您的下一步可能是通过实验来尝试解决这个问题,例如通过尝试计算出对简单测试输入(例如脉冲或阶跃)的响应。有了模拟器后,您至少可以在模拟器上比在真实硬件上更快速、更安全地调整建议方法的参数。
如果您的模拟器是准确的,并且如果您在前 30 秒内看到的问题比之后多,我建议使用卡尔曼滤波器来估计当前误差,然后将(根据模型您构建的)将最小化控制操作时间和下一次观察时间之间的均方误差。使用卡尔曼滤波器至少会考虑到系统启动时增加的观测误差。
警告:上述卡尔曼滤波器的使用是短视的,在某些与动量相对应的情况下会显着失败:它会过度校正并最终从一个极端疯狂地摆动到另一个极端。更好地使用卡尔曼滤波器结果是计算多个控制输入,最小化此输入序列末尾的预测误差(例如使用动态规划),然后在执行第一个控制输入后重新审视问题。在我发现过度校正的简单示例中,如果您计算持续两个时间段的最小化误差的单个控制动作,您可以获得稳定的行为,但重新审视问题并在一个时间段结束时重新计算控制动作。 YMMV.
如果这不起作用,也许是时候进行准确的模拟,将其线性化以获得微分方程,并应用经典控制理论。如果它不能在整个范围内合理地线性化,您可以尝试打破该范围,也许对大错误和小错误使用不同的策略。
我从控制回路中获得的(很少)经验表明,最大限度地减少传感器传感和控制执行之间的回路中的延迟和抖动非常重要。如果在输入和控制之间存在任何不必要的抖动或延迟源,请在修复该问题时忘记控制理论。