diff --git a/404.html b/404.html new file mode 100644 index 00000000..58bcadfd --- /dev/null +++ b/404.html @@ -0,0 +1,89 @@ + + +
+ + + +安装ros2后不能立马使用,需要将ROS2环境添加到环境变量中才能进一步操作。
+添加步骤:
+# 添加基础环境
+echo "source /opt/ros/iron/setup.bash" >> ~/.bashrc
+
+# 添加域ID,为了系统安全,域ID的值一般选0~101和215~232
+echo "export ROS_DOMAIN_ID=<your_domain_id>" >> ~/.bash_profile
+
+# 设置通信范围
+echo "export ROS_AUTOMATIC_DISCOVERY_RANGE=SUBNET" >> ~/.bash_profile
+
+turtlesim工具是一个海龟模拟器,一般被用来学习ROS2的通信机制。rqt是一个图形窗口,用来将可视化的展示各节点的服务、主题关系
+sudo apt update
+sudo apt install ros-iron-turtlesim
+sudo apt install ~nros-iron-rqt*
+
+# 启动一个节点,用来生成海龟
+ros2 run turtlesim turtlesim_node
+# 启动一个节点,用来控制海龟
+ros2 run turtlesim turtle_teleop_key
+# 启动rqt,用来监测和控制海龟
+rqt
+# 启动rqt_graph,用来图形化显示节点间的关系
+rqt_graph
+
+更详细的使用方法参考这里
+ROS2中以节点为基本单位,每个节点之间可以通过topics(主题)、services(服务)、actions(操作)或parameters(参数)来通信。
+ROS2通过节点来实现功能单一、模块化。
通过命令行来操作节点
+# 列出节点
+ros2 node list
+
+# 查看节点信息
+ros2 node info <节点名> # 例如ros2 node info /turtlesim
+
+# 将turtlesim_node的默认节点重映射为my_turtle节点
+ros2 run turtlesim turtlesim_node --ros-args --remap __node:=my_turtle
+
+主题是ROS2的一种基于发布者-订阅者的通信机制,节点可以将数据发布到任意数量的主题,并且同时订阅任意数量的主题。主题可以多对多。
+通过命令行来操作主题
+# 列出主题
+ros2 topic list
+
+# 列出主题(参数-t可以列出主题类型)
+ros2 topic list -t
+
+# # 列出指定主题的类型
+ros2 topic type <主题名>
+
+# 查看主题订阅数量、发布数量
+ros2 topic info <主题名>
+
+# 实时查看主题内的消息
+ros2 topic echo <主题名> # 例如:ros2 topic echo /turtle1/cmd_vel
+
+# 查看主题内消息的速率
+ros2 topic hz <topic_name>
+
+# 向主题发布消息
+ros2 topic pub <topic_name> <msg_type> '<args>'
+
+# 示例:只发送一次,向主题/turtle1/cmd_vel发布类型为geometry_msgs/msg/Twist的消息,注意消息用yaml语法输入
+ros2 topic pub --once /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 1.8}}"
+
+# 示例:每1s发送一次,向主题/turtle1/cmd_vel发布类型为geometry_msgs/msg/Twist的消息,注意消息用yaml语法输入
+ros2 topic pub --rate 1 /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 1.8}}"
+
+服务是ROS2一种基于调用-响应的通信机制。与主题的差异是,主题一般是持续的更新数据,而服务只在客户端调用时才提供数据。
+通过命令行来操作服务
+# 列出服务
+ros2 service list
+
+# 列出服务(参数-t可以列出服务类型)
+ros2 service list -t
+
+# 列出指定服务的类型
+ros2 service type <service_name>
+
+# 查找某个类型的所有服务
+ ros2 topic find <service_type>
+
+ # 调用服务
+ ros2 service call <service_name> <service_type> <arguments>
+
+ # 示例:调用spawn服务新生成一直海龟
+ ros2 service call /spawn turtlesim/srv/Spawn "{x: 2, y: 2, theta: 0.2, name: ''}"
+
+动作是ROS2建立在主题和服务的基础上的基于目标-反馈-结果的通信类型。动作与服务类似,但是可以中断上次操作。
+通过命令行来操作动作
+# 列出动作
+ros2 action list
+
+# 列出动作(参数-t可以列出动作类型)
+ros2 actions list
+
+# 列出动作的客户端数量、服务器数量
+ros2 action info <action_name>
+
+# 查看动作的接口结构
+ros2 action info <action_type>
+
+# 发起动作。<values>需要采用 YAML 格式,添加--feedback后可以获取实时反馈
+ros2 action send_goal <action_name> <action_type> <values>
+
+
+# 示例:查看动作/turtlesim/action/RotateAbsolute的结构
+ros2 interface show turtlesim/action/RotateAbsolute
+
+# 示例:向动作/turtle1/rotate_absolute发起旋转1.57?(反正是个动作)
+ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: 1.57}"
+
+# 示例:向动作/turtle1/rotate_absolute发起旋转1.57,并获取实时反馈
+ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: -1.57}" --feedback
+
+参数是节点的配置值。您可以将参数视为节点设置。节点可以将参数存储为整数、浮点数、布尔值、字符串和列表。在ROS 2中,每个节点维护自己的参数
+通过命令行来操作参数
+# 列出参数
+ros2 param list
+
+# 获取指定节点的参数类型和参数值
+ros2 param get <node_name> <parameter_name>
+
+# 设置指定节点的参数类型和参数值
+ros2 param set <node_name> <parameter_name> <value>
+
+# 导出指定节点的所有参数值
+ros2 param dump <node_name>
+
+# 导入参数到指定节点(parameter_file格式和dump出的格式一致)
+ros2 param load <node_name> <parameter_file>
+
+# 节点启动时加载参数文件
+ros2 run <package_name> <executable_name> --ros-args --params-file <file_name>
+
+# 示例:获取/turtlesim节点的background_g参数的类型和值
+ros2 param get /turtlesim background_g
+
+# 示例:设置/turtlesim节点的background_g参数值为20
+ros2 param set /turtlesim background_g 20
+
+# 示例:导出节点/turtlesim的参数到turtlesim.yaml文件
+ros2 param load /turtlesim turtlesim.yaml
+
+# 示例:将turtlesim.yaml文件参数导入到节点/turtlesim中
+ros2 param load /turtlesim turtlesim.yaml
+
+# 示例:启动turtlesim_node节点时,导入turtlesim.yaml文件的参数
+ros2 run turtlesim turtlesim_node --ros-args --params-file turtlesim.yaml
+
+rqt_console是一个 GUI 工具,用于在 ROS 2 中不同等级的日志消息。通常,日志消息会显示在您的终端中。使用rqt_console,您可以随着时间的推移收集这些消息,以更有条理的方式仔细查看它们,过滤它们,保存它们,甚至重新加载保存的文件以在不同时间进行反思。
+rqt_console记录日志的级别:
+每个级别的含义没有确切的标准,但可以肯定地假设:
+Fatal消息表明系统将终止以尝试保护自身免受损害。
+Error消息表明存在重大问题,这些问题不一定会损坏系统,但会阻止其正常运行。
+Warn消息表明意外的活动或不理想的结果,可能代表更深层次的问题,但不会彻底损害功能。
+Info消息指示事件和状态更新,作为系统是否按预期运行的视觉验证。
+Debug消息详细说明了系统执行的整个逐步过程。
+# 启动rqt_console
+ros2 run rqt_console rqt_console
+
+# 示例:设置节点的记录器日志级别为WRAN
+ros2 run turtlesim turtlesim_node --ros-args --log-level WARN
+
+ros2 bag是一个命令行工具,用于记录系统中主题发布的数据。它累积在任意数量的主题上传递的数据并将其保存在数据库中。然后,您可以重播数据以重现测试和实验的结果。
+安装ros2 bag
+sudo apt-get install ros-iron-ros2bag ros-iron-rosbag2-storage-default-plugins
+
+开始记录
+# 创建保存记录的目录
+mkdir bag_files
+cd bag_files
+
+# 记录主题(ctrl+c停止记录)
+ros2 bag record <topic_name>
+
+# 查看记录的信息
+ros2 bag info <bag_file_name>
+
+# 播放主题
+ros2 bag play <bag_file_name>
+
+# 示例:记录/turtle1/cmd_vel主题(ctrl+c停止记录)
+ros2 bag record /turtle1/cmd_vel
+
+# 示例:记录多个主题,记录/turtle1/cmd_vel主题和/turtle1/pose主题
+ros2 bag record -o subset /turtle1/cmd_vel /turtle1/pose
+
+ROS_DOMAIN_ID也可称为域ID,其值的选择与本地计算机环境有关,Linux环境下,使用0-65535作为端口号,并且32768-60999作为临时端口,临时端口在任何时候都可能会被Linux使用,所以用户端口应该尽量避免与临时端口冲突。
+ROS_DOMAIN_ID与端口号的关联来自一个公式:
端口号 = 7400 + 250 * ROS_DOMAIN_ID + 0
+ROS_DOMAIN_ID = (端口号 - 7400) / 250
+
+为了安全使用,根据上面的计算公式和临时端口的区域可以得出以下限制:
+对于Windows、MacOS等环境,由于临时端口的分配区域不同,限制条件也有差异,详情见
+The ROS_DOMAIN_ID
ROS_AUTOMATIC_DISCOVERY_RANGE变量可以设置 ROS 节点尝试相互发现的距离。
+有效选项有:
+SUBNET,默认值,对于基于 DDS 的中间件来说,这意味着它将发现通过多播可到达的任何节点。
+LOCALHOST,节点只会尝试发现同一台机器上的其他节点。
+OFF,该节点不会发现任何其他节点,即使在同一台机器上。
+SYSTEM_DEFAULT,不更改任何发现设置
+git clone https://github.com/bouffalolab/bouffalo_sdk.git
+
+windows 下使用riscv64-unknown-elf-gcc
+Linux 下使用riscv64-unknown-elf-gcc
# 确认一下交叉编译工具链是否正常
+# 1. 如果是默认路径,确认CROSS_COMPILE ?= riscv64-unknown-elf-
+riscv64-unknown-elf-gcc -v
+
+# 2. 如果是自定义路径,确认配置CROSS_COMPILE ?= /opt/toolchain_gcc_t-head_linux/bin/riscv64-unknown-elf-(这里填的实际工具链位置)
+/opt/toolchain_gcc_t-head_linux/bin/riscv64-unknown-elf-gcc -v
+
+# 执行xxx-gcc -v后打印的末尾字段如下:
+Thread model: posix
+Supported LTO compression algorithms: zlib
+gcc version 10.2.0 (Xuantie-900 elf newlib gcc Toolchain V2.6.1 B-20220906)
+
+cd examples/helloworld
+make CHIP=bl616 BOARD=bl616dk
+
+减轻敲代码的负担,为串口操作添加默认sudo权限
+sudo usermod -aG dialout xxx # xxx 是你自己的用户名
+
+烧录固件
+cd examples/helloworld
+make flash CHIP=chip_name COMX=xxx # chip_name should be bl602/bl702/bl616/bl808/bl606p, COMX in Windows, /dev/ttyxxx in Linux
+
+make clean
后再重新编译开始供电,根据sipeed文档指示,如果不接显示屏之类的耗电高的外设,可以直接通过USB供电。接显示屏太麻烦了,所以这里直接typec口的USB接上HUB(有外部电源)供电。
+接显示屏太麻烦了,所以直接用串口来操作系统。串口的连接方法参考:
+
再插上网线。
+插上网线后系统会自动识别设备,并获取ip地址。我手上的系统不带有ifconfig,所以用ip命令来查看ip地址
ip addr show
+
+# 在licheepi 4a中执行
+sudo apt update # 更新软件源
+sudo apt instal openssh-server # 安装sshd服务
+
+# 本地主机执行
+ssh sipeed@192.168.0.245 # 根据实际ip填写
+
+# 解压到/opt目录下,后边会用到
+sudo tar -xf arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-linux-gnu.tar.xz -C /opt
+
+这里提供通过sunxi-tools工具来进行USB调试,将u-boot直接烧录到RAM中,方便调试。
+git clone https://github.com/linux-sunxi/sunxi-tools
+cd sunxi-tools
+make
+
+# 或者直接从仓库下载
+sudo apt install sunxi-tools
+
+arm_trusted_firmware是用于arm芯片最最最初运行的启动代码,有兴趣可以了解一下ATF的资料。我们这里只编译bl31固件。
+# 分支:`master` 版本:`e09b8aa5a517bae522feb11913a091067d9ed18e`
+git clone https://github.com/ARM-software/arm-trusted-firmware.git
+cd arm-trusted-firmware
+
+# 开始编译。这里是芯片是H616,所以填PLAT=sun50i_h616
+make CROSS_COMPILE=/opt/arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu- PLAT=sun50i_h616 DEBUG=1 bl31
+
+直接上最新的u-boot。
+# 分支:`master` 版本:`f95232c6f06cc0747801bb6a4372b33825ab0164`
+git clone git://git.denx.de/u-boot.git
+
+需要修改两处代码来解决可能出现的两种问题:
+Failed to set core voltage! Can't set CPU frequency
问题,原因是电源驱动不匹配,我测试时板子电源IC是AXP1530,所以可以直接修改drivers/power/axp305.c
文件# drivers/power/axp305.c
+# 1/3 删除axp_set_dcdc4的代码实现
+int axp_set_dcdc4(unsigned int mvolt)
+{
+ (void)mvolt;
+ return 0;
+}
+# 2/3 添加设置dcdc3电压的函数
+#define AXP305_DCDC3_1200MV_OFFSET 71
+int axp_set_dcdc3(unsigned int mvolt)
+{
+ int ret;
+ u8 cfg;
+
+ if (mvolt >= 1220)
+ {
+ cfg = AXP305_DCDC3_1200MV_OFFSET +
+ axp305_mvolt_to_cfg(mvolt, 1220, 1840, 20);
+ }
+ else
+ cfg = axp305_mvolt_to_cfg(mvolt, 500, 1200, 10);
+
+ if (mvolt == 0)
+ return pmic_bus_clrbits(AXP305_OUTPUT_CTRL1,
+ AXP305_OUTPUT_CTRL1_DCDCD_EN);
+
+ ret = pmic_bus_write(AXP305_DCDCD_VOLTAGE, cfg);
+ if (ret)
+ return ret;
+
+ return pmic_bus_setbits(AXP305_OUTPUT_CTRL1,
+ 0x1f);
+}
+
+# 3/3 修改axp_init函数的实现
+int axp_init(void)
+{
+ u8 axp_chip_id;
+ int ret;
+
+ ret = pmic_bus_init();
+ if (ret)
+ return ret;
+
+ ret = pmic_bus_read(AXP305_CHIP_VERSION, &axp_chip_id);
+ if (ret)
+ return ret;
+
+ if ((axp_chip_id & AXP305_CHIP_VERSION_MASK) != 0x4b) {
+ printf("AXP1530: Unsupported chip ID: 0x%x\n", axp_chip_id);
+ return -ENODEV;
+ }
+
+ if (0 != axp_set_dcdc3(1500)) {
+ printf("AXP1530: Failed to set DCDC3\n");
+ return -ENODEV;
+ }
+
+ return ret;
+}
+
+usb_bulk_send() ERROR -7: Operation timed out
的问题,需要修改arch/arm/mach-sunxi/dram_sun50i_h616.c
文件# arch/arm/mach-sunxi/dram_sun50i_h616.c
+# 1/1 在mctl_phy_read_calibration函数开头添加udelay(0)来解决
+static bool mctl_phy_read_calibration(struct dram_para *para)
+{
+ bool result = true;
+ u32 val, tmp;
+ udelay(0); // 为了修复usb_bulk_send() ERROR -7: Operation timed out问题而添加,问题根源位置,见https://github.com/linux-sunxi/sunxi-tools/issues/182
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 0x30, 0x20);
+ // ...
+ // other code
+}
+
+开始编译
+# 使用orangepi_zero2_defconfig的配置
+make CROSS_COMPILE=/opt/arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu- BL31=../arm-trusted-firmware/build/sun50i_h616/debug/bl31.bin orangepi_zero2_defconfig
+
+# 编译
+make CROSS_COMPILE=/opt/arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu- BL31=../arm-trusted-firmware/build/sun50i_h616/debug/bl31.bin
+
+只要取出sd卡再上电,就可以直接进入fel模式
+现在开始用安装的sunxi-tools来通过USB启动u-boot了
+cd u-boot
+../sunxi-tools/sunxi-fel uboot u-boot-sunxi-with-spl.bin
+
+此时板子就能跑起来~有问题的话先检查一下是否有漏操作的地方,或者查查资料吧
+]]># 解压到/opt目录下,后边会用到
+sudo tar -xf arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-linux-gnu.tar.xz -C /opt
+
+这里提供通过sunxi-tools工具来进行USB调试,将u-boot直接烧录到RAM中,方便调试。
+git clone https://github.com/linux-sunxi/sunxi-tools
+cd sunxi-tools
+make
+
+# 或者直接从仓库下载
+sudo apt install sunxi-tools
+
+arm_trusted_firmware是用于arm芯片最最最初运行的启动代码,有兴趣可以了解一下ATF的资料。我们这里只编译bl31固件。
+# 分支:`master` 版本:`e09b8aa5a517bae522feb11913a091067d9ed18e`
+git clone https://github.com/ARM-software/arm-trusted-firmware.git
+cd arm-trusted-firmware
+
+# 开始编译。这里是芯片是H616,所以填PLAT=sun50i_h616
+make CROSS_COMPILE=/opt/arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu- PLAT=sun50i_h616 DEBUG=1 bl31
+
+直接上最新的u-boot。
+# 分支:`master` 版本:`f95232c6f06cc0747801bb6a4372b33825ab0164`
+git clone git://git.denx.de/u-boot.git
+
+需要修改两处代码来解决可能出现的两种问题:
+Failed to set core voltage! Can't set CPU frequency
问题,原因是电源驱动不匹配,我测试时板子电源IC是AXP1530,所以可以直接修改drivers/power/axp305.c
文件# drivers/power/axp305.c
+# 1/3 删除axp_set_dcdc4的代码实现
+int axp_set_dcdc4(unsigned int mvolt)
+{
+ (void)mvolt;
+ return 0;
+}
+# 2/3 添加设置dcdc3电压的函数
+#define AXP305_DCDC3_1200MV_OFFSET 71
+int axp_set_dcdc3(unsigned int mvolt)
+{
+ int ret;
+ u8 cfg;
+
+ if (mvolt >= 1220)
+ {
+ cfg = AXP305_DCDC3_1200MV_OFFSET +
+ axp305_mvolt_to_cfg(mvolt, 1220, 1840, 20);
+ }
+ else
+ cfg = axp305_mvolt_to_cfg(mvolt, 500, 1200, 10);
+
+ if (mvolt == 0)
+ return pmic_bus_clrbits(AXP305_OUTPUT_CTRL1,
+ AXP305_OUTPUT_CTRL1_DCDCD_EN);
+
+ ret = pmic_bus_write(AXP305_DCDCD_VOLTAGE, cfg);
+ if (ret)
+ return ret;
+
+ return pmic_bus_setbits(AXP305_OUTPUT_CTRL1,
+ 0x1f);
+}
+
+# 3/3 修改axp_init函数的实现
+int axp_init(void)
+{
+ u8 axp_chip_id;
+ int ret;
+
+ ret = pmic_bus_init();
+ if (ret)
+ return ret;
+
+ ret = pmic_bus_read(AXP305_CHIP_VERSION, &axp_chip_id);
+ if (ret)
+ return ret;
+
+ if ((axp_chip_id & AXP305_CHIP_VERSION_MASK) != 0x4b) {
+ printf("AXP1530: Unsupported chip ID: 0x%x\n", axp_chip_id);
+ return -ENODEV;
+ }
+
+ if (0 != axp_set_dcdc3(1500)) {
+ printf("AXP1530: Failed to set DCDC3\n");
+ return -ENODEV;
+ }
+
+ return ret;
+}
+
+usb_bulk_send() ERROR -7: Operation timed out
的问题,需要修改arch/arm/mach-sunxi/dram_sun50i_h616.c
文件# arch/arm/mach-sunxi/dram_sun50i_h616.c
+# 1/1 在mctl_phy_read_calibration函数开头添加udelay(0)来解决
+static bool mctl_phy_read_calibration(struct dram_para *para)
+{
+ bool result = true;
+ u32 val, tmp;
+ udelay(0); // 为了修复usb_bulk_send() ERROR -7: Operation timed out问题而添加,问题根源位置,见https://github.com/linux-sunxi/sunxi-tools/issues/182
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 0x30, 0x20);
+ // ...
+ // other code
+}
+
+开始编译
+# 使用orangepi_zero2_defconfig的配置
+make CROSS_COMPILE=/opt/arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu- BL31=../arm-trusted-firmware/build/sun50i_h616/debug/bl31.bin orangepi_zero2_defconfig
+
+# 编译
+make CROSS_COMPILE=/opt/arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu- BL31=../arm-trusted-firmware/build/sun50i_h616/debug/bl31.bin
+
+只要取出sd卡再上电,就可以直接进入fel模式
+现在开始用安装的sunxi-tools来通过USB启动u-boot了
+cd u-boot
+../sunxi-tools/sunxi-fel uboot u-boot-sunxi-with-spl.bin
+
+此时板子就能跑起来~有问题的话先检查一下是否有漏操作的地方,或者查查资料吧
+ +LicheePi 4A 是基于 Lichee Module 4A 核心板的 高性能 RISC-V Linux 开发板,以 TH1520 为主控核心(4xC910@1.85G, RV64GCV,4TOPS@int8 NPU, 50GFLOP GPU),板载最大 16GB 64bit LPDDR4X,128GB eMMC,支持 HDMI+MIPI 双4K 显示输出,支持 4K 摄像头接入,双千兆网口(其中一个支持POE供电)和 4 个 USB3.0 接口,多种音频输入输出(由专用 C906 核心处理)。
+LicheePi 4A长这样的:
+
开始供电,根据sipeed文档指示,如果不接显示屏之类的耗电高的外设,可以直接通过USB供电。接显示屏太麻烦了,所以这里直接typec口的USB接上HUB(有外部电源)供电。
+接显示屏太麻烦了,所以直接用串口来操作系统。串口的连接方法参考:
+
再插上网线。
+插上网线后系统会自动识别设备,并获取ip地址。我手上的系统不带有ifconfig,所以用ip命令来查看ip地址
ip addr show
+
+# 在licheepi 4a中执行
+sudo apt update # 更新软件源
+sudo apt instal openssh-server # 安装sshd服务
+
+# 本地主机执行
+ssh sipeed@192.168.0.245 # 根据实际ip填写
+
+参考ROS2 IRON指南安装基本的环境。注意riscv架构的平台目前还不支持ROS2(2023-07-25)
+ +安装ros2后不能立马使用,需要将ROS2环境添加到环境变量中才能进一步操作。
+添加步骤:
+# 添加基础环境
+echo "source /opt/ros/iron/setup.bash" >> ~/.bashrc
+
+# 添加域ID,为了系统安全,域ID的值一般选0~101和215~232
+echo "export ROS_DOMAIN_ID=<your_domain_id>" >> ~/.bash_profile
+
+# 设置通信范围
+echo "export ROS_AUTOMATIC_DISCOVERY_RANGE=SUBNET" >> ~/.bash_profile
+
+turtlesim工具是一个海龟模拟器,一般被用来学习ROS2的通信机制。rqt是一个图形窗口,用来将可视化的展示各节点的服务、主题关系
+sudo apt update
+sudo apt install ros-iron-turtlesim
+sudo apt install ~nros-iron-rqt*
+
+# 启动一个节点,用来生成海龟
+ros2 run turtlesim turtlesim_node
+# 启动一个节点,用来控制海龟
+ros2 run turtlesim turtle_teleop_key
+# 启动rqt,用来监测和控制海龟
+rqt
+# 启动rqt_graph,用来图形化显示节点间的关系
+rqt_graph
+
+更详细的使用方法参考这里
+ROS2中以节点为基本单位,每个节点之间可以通过topics(主题)、services(服务)、actions(操作)或parameters(参数)来通信。
+ROS2通过节点来实现功能单一、模块化。
通过命令行来操作节点
+# 列出节点
+ros2 node list
+
+# 查看节点信息
+ros2 node info <节点名> # 例如ros2 node info /turtlesim
+
+# 将turtlesim_node的默认节点重映射为my_turtle节点
+ros2 run turtlesim turtlesim_node --ros-args --remap __node:=my_turtle
+
+主题是ROS2的一种基于发布者-订阅者的通信机制,节点可以将数据发布到任意数量的主题,并且同时订阅任意数量的主题。主题可以多对多。
+通过命令行来操作主题
+# 列出主题
+ros2 topic list
+
+# 列出主题(参数-t可以列出主题类型)
+ros2 topic list -t
+
+# # 列出指定主题的类型
+ros2 topic type <主题名>
+
+# 查看主题订阅数量、发布数量
+ros2 topic info <主题名>
+
+# 实时查看主题内的消息
+ros2 topic echo <主题名> # 例如:ros2 topic echo /turtle1/cmd_vel
+
+# 查看主题内消息的速率
+ros2 topic hz <topic_name>
+
+# 向主题发布消息
+ros2 topic pub <topic_name> <msg_type> '<args>'
+
+# 示例:只发送一次,向主题/turtle1/cmd_vel发布类型为geometry_msgs/msg/Twist的消息,注意消息用yaml语法输入
+ros2 topic pub --once /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 1.8}}"
+
+# 示例:每1s发送一次,向主题/turtle1/cmd_vel发布类型为geometry_msgs/msg/Twist的消息,注意消息用yaml语法输入
+ros2 topic pub --rate 1 /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 1.8}}"
+
+服务是ROS2一种基于调用-响应的通信机制。与主题的差异是,主题一般是持续的更新数据,而服务只在客户端调用时才提供数据。
+通过命令行来操作服务
+# 列出服务
+ros2 service list
+
+# 列出服务(参数-t可以列出服务类型)
+ros2 service list -t
+
+# 列出指定服务的类型
+ros2 service type <service_name>
+
+# 查找某个类型的所有服务
+ ros2 topic find <service_type>
+
+ # 调用服务
+ ros2 service call <service_name> <service_type> <arguments>
+
+ # 示例:调用spawn服务新生成一直海龟
+ ros2 service call /spawn turtlesim/srv/Spawn "{x: 2, y: 2, theta: 0.2, name: ''}"
+
+动作是ROS2建立在主题和服务的基础上的基于目标-反馈-结果的通信类型。动作与服务类似,但是可以中断上次操作。
+通过命令行来操作动作
+# 列出动作
+ros2 action list
+
+# 列出动作(参数-t可以列出动作类型)
+ros2 actions list
+
+# 列出动作的客户端数量、服务器数量
+ros2 action info <action_name>
+
+# 查看动作的接口结构
+ros2 action info <action_type>
+
+# 发起动作。<values>需要采用 YAML 格式,添加--feedback后可以获取实时反馈
+ros2 action send_goal <action_name> <action_type> <values>
+
+
+# 示例:查看动作/turtlesim/action/RotateAbsolute的结构
+ros2 interface show turtlesim/action/RotateAbsolute
+
+# 示例:向动作/turtle1/rotate_absolute发起旋转1.57?(反正是个动作)
+ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: 1.57}"
+
+# 示例:向动作/turtle1/rotate_absolute发起旋转1.57,并获取实时反馈
+ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: -1.57}" --feedback
+
+参数是节点的配置值。您可以将参数视为节点设置。节点可以将参数存储为整数、浮点数、布尔值、字符串和列表。在ROS 2中,每个节点维护自己的参数
+通过命令行来操作参数
+# 列出参数
+ros2 param list
+
+# 获取指定节点的参数类型和参数值
+ros2 param get <node_name> <parameter_name>
+
+# 设置指定节点的参数类型和参数值
+ros2 param set <node_name> <parameter_name> <value>
+
+# 导出指定节点的所有参数值
+ros2 param dump <node_name>
+
+# 导入参数到指定节点(parameter_file格式和dump出的格式一致)
+ros2 param load <node_name> <parameter_file>
+
+# 节点启动时加载参数文件
+ros2 run <package_name> <executable_name> --ros-args --params-file <file_name>
+
+# 示例:获取/turtlesim节点的background_g参数的类型和值
+ros2 param get /turtlesim background_g
+
+# 示例:设置/turtlesim节点的background_g参数值为20
+ros2 param set /turtlesim background_g 20
+
+# 示例:导出节点/turtlesim的参数到turtlesim.yaml文件
+ros2 param load /turtlesim turtlesim.yaml
+
+# 示例:将turtlesim.yaml文件参数导入到节点/turtlesim中
+ros2 param load /turtlesim turtlesim.yaml
+
+# 示例:启动turtlesim_node节点时,导入turtlesim.yaml文件的参数
+ros2 run turtlesim turtlesim_node --ros-args --params-file turtlesim.yaml
+
+rqt_console是一个 GUI 工具,用于在 ROS 2 中不同等级的日志消息。通常,日志消息会显示在您的终端中。使用rqt_console,您可以随着时间的推移收集这些消息,以更有条理的方式仔细查看它们,过滤它们,保存它们,甚至重新加载保存的文件以在不同时间进行反思。
+rqt_console记录日志的级别:
+每个级别的含义没有确切的标准,但可以肯定地假设:
+Fatal消息表明系统将终止以尝试保护自身免受损害。
+Error消息表明存在重大问题,这些问题不一定会损坏系统,但会阻止其正常运行。
+Warn消息表明意外的活动或不理想的结果,可能代表更深层次的问题,但不会彻底损害功能。
+Info消息指示事件和状态更新,作为系统是否按预期运行的视觉验证。
+Debug消息详细说明了系统执行的整个逐步过程。
+# 启动rqt_console
+ros2 run rqt_console rqt_console
+
+# 示例:设置节点的记录器日志级别为WRAN
+ros2 run turtlesim turtlesim_node --ros-args --log-level WARN
+
+ros2 bag是一个命令行工具,用于记录系统中主题发布的数据。它累积在任意数量的主题上传递的数据并将其保存在数据库中。然后,您可以重播数据以重现测试和实验的结果。
+安装ros2 bag
+sudo apt-get install ros-iron-ros2bag ros-iron-rosbag2-storage-default-plugins
+
+开始记录
+# 创建保存记录的目录
+mkdir bag_files
+cd bag_files
+
+# 记录主题(ctrl+c停止记录)
+ros2 bag record <topic_name>
+
+# 查看记录的信息
+ros2 bag info <bag_file_name>
+
+# 播放主题
+ros2 bag play <bag_file_name>
+
+# 示例:记录/turtle1/cmd_vel主题(ctrl+c停止记录)
+ros2 bag record /turtle1/cmd_vel
+
+# 示例:记录多个主题,记录/turtle1/cmd_vel主题和/turtle1/pose主题
+ros2 bag record -o subset /turtle1/cmd_vel /turtle1/pose
+
+ROS_DOMAIN_ID也可称为域ID,其值的选择与本地计算机环境有关,Linux环境下,使用0-65535作为端口号,并且32768-60999作为临时端口,临时端口在任何时候都可能会被Linux使用,所以用户端口应该尽量避免与临时端口冲突。
+ROS_DOMAIN_ID与端口号的关联来自一个公式:
端口号 = 7400 + 250 * ROS_DOMAIN_ID + 0
+ROS_DOMAIN_ID = (端口号 - 7400) / 250
+
+为了安全使用,根据上面的计算公式和临时端口的区域可以得出以下限制:
+对于Windows、MacOS等环境,由于临时端口的分配区域不同,限制条件也有差异,详情见
+The ROS_DOMAIN_ID
ROS_AUTOMATIC_DISCOVERY_RANGE变量可以设置 ROS 节点尝试相互发现的距离。
+有效选项有:
+SUBNET,默认值,对于基于 DDS 的中间件来说,这意味着它将发现通过多播可到达的任何节点。
+LOCALHOST,节点只会尝试发现同一台机器上的其他节点。
+OFF,该节点不会发现任何其他节点,即使在同一台机器上。
+SYSTEM_DEFAULT,不更改任何发现设置
+git clone https://github.com/bouffalolab/bouffalo_sdk.git
+
+windows 下使用riscv64-unknown-elf-gcc
+Linux 下使用riscv64-unknown-elf-gcc
# 确认一下交叉编译工具链是否正常
+# 1. 如果是默认路径,确认CROSS_COMPILE ?= riscv64-unknown-elf-
+riscv64-unknown-elf-gcc -v
+
+# 2. 如果是自定义路径,确认配置CROSS_COMPILE ?= /opt/toolchain_gcc_t-head_linux/bin/riscv64-unknown-elf-(这里填的实际工具链位置)
+/opt/toolchain_gcc_t-head_linux/bin/riscv64-unknown-elf-gcc -v
+
+# 执行xxx-gcc -v后打印的末尾字段如下:
+Thread model: posix
+Supported LTO compression algorithms: zlib
+gcc version 10.2.0 (Xuantie-900 elf newlib gcc Toolchain V2.6.1 B-20220906)
+
+cd examples/helloworld
+make CHIP=bl616 BOARD=bl616dk
+
+减轻敲代码的负担,为串口操作添加默认sudo权限
+sudo usermod -aG dialout xxx # xxx 是你自己的用户名
+
+烧录固件
+cd examples/helloworld
+make flash CHIP=chip_name COMX=xxx # chip_name should be bl602/bl702/bl616/bl808/bl606p, COMX in Windows, /dev/ttyxxx in Linux
+
+make clean
后再重新编译