ROS2机器人slam_toolbox建图零基础

系统:Ubuntu22.04

ROS2版本:Humble

雷达设备:rplidar_a1

一、安装必要的软件包

# 更新系统 sudo apt update
# 安装slam_toolbox sudo apt install ros-humble-slam-toolbox
# 安装RPLidar驱动 sudo apt install ros-humble-rplidar-ros
# 安装导航相关包 sudo apt install ros-humble-navigation2 ros-humble-nav2-bringup

二、配置RPLidar_A1

创建udev规则(让系统识别雷达)

# 创建udev规则 echo 'KERNEL=="ttyUSB*", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", MODE:="0666", GROUP:="dialout", SYMLINK+="rplidar"' | sudo tee /etc/udev/rules.d/rplidar.rules
# 重新加载udev规则 sudo udevadm control --reload-rules sudo udevadm trigger

重新插拔雷达USB线

测试雷达连接

# 查看雷达是否被识别 ls -l /dev | grep ttyUSB # 应该看到类似:lrwxrwxrwx 1 root root 7 Nov 6 10:20 rplidar -> ttyUSB0

三、启动雷达

# 启动RPLidar A1 ros2 launch rplidar_ros rplidar_a1_launch.py
# 在另一个终端检查激光数据 ros2 topic echo /scan --no-arr | head -5 #这一步有报错很正常,因为我们只看前5行的数据

四、创建SLAM启动文件

# 创建工作空间目录(如果还没有) mkdir -p ~/slam_ws/src cd ~/slam_ws/src
# 创建功能包(如果需要) ros2 pkg create my_slam --build-type ament_cmake --dependencies rclcpp slam_toolbox nav2_msgs
# 创建launch目录 mkdir -p ~/slam_ws/src/my_slam/launch

创建启动文件

nano ~/slam_ws/src/my_slam/launch/slam_with_rplidar.launch.py

添加以下代码:

import launch from launch_ros.actions import Node from launch.actions import DeclareLaunchArgument from launch.substitutions import LaunchConfiguration def generate_launch_description(): # 定义启动参数 use_sim_time = LaunchConfiguration('use_sim_time', default='false') # RPLidar A1 节点 rplidar_node = Node( package='rplidar_ros', executable='rplidar_node', name='rplidar_node', parameters=[{ 'serial_port': '/dev/rplidar', 'serial_baudrate': 115200, 'frame_id': 'laser', 'inverted': False, 'angle_compensate': True, 'scan_mode': 'Standard' }], output='screen' ) # slam_toolbox 节点 slam_toolbox_node = Node( package='slam_toolbox', executable='async_slam_toolbox_node', name='slam_toolbox', output='screen', parameters=[{ 'use_sim_time': use_sim_time, 'map_frame': 'map', 'odom_frame': 'odom', 'base_frame': 'base_link', 'scan_topic': '/scan', 'mode': 'mapping', # 建图模式 'resolution': 0.05, # 地图分辨率 'max_laser_range': 12.0, # 最大激光范围 }] ) # 静态TF发布 - 定义雷达位置 static_tf_laser = Node( package='tf2_ros', executable='static_transform_publisher', name='static_transform_publisher_laser', arguments=['0', '0', '0.1', '0', '0', '0', 'base_link', 'laser'] ) # 静态TF发布 - 定义base_link到odom的初始位置 static_tf_odom = Node( package='tf2_ros', executable='static_transform_publisher', name='static_transform_publisher_odom', arguments=['0', '0', '0', '0', '0', '0', 'odom', 'base_link'] ) return launch.LaunchDescription([ DeclareLaunchArgument('use_sim_time', default_value='false'), rplidar_node, static_tf_laser, static_tf_odom, slam_toolbox_node, ])

添加依赖

cd ~/slam_ws/src/my_slam nano CMakeLists.txt

将内容修改为:

cmake_minimum_required(VERSION 3.8) project(my_slam) if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_compile_options(-Wall -Wextra -Wpedantic) endif() # find dependencies find_package(ament_cmake REQUIRED) find_package(rclcpp REQUIRED) find_package(slam_toolbox REQUIRED) find_package(nav2_msgs REQUIRED) # 添加这行:安装launch目录 install(DIRECTORY launch DESTINATION share/${PROJECT_NAME} ) if(BUILD_TESTING) find_package(ament_lint_auto REQUIRED) # the following line skips the linter which checks for copyrights # comment the line when a copyright and license is added to all source files set(ament_cmake_copyright_FOUND TRUE) # the following line skips cpplint (only works in a git repo) # comment the line when this package is in a git repo and when # a copyright and license is added to all source files set(ament_cmake_cpplint_FOUND TRUE) ament_lint_auto_find_test_dependencies() endif() ament_package()

这一步主要添加了launch目录:

install(DIRECTORY launch

    DESTINATION share/${PROJECT_NAME}        

)

五、构建工作空间

cd ~/slam_ws colcon build source install/setup.bash

六、启动完整的SLAM系统

# 终端1:启动SLAM和雷达 ros2 launch my_slam slam_with_rplidar.launch.py # 终端2:启动RViz2 ros2 run rviz2 rviz2

七、配置RViz2显示建图过程

在RViz2中:

1、修改Fixed Frame:

        Global Option---->Fixed Frame:设置为 map

2、添加显示项(点击Add按钮)

        LaserScan:

                Topic :  /scan

                Size : 0.1

                Color : 红色或绿色

        Map:

                Topic : /map

                Color Scheme : costmap

                Draw Behind : √

TF:

        显示坐标框架关系

3、保存RViz配置

file---->Save Config As ----> ~/slam_ws/slam_config.rviz

 八、开始建图

1、缓慢移动雷达在环境中行走

2、观察RViz中的建图过程

3、确保覆盖所有区域

九、保存地图

建图完成后,保存地图:

ros2 run nav2_map_server map_saver_cli -f ~/my_first_map

Read more

前端拖拽交互实现:别再只会用原生拖拽了

前端拖拽交互实现:别再只会用原生拖拽了

前端拖拽交互实现:别再只会用原生拖拽了 毒舌时刻 这代码写得跟网红滤镜似的——仅供参考。 各位前端同行,咱们今天聊聊前端拖拽交互。别告诉我你还在用原生的HTML5拖拽API,那感觉就像在用诺基亚手机——能打电话,但体验太差。 为什么你需要拖拽交互 最近看到一个项目,拖拽功能全靠原生API实现,卡顿、不流畅,用户体验极差,我差点当场去世。我就想问:你是在做拖拽还是在做卡顿生成器? 反面教材 // 反面教材:原生拖拽API function handleDragStart(e) { e.dataTransfer.setData('text/plain', e.target.id); } function handleDragOver(e) { e.preventDefault(); } function handleDrop(e) { e.preventDefault(); const id = e.dataTransfer.

个性化图书推荐系统信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】

个性化图书推荐系统信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】

摘要 随着数字化阅读的普及,个性化图书推荐系统在提升用户体验和满足读者需求方面发挥了重要作用。传统的图书推荐方式往往基于简单的分类或热门榜单,难以满足读者多样化的兴趣偏好。现代推荐系统通过分析用户行为数据、阅读历史和偏好,能够提供更加精准的个性化推荐。本研究旨在开发一个基于SpringBoot后端、Vue前端和MySQL数据库的个性化图书推荐系统,该系统能够通过算法分析用户行为,动态调整推荐内容,从而提升用户的阅读体验和满意度。关键词:个性化推荐、数字化阅读、用户行为分析、动态调整、阅读体验。 本研究采用SpringBoot作为后端框架,结合Vue.js前端技术,构建了一个高效、可扩展的个性化图书推荐系统。系统通过MySQL数据库存储用户数据、图书信息和推荐记录,并利用协同过滤算法和内容-based算法实现精准推荐。功能模块包括用户注册与登录、图书浏览与搜索、推荐列表生成、用户反馈收集等。系统支持管理员对图书信息进行管理,同时提供用户个人中心,方便查看阅读历史和推荐记录。后端采用RESTful API设计,前端通过Axios实现数据交互,确保系统的高效运行和良好的用户体验。关键词:

Vue入门到精通:从零开始学Vue

Vue入门到精通:从零开始学Vue

目录 一、第一个Vue程序 第一步 Vue构造函数的参数:options template配置项 第二步 模板语句的数据来源 Template配置项 Vue实例和容器 二、Vue模板语法 Vue 插值 Vue 指令 v-bind指令 v-model指令 三、MVVM分层思想 四、VM defineProperty 五、数据代理机制 Vue数据代理机制对属性名的要求 手写Vue框架数据代理的实现 六、解读Vue框架源代码 data(函数) 七、Vue事件处理 事件绑定 Vue事件绑定 事件回调函数中的this methods实现原理 八、事件修饰符 按键修饰符 九、计算属性 反转字符串methods实现 反转字符串计算属性实现 计算属性用法 十、侦听属性 比较大小的案例watch实现 computed实现

StructBERT WebUI实战教程:用remove_duplicates函数实现万级评论去重脚本

StructBERT WebUI实战教程:用remove_duplicates函数实现万级评论去重脚本 你是不是也遇到过这样的烦恼?产品上线后,用户评论像潮水一样涌来,每天几千条,甚至上万条。但仔细一看,好多评论内容都差不多:“产品很好用”、“质量不错”、“推荐购买”……这些重复或相似的评论不仅让数据分析变得困难,还浪费了宝贵的存储空间。 手动去重?别开玩笑了,上万条评论,眼睛看花了也分不清哪些是重复的。用简单的字符串匹配?那更不行,“很好用”和“非常好用”明明意思一样,但字面上完全不同,传统方法根本识别不出来。 今天,我就带你用一个超级简单的方法,基于StructBERT WebUI,写一个不到50行的Python脚本,轻松搞定万级评论的去重工作。不用懂复杂的AI算法,也不用搭建复杂的环境,跟着我做,10分钟就能上手。 1. 为什么选择StructBERT做评论去重? 在开始写代码之前,我们先搞清楚一个问题:为什么不用传统的字符串匹配,而要选择StructBERT这种AI模型? 1.1 传统方法的局限性 我以前也试过用传统方法做评论去重,结果发现一堆问题: 字符串完