群组信息

技术大佬

社区官方认证技术大佬

成员列表

  • IMU的标定和校准:结合FishBot代码介绍

    大家好,我是继续学习的小鱼,今天再继续结合FIshBot的代码,介绍下IMU的标定,当然FishBot使用的代码很简单,只进行了静态校准,不过也有那么一些参考意义。

    73f28881-c1ca-4f53-a6c9-ddaed7eddd48-image.png

    IMU的标定和校准:结合FishBot代码介绍

    惯性测量单元(IMU)广泛应用于机器人、无人机和其他运动控制系统中,用于测量和报告设备的加速度和角速度。标定和校准IMU对于确保这些测量准确至关重要。本文将围绕MPU6050传感器的噪声源、常用校准方法和结合FishBot的校准程序进行详细介绍。

    1. MPU6050的噪声源

    MPU6050是一款广泛使用的六轴IMU,包括三轴加速度计和三轴陀螺仪。它的输出数据受到多种噪声源的影响,这些噪声源会降低测量的准确性和可靠性。

    噪声类型与描述参数

    • 高斯噪声:最常见的噪声类型,表现为读数的随机波动,通常假定其遵循高斯分布。
    • 偏移误差:传感器输出与实际值之间的固定偏差,通常在长时间内稳定。
    • 温度变化:MPU6050对温度变化敏感,可能导致读数随温度波动。
    • 电源噪声:来自电源的不稳定性可能引入噪声,尤其是在低电压供电时。
    • 机械振动:机械环境中的振动可以通过结构传递到传感器,导致错误的加速度或角速度测量。

    2. 常用的校准方法

    校准IMU通常包括以下几个步骤:

    • 静态校准:将设备放置在稳定的环境中,记录加速度计和陀螺仪的输出,以确定零偏和灵敏度误差。
    • 动态校准:通过移动设备以覆盖完整的运动范围,并使用已知的运动模式来校正传感器输出。
    • 温度补偿:记录不同温度下的传感器输出,建立温度对输出影响的模型,进行实时补偿。
    • 软件滤波:应用数字滤波器,如卡尔曼滤波器,减少输出数据中的随机噪声。

    3. FishBot的校准方法

    FishBot代码分析

    FishBot的校准方法通过软件对MPU6050进行自动校准,校准方法是获取一组初始数据,然后求均值作为静态误差。以下是FishBot代码的关键部分解析:

    void MPU6050::calcOffsets(bool is_calc_gyro, bool is_calc_acc){
      if(is_calc_gyro){ setGyroOffsets(0,0,0); }
      if(is_calc_acc){ setAccOffsets(0,0,0); }
      
      float ag[6] = {0,0,0,0,0,0}; // 3*acc, 3*gyro
      for(int i = 0; i < CALIB_OFFSET_NB_MES; i++){
        this->fetchData();
        ag[0] += accX;
        ag[1] += accY;
        ag[2] += (accZ-1.0);  // 假设设备静止且Z轴向下
        ag[3] += gyroX;
        ag[4] += gyroY;
        ag[5] += gyroZ;
        delay(1);
      }
      
      if(is_calc_acc){
        accXoffset = ag[0] / CALIB_OFFSET_NB_MES;
        accYoffset = ag[1] / CALIB_OFFSET_NB_MES;
        accZoffset = ag
    
    [2] / CALIB_OFFSET_NB_MES;
      }
      if(is_calc_gyro){
        gyroXoffset = ag[3] / CALIB_OFFSET_NB_MES;
        gyroYoffset = ag[4] / CALIB_OFFSET_NB_MES;
        gyroZoffset = ag[5] / CALIB_OFFSET_NB_MES;
      }
    }
    

    校准过程解析

    • 零偏校准:代码首先将陀螺仪和加速度计的偏移设置为零,随后在固定次数(CALIB_OFFSET_NB_MES)的测量中累计传感器读数。
    • 计算偏移:通过平均这些值,计算出每个轴的偏移量。对于加速度计Z轴,考虑到重力加速度(减去1.0)。
    • 延时:在连续测量之间进行短暂的延时,以避免采样率过高导致的数据相关性。

    通过此方法,FishBot能够自动调整传感器的偏移值,从而提高测量的精度和稳定性。这种校准对于机器人和自动化系统中的精确运动控制至关重要。

    发布在 文档资料 fishbot imu 校准
  • RE: 请问进行导航的时候 地图变成这个样子是怎么回事 怎么解决

    @2406291085 没改好地图

    发布在 FishBot机器人
  • 你真的了解IMU的参数吗?结合FishBot的MPU6050看一下

    大家好,我是爱学习的小鱼,最近打算设计IMU模块,看了挺多,但是刚开始的时候不了解参数及含义,就学习了下。今天就结合我们 FishBot 运动控制板的IMU模块——MPU6050详细介绍下IMU的参数,比如量程,噪声,下次挑选IMU的时候就知道怎么选择了。

    7e7b3f6c-6edb-4080-a494-985755d1bba1-image.png

    1. MPU6050的测量原理及数据类型

    MPU6050是一款集成了3轴陀螺仪和3轴加速度计的传感器,能够提供关于设备运动状态的详尽数据。它通过测量设备在三个空间轴(X、Y和Z轴)上的角速度和加速度,帮助用户了解设备的运动情况。陀螺仪部分通过检测因旋转而引起的科里奥利力来测量角速度。加速度计部分则测量设备加速过程中各轴向的加速度。

    科里奥力(Coriolis Force)是一种因旋转参考系中物体运动而产生的惯性力。它是由法国科学家古斯塔夫·科里奥利在1835年首次描述的,主要出现在旋转系统中,如地球自转等。科里奥利力的大小和方向取决于物体的速度和旋转轴的角速度。

    在陀螺仪传感器中,如MPU6050,科里奥利力的原理被用来测量角速度。当传感器(或载体)绕某轴旋转时,陀螺仪内的振动结构(通常是微型振子)也会因旋转而受到偏移,这种偏移通过电容式传感器检测到。检测到的信号随后被放大和转换为电信号,最终输出为旋转速度的测量值。科里奥利力的应用使得MPU6050能精确追踪设备的方向变化,这在手机、无人机、运动追踪设备等多种应用中非常关键。
    4079165d-4367-476c-98d7-59ad6f3ba275-image.png

    2. 测量数据的单位

    • 角速度(陀螺仪): 度/秒(°/s)
    • 加速度(加速度计): g(重力加速度,1g 约等于 9.81 m/s²)

    3. IMU参数:量程、灵敏度和噪声

    量程和灵敏度选择

    • 量程:MPU6050的陀螺仪部分支持±250, ±500, ±1000, ±2000°/秒的量程,加速度计部分支持±2, ±4, ±8, ±16g的量程。选择量程时需考虑应用场景的需求:例如,如果设备用于高速运动的跟踪,应选择较高的量程以避免数据溢出。
    • 灵敏度:陀螺仪的灵敏度根据量程不同而不同,例如,在±250°/秒的量程下,灵敏度为131 LSB/°/s。加速度计的灵敏度也随量程变化,如在±2g的量程下,灵敏度为16384 LSB/g。选择灵敏度高的设定可以提高测量的精确度,但可能会降低动态范围。

    噪声

    • 噪声类型:MPU6050的噪声主要包括零偏噪声和随机游走噪声。
    • 噪声单位:通常以°/s/√Hz和mg/√Hz来表示。
    • 噪声产生原因:主要是由电子电路的内在物理特性引起的,如器件内部的电阻和电容。

    4. MPU6050的参数设置代码解析

    下面这段代码是从FishBot主控板使用的IMU模块驱动中摘抄的,代码中包含了设置陀螺仪和加速度计量程的功能。通过写入不同的配置值到MPU6050的寄存器,可以调整量程和灵敏度。

    // 设置陀螺仪量程
    byte MPU6050::setGyroConfig(int config_num){
        byte status;
        switch(config_num){
            case 0: // ±250 deg/s
                gyro_lsb_to_degsec = 131.0;
                status = writeData(MPU6050_GYRO_CONFIG_REGISTER, 0x00);
                break;
            case 1: // ±500 deg/s
                gyro_lsb_to_degsec = 65.5;
                status = writeData(MPU6050_GYRO_CONFIG_REGISTER, 0x08);
                break;
            case 2: // ±1000 deg/s
                gyro_lsb_to_degsec = 32.8;
                status = writeData(MPU6050_GYRO_CONFIG_REGISTER, 0x10);
                break;
            case 3: // ±2000 deg/s
                gyro_lsb_to_degsec = 16.4;
                status = writeData(MPU6050_GYRO_CONFIG_REGISTER, 0x18);
                break;
            default:
    
    
                status = 1; // 错误处理
                break;
        }
        return status;
    }
    
    // 设置加速度计量程
    byte MPU6050::setAccConfig(int config_num){
        byte status;
        switch(config_num){
            case 0: // ±2 g
                acc_lsb_to_g = 16384.0;
                status = writeData(MPU6050_ACCEL_CONFIG_REGISTER, 0x00);
                break;
            case 1: // ±4 g
                acc_lsb_to_g = 8192.0;
                status = writeData(MPU6050_ACCEL_CONFIG_REGISTER, 0x08);
                break;
            case 2: // ±8 g
                acc_lsb_to_g = 4096.0;
                status = writeData(MPU6050_ACCEL_CONFIG_REGISTER, 0x10);
                break;
            case 3: // ±16 g
                acc_lsb_to_g = 2048.0;
                status = writeData(MPU6050_ACCEL_CONFIG_REGISTER, 0x18);
                break;
            default:
                status = 1; // 错误处理
                break;
        }
        return status;
    }
    

    此代码段显示了如何根据需要配置MPU6050的量程,以适应不同的应用场景。

    发布在 文档资料 fishbot imu 参数 详细介绍
  • RE: 将ROS2的图像话题转成视频流在浏览器中显示

    @小鱼 完整代码:

    import rclpy
    from rclpy.node import Node
    from sensor_msgs.msg import Image
    from cv_bridge import CvBridge
    import cv2
    from flask import Flask, Response
    import io
    import threading
    import argparse
    
    # 初始化Flask应用
    app = Flask(__name__)
    
    # 创建一个全局变量来存储图像数据
    current_image = None
    
    # 创建ROS2节点类
    class ImageSubscriber(Node):
        def __init__(self, topic_name):
            super().__init__('image_subscriber')
            self.subscription = self.create_subscription(
                Image,
                topic_name,
                self.image_callback,
                10)
            self.subscription  # 防止订阅被自动销毁
            self.bridge = CvBridge()
    
        def image_callback(self, msg):
            global current_image
            cv_image = self.bridge.imgmsg_to_cv2(msg, "bgr8")
            # 将图像转换为JPEG格式
            _, buffer = cv2.imencode('.jpg', cv_image)
            current_image = buffer.tobytes()
    
    # 生成器函数,不断发送图像
    def generate():
        while True:
            if current_image is not None:
                yield (b'--frame\r\n'
                       b'Content-Type: image/jpeg\r\n\r\n' + current_image + b'\r\n')
            else:
                yield (b'--frame\r\n'
                       b'Content-Type: text/plain\r\n\r\nNo image available\r\n')
    
    @app.route('/video_stream')
    def video_stream():
        return Response(generate(),
                        mimetype='multipart/x-mixed-replace; boundary=frame')
    
    def run_ros_node(topic_name):
        rclpy.init()
        image_subscriber = ImageSubscriber(topic_name)
        rclpy.spin(image_subscriber)
        # 清理和关闭ROS2节点
        image_subscriber.destroy_node()
        rclpy.shutdown()
    
    def main(args=None):
        parser = argparse.ArgumentParser(description="Subscribe to a ROS2 image topic and serve it as a video stream.")
        parser.add_argument('topic_name', type=str, help="The name of the ROS2 topic to subscribe to.")
        args = parser.parse_args()
    
        # 创建线程运行ROS2节点
        ros_thread = threading.Thread(target=run_ros_node, args=(args.topic_name,))
        ros_thread.start()
    
        # 启动Flask HTTP服务器
        try:
            app.run(host='0.0.0.0', port=5000, threaded=True)
        except KeyboardInterrupt:
            pass
        finally:
            # 确保ROS线程可以优雅退出
            ros_thread.join()
    
    if __name__ == '__main__':
        main()
    
    发布在 文档资料
  • 还在用AMCL定位吗?快试试这个SLAM工具

    大家好,我是爱学习的小鱼,今天推荐一个ROS2中的开元SLAM库,大家知道Nav2的默认定位模块是AMCL,它根据已知地图,雷达Scan数据和里程计完成定位,虽然可以利用静态地图作Scan-To-Map 来提高定位精度,但现实世界中的地图往往是动态更新的,显然一直使用某一张地图并不能满足我们的需求,SLAM-Toolbox就提供了一个动态的SLAM解决方案(以前在公司的时候都是修改Cartography来实现的),下面是详细介绍。

    SLAM Toolbox:动态世界的SLAM解决方案

    212f86d0-40e7-47dd-9b0f-9a7deb386265-image.png

    SLAM Toolbox 是一个强大的开源库,专为动态环境中的二维SLAM(同时定位与地图构建)而设计。该项目由 Steve Macenski 在 Simbe Robotics 创立,并在他在三星研究院的期间以及业余时间进行了维护和更新。SLAM Toolbox 不仅提供了常规的移动机器人所需的 2D SLAM 功能,如启动、绘图、保存地图等,还包括了一些高级特性,如地图的连续细化、重映射、以及基于优化的定位模式等。

    核心功能与AMCL对比

    SLAM Toolbox 的设计目标是提供一个比其他SLAM库(无论是免费还是付费的)更全面的解决方案。其核心功能包括:

    • 基础2D SLAM:允许用户启动地图构建,保存为PGM文件,同时提供了地图保存等实用工具。
    • 序列化和反序列化:能够在任何时间点加载已保存的位姿图(pose-graph),继续地图的绘制或修改。
    • 终身映射:加载已保存的位姿图,继续在空间中绘图,同时从新加入的扫描中删除多余的信息。
    • 优化基定位模式:在没有先验地图的情况下,通过位姿图进行“激光里程计”模式定位,支持本地闭环。

    与AMCL(自适应蒙特卡罗定位方法)相比,SLAM Toolbox 提供了更为动态和灵活的地图处理能力。AMCL主要用于在已知地图中进行定位,而SLAM Toolbox 则允许用户不仅进行定位,还可以继续更新和优化地图。此外,SLAM Toolbox 支持的“终身映射”功能使得它可以在长时间内持续更新地图,这是AMCL所不支持的。

    高级应用

    除了基础的地图绘制和保存功能,SLAM Toolbox 还提供了几种高级应用:

    1. 生命周期管理:在多次会话中对同一区域进行映射,允许用户创建和更新现有地图,并将数据序列化以供其他映射会话使用。
    2. 动态本地化:将现有的序列化地图加载到节点中,维护最近扫描的滚动缓冲区,并在缓冲区过期后移除扫描,但不影响底层地图。

    支持和贡献

    SLAM Toolbox 在多种环境(如零售、仓库、图书馆和研究环境)中已被广泛应用。对于在生产环境中使用的机器人,建议使用SLAM Toolbox的Snap版本,其进行了优化,速度提升约10倍。此外,如果遇到使用或配置问题,可以在 ROS Answers 上发帖求助,或在GitHub上提交问题和功能请求。

    安装和配置

    SLAM Toolbox 支持通过ROS2进行安装和运行,具体的安装命令如下:

    rosdep install -q -y -r --from-paths src --ignore-src
    apt install ros-$ROS_DISTRO-slam-toolbox
    

    运行时,可以通过 ros2 launch slam_toolbox online_sync_launch.py 命令启动在线同步模式。

    结语

    SLAM Toolbox 不仅为研究人员和工程师提供了一个功能丰富的SLAM库,还通过其开源的方式,鼓

    励了更广泛的社区合作和知识共享。无论是在工业应用还是学术研究中,SLAM Toolbox 都展现了其卓越的性能和灵活性,使其成为当前最受推荐的ROS2-SLAM库之一。

    发布在 文档资料 slamtoolbox ros2 slam 动态地图 定位
  • RE: 四驱板使用fishbot四驱代码,无法正常发送odom和imu话题 发布在 嵌入式系统
  • RE: 四驱板使用fishbot四驱代码,无法正常发送odom和imu话题

    @2429148505 和二驱差不多,就是速度计算那里,每个轮子因为出场原因,减速比并不一样造成的误差

    发布在 嵌入式系统
  • RE: 四驱板使用fishbot四驱代码,无法正常发送odom和imu话题

    @2429148505四驱板使用fishbot四驱代码,无法正常发送odom和imu话题 中说:

    在的麦轮在控制层面会出现右偏的情况

    校准轮距和轮子的编码器数值到距离的转换因子就好

    发布在 嵌入式系统
  • RE: 四驱板使用fishbot四驱代码,无法正常发送odom和imu话题

    @2429148505 在ROS 2中,融合IMU和里程计数据可以使用多种方式和工具包。常用的方法是通过机器人定位和导航工具包(如robot_localization),它能够处理多个传感器输入并提供融合后的定位信息。

    以下是一个基本的步骤指南,帮助你在ROS 2中实现IMU和里程计数据的融合:

    1. 安装ROS 2和依赖包

    确保你已经安装了ROS 2和相关的依赖包。可以参考ROS 2的官方安装指南来安装ROS 2。

    2. 安装robot_localization

    robot_localization是一个非常强大的工具包,用于融合多个传感器数据,包括IMU和里程计。

    sudo apt-get update
    sudo apt-get install ros-<your-ros2-distro>-robot-localization
    

    请将<your-ros2-distro>替换为你所使用的ROS 2发行版名称,如foxygalactichumble

    3. 配置IMU和里程计数据发布

    确保你的IMU和里程计数据分别发布到正确的ROS主题上。通常情况下:

    • IMU数据发布到/imu/data主题
    • 里程计数据发布到/odom主题

    你可以使用ROS 2的发布者和订阅者来发布这些数据。

    4. 创建配置文件

    创建一个YAML配置文件,用于配置robot_localization节点的参数。以下是一个示例配置文件ekf.yaml

    ekf_filter_node:
      ros__parameters:
        frequency: 30.0
        sensor_timeout: 0.1
        two_d_mode: true
        publish_tf: true
        map_frame: map
        odom_frame: odom
        base_link_frame: base_link
        world_frame: odom
    
        odom0: /odom
        odom0_config: [true, true, false,
                       false, false, true,
                       false, false, false,
                       false, false, false,
                       false, false, false]
        odom0_queue_size: 10
    
        imu0: /imu/data
        imu0_config: [false, false, false,
                      true, true, false,
                      false, false, false,
                      false, false, true,
                      false, false, false]
        imu0_queue_size: 10
        imu0_remove_gravitational_acceleration: true
    

    5. 启动robot_localization节点

    创建一个启动文件,使用launch来启动robot_localization节点,并加载你的配置文件。以下是一个示例启动文件ekf_launch.py

    from launch import LaunchDescription
    from launch_ros.actions import Node
    
    def generate_launch_description():
        return LaunchDescription([
            Node(
                package='robot_localization',
                executable='ekf_node',
                name='ekf_filter_node',
                output='screen',
                parameters=['/path/to/your/ekf.yaml'],
            )
        ])
    

    /path/to/your/ekf.yaml替换为你的ekf.yaml文件的实际路径。

    6. 运行你的ROS 2应用

    使用ros2 launch命令启动你的应用:

    ros2 launch <your_package_name> ekf_launch.py
    

    <your_package_name>替换为包含启动文件的实际包名。

    7. 验证融合结果

    你可以使用rviz2或其他可视化工具来查看融合后的定位结果。确保定位结果是预期的,并根据需要调整配置文件中的参数。

    通过这些步骤,你应该能够在ROS 2中成功融合IMU和里程计数据,以实现更精确的机器人定位和导航。

    发布在 嵌入式系统
  • RE: 请教一下,ROS_DISTRO was set to 'humble' before. Please make sure that the environment does not mix paths from different distributions.该咋解决啊阿 发布在 ROS2