[ROS]动态参数设置-可视化调试-创建cfg文件

2023-10-30

用途:调试时(尤其在导航和建图应用中)需要经常修改程序中的参数值,这时无论时修改命令行,还是编写固定修改参数的可执行文件,都无法满足要求。ROS为我们提供了动态参数设置机制。

一、创建cfg文件

创建动态参数ROS包(名字:book_dynamic_param),在创建ros包的时候注意加入依赖项roscpp, rospy, dynamic_reconfigure。在功能包下新建cfg文件夹,并创建DynamicParam.cfg文件,内容如下:

#!/usr/bin/env python
PACKAGE = "book_dynamic_param"

from dynamic_reconfigure.parameter_generator_catkin import *

gen = ParameterGenerator()

gen.add("IntDyParam",int_t,0,"An Int Parameter",0,0,9)
gen.add("DouDyParam",double_t,0,"A Double Parameter",1.5,0,9)
gen.add("StrDyParam",str_t,0,"A String Parameter","Hello,I'm Robot!")
gen.add("BoolDyParam",bool_t,0,"A Bool Parameter",True)

student_info = gen.enum([gen.const("Name",str_t,"LiLei","Name Information"),
                         gen.const("Sex",str_t,"Man","Sex Information"),
                         gen.const("Age",str_t,"18","Age Information")],
                        "A set contain a student information")

gen.add("StudentInfo",str_t,0,"A studenet information set","LiLei",edit_method=student_info)
exit(gen.generate(PACKAGE,"node_DynamicParam","DynamicParam"))   

该配置文件使用Python语言实现,首先需要导入dynamic_reconfigure功能包提供参数生成器,通过gen = ParameterGenerator()创建生成器。这里定义了四个不同类型的参数:int_t、double_t、str_t、bool_t。使用参数生成器的add(name, type, level, description, default, min, max) 方法生成参数,具体用法如下:

(1)name : 参数名,使用字符串描述

(2)type: 定义参数类型,可以是int_t, double_t, str_t, bool_t。

(3)level: 需要传入参数动态配置回调函数中的掩码,在回调函数中会修改所有参数的掩码,表示参数已经进行修改。

(4)description: 描述参数作用的字符串。

(5)default: 设置参数的默认值。

(6)min: 可选,设置参数的最小值,对于字符串和布尔类型值不生效。

(7)max: 可选,设置参数的最大值,对于字符串和布尔类型值不生效。

然后利用gen.enum方法生成一个枚举类型值,最后通过exit生成所有与C++和python相关的文件并推出程序。

exit(gen.generate(PACKAGE,"node_DynamicParam","DynamicParam")) 中,第二个参数表示动态参数运行的节点名,第三个参数是生成文件所使用的前缀,需要和配置文件DynamicParam.cfg名称相同。

配置文件创建完成后,需要为配置文件添加可执行权限,通过执行如下命令实现:

chmod a+x cfg/DynamicParam.cfg

在CMakeLists.txt文件添加以下内容:

generate_dynamic_reconfigure_options(
    cfg/DynamicParam.cfg
)
add_dependencies(PubForBeginner ${PROJECT_NAME}_gencfg)
//注意:PubForBeginner 是工作空间已经编译好的可执行节点,我们可以根据自己
//工作空间中的节点任意替换

在....../devel/include/book_dynamic_param文件夹可以看到自动生成的DynamicParamConfig.h

二、创建动态参数设置可执行文件

book_dyparam.cpp

#include "ros/ros.h"
#include "dynamic_reconfigure/server.h"
#include "book_dynamic_param/DynamicParamConfig.h"

//define call back function
void paramCallback(book_dynamic_param::DynamicParamConfig& config,uint32_t level)
{
    ROS_INFO("Request: %d %f %s %s %s",
                config.IntDyParam,config.DouDyParam,
                config.StrDyParam.c_str(),
                config.BoolDyParam?"True":"False",
                config.StudentInfo.c_str());
}

int main(int argc, char** argv)
{
    //initial and name node
    ros::init(argc,argv,"node_DynamicParam");
    //create node handle
    dynamic_reconfigure::Server<book_dynamic_param::DynamicParamConfig> server;
    dynamic_reconfigure::Server<book_dynamic_param::DynamicParamConfig>::CallbackType f;

    f = boost::bind(&paramCallback,_1,_2);
    server.setCallback(f);
    ros::spin();
    return 0;
}

注解:

(1)dynamic_reconfigure::Server<book_dynamic_param::DynamicParamConfig> server:创建一个参数动态配置服务端实例,参数配置的类型就是配置文件中描述的类型。该服务端实例会监听客户端的参数配置请求。

(2)dynamic_reconfigure::Server<book_dynamic_param::DynamicParamConfig>::CallbackType f:定义回调函数,并将回调函数和服务端绑定,当客户端请求修改参数时,服务端即可跳转到回调函数中进行处理。回调函数有两个传入参数,一个是新的参数配置值,另一个是表示参数修改的掩码。

三、我的CMakeList.txt文件

cmake_minimum_required(VERSION 2.8.3)
project(book_dynamic_param)

find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs dynamic_reconfigure)

generate_dynamic_reconfigure_options(
    cfg/DynamicParam.cfg
)
catkin_package(
)

include_directories(
  include ${catkin_INCLUDE_DIRS}
)

add_executable(book_dyparam
  src/book_dyparam.cpp
)
add_dependencies(book_dyparam ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(book_dyparam
  ${catkin_LIBRARIES}
)

测试:

nanorobot@ubuntu:~/catkin_test$ rosrun book_dynamic_param book_dyparam

启动可视化界面:

rosrun rqt_reconfigure rqt_reconfigure

界面如下:

如图在可视化界面滑动滑柄并勾选不同参数,可以看到如下信息打印:

[ INFO] [1630324846.122919483]: Request: 2 2.700000 Hello,I'm Robot! True Man
[ INFO] [1630324856.262749374]: Request: 4 2.700000 Hello,I'm Robot! True Man
[ INFO] [1630324857.365995972]: Request: 4 5.400000 Hello,I'm Robot! True Man
[ INFO] [1630324860.309818882]: Request: 4 5.400000 Hello,I'm Robot! False Man
[ INFO] [1630324861.333899967]: Request: 4 5.400000 Hello,I'm Robot! True Man
[ INFO] [1630324862.863199146]: Request: 4 5.400000 Hello,I'm Robot! True 18

refenence:本文参考《ROS机器人编程与SLAM算法解析指南》书中例程实现。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[ROS]动态参数设置-可视化调试-创建cfg文件 的相关文章

  • 如何在内核内部使用性能计数器?

    我想访问内核内部的性能计数器 我发现了很多在用户空间中使用性能计数器的方法 但是你能告诉我一些在内核空间中使用这些计数器的方法吗 Please 不指定工具名称 我想写自己的代码 最好是内核模块 我使用的是内核为 3 18 1 的 Ubunt
  • UNIX/Linux IPC:从管道读取。运行时如何知道数据长度?

    我有一个子进程 它生成一些可变长度的输出 然后使用半双工管道将其发送到父进程 在父级中 如何使用 read 函数 由于每次数据的长度可能不同 我如何在运行时知道数据的大小以对缓冲区执行任何 malloc 操作 fstat 函数可以用于管道文
  • Symfony 权限被拒绝

    谁能帮我解决我收到的以下错误消息 我终于在虚拟机上安装了 Symfony 它似乎工作正常 除了我偶尔收到这样的消息 1 2 ContextErrorException Warning SessionHandler read open var
  • ModuleNotFoundError:没有名为“schedule”的模块

    我有导入时间表的Python程序 import schedule 在开头 使用 python3 命令执行代码没有问题 但从其他 python 文件启动它call sudo python3 ProgramWithSchedule py she
  • 如何在Linux下生成系统范围的唯一ID

    我正在使用多进程 Linux 系统 需要生成唯一的 ID 安全性不是考虑因素 因此 ID 生成器从零开始递增就可以了 而且它只是在本地计算机内 不涉及网络 显然 实现这一点并不难 但我只是想知道是否已经提供了任何东西 最好是轻量级的 这听起
  • 针对 openpose 将 GCC 9.3.0 降级到 7 后,cuda_compile_1_ generated_batch_norm_layer.cu.o.Release.cmake 出现 CMake 错误

    你知道我该如何解决以下错误吗 这是在我使用以下命令从 GCC 9 3 0 降级到 7 后发生的 使用以前版本的 GCC 我收到此错误 CMake 不支持的 GNU 版本 不支持高于 8 的 gcc 版本 https stackoverflo
  • 为什么 gcc 会在显然不需要的时候生成 PLT?

    考虑这段代码 int foo int main foo while 1 int foo 在共享对象中实现 编译此代码gcc o main main c lfoo nostdlib m32 O2 e main no pic L shared给
  • python os.path.exists() 对于存在的 nfs 挂载目录文件失败

    我基本上有一个用于网站的网络服务器和另一个仅存储文件的网络服务器 文件服务器通过安装其目录之一连接到主服务器 该网站运行 Django 所以我主要处理 python 不管怎样 我似乎遇到了一些问题 文件被报告为不存在 即使它们实际上存在 基
  • 如何从子进程为父进程设置环境变量?

    如何从子进程为父进程设置环境变量 例如 我有父进程和子进程 子进程继承自父进程环境变量 TMP VARIABLE 777 如何将子进程中 TMP VARIABLE 的值更改为 999 使其值对父进程可见 因为 TMP VARIABLE 99
  • 在linux中将数据“广播”到多个进程的规范方法?

    我有一个应用程序需要将数据流从一个进程发送到多个读取器 每个读取器都需要查看自己的流副本 这是相当高的速率 100MB s 并不罕见 因此我希望尽可能避免重复 在我的理想世界中 Linux 应该有支持多个读取器的命名管道 并为常见的单读取器
  • 何时调用setsockopt?在bind()和connect()之前?

    我继承了一些 TCP 代码 调用 bind tcpSocket struct sockaddr server addr sizeof server addr 在致电之前 setsockopt tcpSocket SOL SOCKET SO
  • Linux 上共享内存的生命周期是多长

    我正在使用 ftok shmget shmat shmdt 函数在 Linux 上创建 写入和读取共享段 如果我写入一个程序中的段 然后退出 然后稍后从另一个程序中读取该段 我会惊讶地发现数据仍然存在 我预计当共享一个段的最后一个进程执行
  • 很好的 C 库集合? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个很好的 ANSI C 库集合 用于处理向量 哈希映射 二进制树 字符串处理等 Try g
  • 有人可以解释一下以下内存分配 C 程序的性能行为吗?

    在我的机器上 时间 A 和时间 B 交换取决于是否A是 定义或未定义 这会改变两个的顺序 callocs 被称为 我最初将此归因于寻呼系统 奇怪的是 当mmap被用来代替calloc 情况更加奇怪 两个循环花费的时间相同 正如预期的那样 作
  • Linux 是否允许从信号处理程序进行任何系统调用?

    我的理解是 一般来说 如果您从信号处理程序调用非异步信号安全函数 则行为是未定义的 但我听说 Linux 允许您安全地调用任何系统调用 这是真的 另外 SIGSEGV 处理程序的唯一可移植行为是中止或退出 但我知道如果返回 linux 实际
  • python中的多服务器监控/自动重启

    我有 2 个服务器程序 必须使用 GNU Screen 启动 我想使用基于 Python 的程序来强化这些服务器 防止崩溃 该程序启动每个屏幕会话 然后监视服务器进程 如果服务器进程崩溃 我需要 python 代码来终止无关的屏幕会话并再次
  • 使用 Python for Linux 模拟按键事件

    我正在编写一个脚本来自动运行特定模型 当模型失败时 它会等待用户输入 Enter 键 我可以检测到模型何时失败 但我无法使用 python 在 Linux 上 来模拟按键事件 Windows 有 SendKeys 库来执行此操作 但我想知道
  • 无法声明接口:资源繁忙

    我正在使用 USB4Java 低级版本 并且基本上是根据这段代码工作的here http www mets blog com java usb communication usb4java 我在 Ubuntu 中工作 遇到了有关权限的问题
  • 在Linux服务器中安装ZLIB

    我要安装ZLIB http www techsww com tutorials libraries zlib installation installing zlib on ubuntu linux php在Linux服务器中 我的服务器帐
  • 线程和 fork()。我该如何处理呢? [复制]

    这个问题在这里已经有答案了 可能的重复 多线程程序中的fork https stackoverflow com questions 1235516 fork in multi threaded program 如果我有一个使用 fork 的

随机推荐