使用卡尔曼滤波器估计pybullet中的机器人位置

news2024/12/25 8:53:28

⭐️ 卡尔曼滤波

卡尔曼滤波是一种递归算法,用于从具有噪声的观测中估计系统状态。它特别适合用于线性、高斯动态系统。

笔者之前写过一篇博文介绍卡尔曼滤波器《boss:整个卡尔曼滤波器的简单案例——估计机器人位置》,本文手动实现一个卡尔曼滤波器并结合pybullet实现一个机器人位置估计的案例。


卡尔曼滤波的工作流程

  1. 预测步骤(Predict):

    • 根据当前的状态估计值和状态转移模型,预测下一个时刻的状态。
    • 预测状态的协方差矩阵。
  2. 更新步骤(Update):

    • 利用新观测数据更新预测值,得到更精确的状态估计。
    • 更新状态的协方差矩阵。

公式如下:

  • 状态预测
    x ^ k − = F x ^ k − 1 + B u k \hat{x}_k^- = F \hat{x}_{k-1} + B u_k x^k=Fx^k1+Buk
    P k − = F P k − 1 F T + Q P_k^- = F P_{k-1} F^T + Q Pk=FPk1FT+Q

  • 更新观测
    K k = P k − H T ( H P k − H T + R ) − 1 K_k = P_k^- H^T (H P_k^- H^T + R)^{-1} Kk=PkHT(HPkHT+R)1
    x ^ k = x ^ k − + K k ( z k − H x ^ k − ) \hat{x}_k = \hat{x}_k^- + K_k (z_k - H \hat{x}_k^-) x^k=x^k+Kk(zkHx^k)
    P k = ( I − K k H ) P k − P_k = (I - K_k H) P_k^- Pk=(IKkH)Pk

准备数据和参数
  • F: 状态转移矩阵
  • H: 观测矩阵
  • Q: 过程噪声协方差
  • R: 测量噪声协方差
  • x: 状态向量
  • P: 状态协方差矩阵
  • z: 观测值

⭐️ 案例

  1. 设置 PyBullet 模拟环境
    在这个例子中,我们将模拟一个简单的机器人(如移动小车)在一个二维环境中的运动,机器人会随机移动,并且我们会使用卡尔曼滤波来修正机器人的位置估计。我们的目标是实现路径规划并利用卡尔曼滤波修正运动中的噪声。

  2. 路径规划
    我们使用一个非常简单的路径规划方案,例如通过设置目标位置并计算机器人当前位置到目标位置的距离,然后让机器人朝目标移动。

import pybullet as p
import time
import numpy as np
import matplotlib.pyplot as plt
import pybullet_data


# --- 1. 设置环境 ---
# 启动 PyBullet 环境
# p.connect(p.DIRECT)  # 使用非图形界面进行模拟
p.connect(p.GUI)  # 使用非图形界面进行模拟
# 修改窗口位置和大小(Windows/Linux)
p.configureDebugVisualizer(p.COV_ENABLE_GUI, 1)  # 确保 GUI 启用
p.resetDebugVisualizerCamera(
    cameraDistance=7,   # 调整距离
    cameraYaw=50,       # 调整视角
    cameraPitch=-35,
    cameraTargetPosition=[0, 0, 0]
)

# 加载 PyBullet 物理引擎
p.setAdditionalSearchPath(pybullet_data.getDataPath())  # 设置路径

# 设置场景
p.setGravity(0, 0, -9.81)
p.loadURDF("plane.urdf")  # 加载地面

# 加载机器人(这里假设一个简单的箱形机器人)
robot = p.loadURDF("r2d2.urdf", basePosition=[0, 0, 0.1])  # 可替换为任何简单的 URDF 文件

class KalmanFilter:
    def __init__(self, F, H, Q, R, x0, P0):
        """
        :param F: 状态转移矩阵
        :param H: 观测矩阵
        :param Q: 过程噪声协方差
        :param R: 观测噪声协方差
        :param x0: 初始状态
        :param P0: 初始协方差矩阵
        """
        self.F = F  # 状态转移矩阵
        self.H = H  # 观测矩阵
        self.Q = Q  # 过程噪声协方差
        self.R = R  # 观测噪声协方差
        self.x = x0  # 初始状态
        self.P = P0  # 初始协方差矩阵

    def predict(self):
        """预测步骤"""
        # 预测状态
        self.x = np.dot(self.F, self.x)
        # 预测协方差
        self.P = np.dot(np.dot(self.F, self.P), self.F.T) + self.Q

    def update(self, z):
        """更新步骤"""
        # 计算卡尔曼增益
        S = np.dot(np.dot(self.H, self.P), self.H.T) + self.R
        K = np.dot(np.dot(self.P, self.H.T), np.linalg.inv(S))

        # 更新状态估计
        y = z - np.dot(self.H, self.x)
        self.x = self.x + np.dot(K, y)

        # 更新协方差矩阵
        self.P = self.P - np.dot(np.dot(K, self.H), self.P)

    def get_estimate(self):
        """获取当前状态估计"""
        return self.x


# 初始状态:机器人位置 (x, y, theta)
x0 = np.array([0, 0, 0])  # 初始位置和角度
P0 = np.eye(3)  # 初始协方差矩阵

# 过程噪声协方差和观测噪声协方差
Q = np.array([[0.1, 0, 0], [0, 0.1, 0], [0, 0, 0.1]])
R = np.array([[0.5, 0], [0, 0.5]])

# 状态转移矩阵和观测矩阵(简化模型)
F = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])  # 简单的线性状态转移
H = np.array([[1, 0, 0], [0, 1, 0]])  # 观察模型(x, y)

# 创建卡尔曼滤波器对象
ekf = KalmanFilter(F=F, H=H, Q=Q, R=R, x0=x0, P0=P0)

# --- 3. 路径规划算法 ---
# 设置目标位置
target_position = np.array([3, 2])  # 目标位置

# 机器人当前状态和路径记录
path = [x0[:2]]

# 设定移动的步长
step_size = 0.1

# 模拟机器人的运动
# for _ in range(100):
while True:
    # 获取当前机器人状态(位置)
    current_position = p.getBasePositionAndOrientation(robot)[0]
    # 添加噪声
    noisy_position = current_position[:2] + np.random.normal(0, 0.1, size=2)
    
    # 执行卡尔曼滤波
    ekf.predict()  # 预测
    ekf.update(noisy_position)  # 更新

    # 获取过滤后的估计位置
    estimated_position = ekf.get_estimate()[:2]

    # 根据当前估计位置计算控制输入(简单的前进和旋转到目标)
    direction = target_position - estimated_position
    distance = np.linalg.norm(direction)
    if distance < step_size:
        break  # 到达目标

    direction = direction / distance  # 单位方向向量

    # 更新机器人状态(简单地模拟机器人运动)
    new_position = estimated_position + direction * step_size
    p.resetBasePositionAndOrientation(robot, np.array(new_position.tolist() + [0]), [0, 0, 0, 1])

    # 记录路径
    path.append(estimated_position)

    # 显示更新
    time.sleep(0.1)

# --- 4. 绘制路径 ---
path = np.array(path)
plt.plot(path[:, 0], path[:, 1], label='Path')
plt.scatter(target_position[0], target_position[1], color='red', label='Target')
plt.title("Robot Path with Kalman Filter")
plt.xlabel("X Position")
plt.ylabel("Y Position")
plt.legend()
plt.show()

# 断开连接
p.disconnect()

运行结果

卡尔曼位置估计

在这里插入图片描述

笔者水平有限,若有不对的地方欢迎评论指正!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2245810.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【尚筹网】二、环境搭建一

【尚筹网】二、环境搭建一 环境搭建总体目标创建工程系统架构图工程创建计划创建空项目创建对应的 Maven 模块建立模块间的依赖 创建数据库基于 Maven 的 Mybatis 的逆向过程配置 pom创建 generatorConfig.xml执行逆向工程操作的 maven 指令将逆向工程生成的资源归位 父工程依赖…

全面解析 JMeter 后置处理器:概念、工作原理与应用场景

在性能测试中&#xff0c;Apache JMeter是一个非常流行的工具&#xff0c;它不仅能够模拟大量用户进行并发访问&#xff0c;还提供了丰富的扩展机制来满足各种复杂的测试需求。后置处理器&#xff08;Post-Processor&#xff09;是JMeter中非常重要的组件之一&#xff0c;用于在…

数字IC后端实现时钟树综合系列教程 | Clock Tree,Clock Skew Group之间的区别和联系

Q: Clock&#xff0c;Clock Tree和Skew Group有何区别&#xff1f;Innovus CCOPT引擎是如何使用这些的&#xff1f; Clock是时序约束SDC中的时钟定义点。 create_clock -name clk_osc -period $period_24m [get_ports xin_osc0_func] 时钟树综合(Clock Tree Synthesis)之前应…

基于零相差前馈补偿的 PID 控制

零相差前馈补偿是一种结合前馈补偿与反馈控制的策略&#xff0c;旨在提高控制系统对参考信号的跟踪精度。通过设计合理的前馈补偿器&#xff0c;使得系统对参考输入实现零相位差的跟踪&#xff0c;同时利用 PID 控制器保证系统的稳定性和动态性能。 1. 原理概述 目标&#xff…

odoo18中模型的常用字段类型

字段的公共属性: Char 字符类型&#xff0c;对应数据库中varchar类型&#xff0c;除了通用类型外接收另外两个参数&#xff1a; size: 字符长度&#xff0c;超出的长度将被截断 trim: 默认True&#xff0c;是否字段值应该被去空白。 Text 文本类型&#xff0c;对应数据库…

Wireshark抓取HTTPS流量技巧

一、工具准备 首先安装wireshark工具&#xff0c;官方链接&#xff1a;Wireshark Go Deep 二、环境变量配置 TLS 加密的核心是会话密钥。这些密钥由客户端和服务器协商生成&#xff0c;用于对通信流量进行对称加密。如果能通过 SSL/TLS 日志文件&#xff08;例如包含密钥的…

鸿蒙生态崛起

1.鸿蒙生态&#xff1a;开发者的新蓝海 从开发者角度看&#xff0c;鸿蒙生态带来了巨大机遇。其分布式能力实现了不同设备间的无缝体验&#xff0c;如多屏协同&#xff0c;让应用能跨手机、平板、智能穿戴和车载设备流畅运行。开发工具也有显著提升&#xff0c;方舟编译器等极大…

【MySQL】精细讲解:数据库内置函数深度学习解析

前言&#xff1a;本节内容讲述mysql里面的函数的概念&#xff0c; 在mysql当中&#xff0c; 内置了很多函数工作。 这些函数丰富了我们的操作。 比如字符串函数、数据函数以及一些其他函数等等。 ps:友友们学习了表的基本操作后就可以观看本节内容啦! 目录 日期函数 current_…

亚信安全与飞书达成深度合作

近日&#xff0c;亚信安全联合飞书举办的“走近先进”系列活动正式走进亚信。活动以“安全护航信息化 共筑数字未来路”为主题&#xff0c;吸引了众多数字化转型前沿企业的近百位领导参会。作为“走近先进”系列的第二场活动&#xff0c;本场活动更加深入挖掘了数字化转型的基础…

[less] Operation on an invalid type

我这个是升级项目的时候遇到的&#xff0c;要从 scss 升级到 less&#xff0c;然后代码中就报了这个错误 我说一下代码的错误过程&#xff0c;但是这里没有复现&#xff0c;因为我原本报错的代码要复杂很多&#xff0c;而且是公司代码&#xff0c;不方便透露&#xff0c;这是我…

“iOS profile文件与私钥证书文件不匹配”总结打ipa包出现的问题

目录 文件和证书未加载或特殊字符问题 证书过期或Profile文件错误 确认开发者证书和私钥是否匹配 创建证书选择错误问题 申请苹果 AppId时勾选服务不全问题 ​总结 在上线ios平台的时候&#xff0c;在Hbuilder中打包遇见了问题&#xff0c;生成ipa文件时候&#xff0c;一…

大语言模型(LLM)安全:十大风险、影响和防御措施

一、什么是大语言模型&#xff08;LLM&#xff09;安全&#xff1f; 大语言模型&#xff08;LLM&#xff09;安全侧重于保护大型语言模型免受各种威胁&#xff0c;这些威胁可能会损害其功能、完整性和所处理的数据。这涉及实施措施来保护模型本身、它使用的数据以及支持它的基…

基础知识学习上

基础知识学习上 1.关于print1.1 format 方法 2.运算符2.1 除法运算2.2 幂运算 3.条件控制语句3.1 if语句3.2 循环语句 4.复杂数据类型4.1列表4.2字典4.3字符串 5.函数 1.关于print 分隔符 print(1, 2, 3, 4, sep-) print(1, 2, 3, 4, sep。)结尾符 print(1, 2, 3, 4, end?) pr…

开源远程桌面工具:RustDesk

在远程办公和远程学习日益普及的今天&#xff0c;我们经常需要远程访问办公电脑或帮助他人解决电脑问题。 市面上的远程控制软件要么收费昂贵&#xff0c;要么需要复杂的配置&#xff0c;更让人担心的是数据安全问题。 最近我发现了一款名为 RustDesk 的开源远程桌面工具&…

双通道CAN转以太网(三格电子)

一、功能描述 SG-CANET-210 是一款用来把 CAN 总线数据转为网口数据的设备。网口支 持 TCP Sever 、TCP Client 、UDP Sever 、UDP Client 、UDP Broadcast 模式&#xff0c;可以 通过软件配置和网页配置。设备提供两路 CAN 接口&#xff0c;两路 CAN 可分别配置为 不同的工作…

WebApis学习笔记,第二节:高级语法

WebApis学习笔记&#xff0c;第二节&#xff1a;高级语法 一、JS组成 我们再回顾一下JS的组成&#xff1a;ECMAScript: 规定了js基础语法核心知识。 比如&#xff1a;变量、分支语句、循环语句、对象等等Web APIs : DOM 文档对象模型&#xff0c; 定义了一套操作HTML文档的AP…

【ubuntu24.04.1最简洁安装方案】

我的电脑配置&#xff1a; 128GB固态硬盘&#xff0c;1TB 机械硬盘&#xff0c;我把整个 windows 系统全噶掉了&#xff0c;只安装ubuntu24.04.1一个Linux系统噶windows系统&#xff0c; 推荐使用 DiskGenius这个工具&#xff0c;好用&#xff0c;但是也要弄明白了再用啊&#…

【spring的底层原理】Bean的生命周期

文章目录 什么是Bean的生命周期Bean的生命周期可以分为几个步骤Bean的定义阶段加载BeanDefinition中指定的类实例化前&#xff08;可选&#xff09;实例化属性注入Aware接口回调BeanPostProcessor前置处理初始化初始化前&#xff08;可选&#xff09;初始化初始化后&#xff08…

全面前端显示:鹅成熟与否识别

1.背景意义 研究背景与意义 随着生态保护意识的增强和生物多样性的重要性日益凸显&#xff0c;水鸟尤其是加拿大鹅的保护与管理成为了生态学研究的一个重要领域。加拿大鹅在北美地区广泛分布&#xff0c;其种群数量的变化不仅反映了生态环境的健康状况&#xff0c;也对当地生…

label studio+sam实现半自动标注

1、主要参考&#xff1a;https://github.com/open-mmlab/playground/tree/main/label_anything 这里提醒大家一点&#xff0c;有人使用过程中&#xff0c;出现自动标注无反应&#xff0c;就是操作步骤出现了问题&#xff01;一定记住按这个顺序操作&#xff01;&#xff01;&a…