无迹卡尔曼滤波(UKF)代码报错:fx函数参数不匹配求助
解决UKF实现中的TypeError: fx() takes 1 positional argument but 2 were given
问题描述
实现无迹卡尔曼滤波(UKF)时触发TypeError,提示fx() takes 1 positional argument but 2 were given。尝试增加初始状态维度(加入x、y方向速度)后问题仍存在,代码及报错信息如下:
代码片段
import numpy as np import math from filterpy.kalman import UKF, MerweScaledSigmaPoints from filterpy.common import Q_discrete_white_noise def fx(x, dt): # state transition functioin - predict next state based # on constant velocity model x = vt + x_0 F = np.array([[1, 0, dt, 0], [0, 1, 0, dt]]) return np.dot(F,x) def hx(x): # Extract the relative NE_X and NE_Y coordinates from the state vector x x, y = x[0], x[1] # Calculate distance distance = math.sqrt((x)**2 + (y)**2) # Calculate bearing in radians bearing = math.atan2(y, x) return np.array([[bearing], [distance]]) ### UKF ### ### Preparation of the data ### # 假设bearings和distances是已定义的输入数据 bearings = [np.radians(30), np.radians(35), np.radians(40)] distances = [100, 110, 120] first_bearing = bearings[0] first_distance = distances[0] # Calculate the position of the object related to the boat frame relative_ne_x = first_distance * math.cos(first_bearing) relative_ne_y = first_distance * math.sin(first_bearing) ### Define the initial values and the functions ### # Store the values in variable x if needed x = np.array([relative_ne_x, relative_ne_y]) # Initial state P = np.diag([1, 1]) # initial uncertainty points = MerweScaledSigmaPoints(n=2, alpha=1e-3, beta=2, kappa=0) ukf = UKF(dim_x=4, dim_z=2, dt=1.5, fx=fx, hx=hx, points=points) ukf.x = x # initial state ukf.P = P # initial uncertainty z_std1 = np.radians(5) # degrees z_std2 = 20 # meters ukf.R = np.diag([z_std1**2, z_std2**2]) # measurement noise covariance matrix ukf.Q = Q_discrete_white_noise(dim=2, var=0.01**2, dt=1.5, block_size=2) # process noise covariance matrix # Get a subset of bearings and distances starting from the start_index subset_bearings = bearings[1:] subset_distances = distances[1:] zs = [[bearing, distance] for [bearing, distance] in zip(subset_bearings, subset_distances)] # measurements print(zs) for z in zs: ukf.predict() ukf.update(z) print(ukf.x, 'log-likelihood', ukf.log_likelihood)
报错信息
Traceback (most recent call last): File "Desktop/LABSF/Main.py", line 354, in <module> ukf.predict() File "Desktop/LABSF/env/lib/python3.9/site-packages/filterpy/kalman/UKF.py", line 388, in predict self.compute_process_sigmas(dt, fx, **fx_args) File "Desktop/LABSF/env/lib/python3.9/site-packages/filterpy/kalman/UKF.py", line 503, in compute_process_sigmas self.sigmas_f[i] = fx(s, dt, **fx_args) TypeError: fx() takes 1 positional argument but 2 were given
问题分析与修复步骤
核心原因
报错本质是状态维度不匹配导致的连锁问题:
- UKF初始化时设置
dim_x=4(包含位置+速度),但初始状态、Sigma点维度、状态转移矩阵都只按2维设计,FilterPy内部调用fx时参数传递逻辑被破坏,触发了参数数量的错误提示。
具体修复点
1. 修正初始状态与不确定性矩阵维度
初始状态需匹配dim_x=4,包含x位置、y位置、x速度、y速度;不确定性矩阵同步改为4维:
# 初始状态:[x位置, y位置, x速度, y速度],速度初始设为0 x = np.array([relative_ne_x, relative_ne_y, 0.0, 0.0]) # 速度的初始不确定性设小一些 P = np.diag([1, 1, 0.1, 0.1])
2. 修正状态转移矩阵F的维度
常量速度模型的状态转移矩阵应为4x4,确保输出状态维度与输入一致:
def fx(x, dt): F = np.array([[1, 0, dt, 0], [0, 1, 0, dt], [0, 0, 1, 0], [0, 0, 0, 1]]) return np.dot(F, x)
3. 修正Sigma点的维度
MerweScaledSigmaPoints的n参数必须等于UKF的状态维度dim_x=4:
points = MerweScaledSigmaPoints(n=4, alpha=1e-3, beta=2, kappa=0)
4. 修正测量函数hx的输出格式
hx返回的测量值需为1维数组,匹配dim_z=2的设置:
def hx(x): x_pos, y_pos = x[0], x[1] distance = math.sqrt(x_pos**2 + y_pos**2) bearing = math.atan2(y_pos, x_pos) return np.array([bearing, distance])
修复后验证
运行修改后的代码,ukf.predict()将正常调用fx(x, dt),参数数量匹配,状态维度一致,不再触发TypeError。
内容的提问来源于stack exchange,提问作者GioRz
相关产品推荐
相关产品推荐

