You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无迹卡尔曼滤波(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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 15:43:14