Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor rmoss project #45

Open
gezp opened this issue Jul 22, 2024 · 21 comments
Open

Refactor rmoss project #45

gezp opened this issue Jul 22, 2024 · 21 comments

Comments

@gezp
Copy link
Member

gezp commented Jul 22, 2024

rmoss项目已经很久没有更新了,代码框架已经过时,是时候重新回头考虑rmoss软件系统应该如何设计这个问题了。目前可以参考的开源项目有很多,比如:

rmoss项目将只做rmoss_corermoss_gazebo仿真器项目,而任务级功能软件包rmoss_contrib将不再维护,其中的rmoss_auto_aim建立独立仓库进行维护。而像能量机关等任务级功能是需要参赛队伍去自行开发,而且每年可能都会有变化,甚至会有新任务的出现,如有开发者愿意开发任务级功能以作为demo演示,则建立独立仓库进行维护。

其中有几个部分需要讨论:

  • rmoss机器人软件架构:一个RM机器人软件应该怎样解耦设计?需要哪些功能包?每个包消息链路以及层级关系如何设计?
  • rmoss_core目录结构:rmoss_core应该包含哪些通用公共的功能?
  • rmoss_interfaces消息类型:机器人控制消息,机器人状态消息,裁判系统提供的状态消息,优先使用ros现在已有的消息类型。

欢迎大家讨论,并提出建议。

@gezp
Copy link
Member Author

gezp commented Jul 22, 2024

cc @Ericsii @WUyinwei-hah

@gezp
Copy link
Member Author

gezp commented Jul 22, 2024

目前想到的rmoss_core应该包含以下package:

  • rmoss_transporter:即rmoss_base中transporter功能,仅作为库进行依赖
  • rmoss_cam: 相机功能
  • rmoss_projectile_motion: 弹道运动计算功能,仅作为库进行依赖
  • rmoss_util:通用工具类,仅作为库进行依赖

rmoss_base没有存在的必要性,其中的simple_robot_base_node.cpp仅仅作为example样例存在,不同机器人的base模块必然不同,因此可以删除rmoss_base包。

@gezp
Copy link
Member Author

gezp commented Jul 22, 2024

参考navigation2,可以采用LifecycleNode进行节点管理,删除rmoss_util/task_manager功能类

@Ericsii
Copy link
Member

Ericsii commented Jul 22, 2024

参考navigation2,可以采用LifecycleNode进行节点管理,删除rmoss_util/task_manager功能类

支持使用LifecycleNode来进行管理。rmoss_interface中对于云台的底盘控制的消息应该重新修改一下,我倾向于类似ros2_control的方式来控制云台

@baiyeweiguang
Copy link
Contributor

  • 裁判系统可以单独作为一个功能提供
  • rmoss_util可以进一步拆分,避免越做越大(防止为了一个小工具而安装一堆库,等一坨东西编译半天)
    • 除了ros2以外没有其他依赖的通用工具类
    • 图像处理的工具类或者是对OpenCV某个功能的封装
    • 一些常用的数学算法工具,比如均值滤波、卡尔曼滤波,曲线拟合,不同旋转表示之间的转换

@gezp
Copy link
Member Author

gezp commented Jul 23, 2024

  • 裁判系统可以单独作为一个功能提供

你说的是裁判系统给机器人提供的信息?还是仿真器的裁判系统实现?

  • rmoss_util可以进一步拆分,避免越做越大(防止为了一个小工具而安装一堆库,等一坨东西编译半天)

    • 除了ros2以外没有其他依赖的通用工具类
    • 图像处理的工具类或者是对OpenCV某个功能的封装
    • 一些常用的数学算法工具,比如均值滤波、卡尔曼滤波,曲线拟合,不同旋转表示之间的转换

这个我也赞同,rmoss_util应该只放一些简单的工具类,复杂的工具类应该单独做package,第二点图像处理工具类我倾向于独立出去,放在rmoss_perception_common之类的包中?

@gezp
Copy link
Member Author

gezp commented Jul 23, 2024

支持使用LifecycleNode来进行管理。rmoss_interface中对于云台的底盘控制的消息应该重新修改一下,我倾向于类似ros2_control的方式来控制云台

可以简单讲一下这种方式下云台和底盘消息怎么定义吗?比如应该包含哪些字段,我对ros2_control不太熟 @Ericsii

@Ericsii
Copy link
Member

Ericsii commented Jul 23, 2024

支持使用LifecycleNode来进行管理。rmoss_interface中对于云台的底盘控制的消息应该重新修改一下,我倾向于类似ros2_control的方式来控制云台

可以简单讲一下这种方式下云台和底盘消息怎么定义吗?比如应该包含哪些字段,我对ros2_control不太熟 @Ericsii

可以参考一下 ros2_control 的 architecture 这部分介绍,应该算是使用 ros 来控制机器人的标准推荐做法 https://control.ros.org/rolling/doc/getting_started/getting_started.html#controller-manager

@Ericsii
Copy link
Member

Ericsii commented Jul 23, 2024

  • 裁判系统可以单独作为一个功能提供

可以把裁判系统通讯尽量直接兼容裁判系统协议,如果之后有队伍愿意做无下位机的方案也可以直接使用

@gezp
Copy link
Member Author

gezp commented Jul 23, 2024

系统架构设计想法:
arch
其中

  • Task Layer: 功能任务层,包含感知,规划,定位,导航等任务的实现,可以被不同的机器人复用,不需要考虑机器人硬件结构。
  • Interfece Layer: 机器人与功能任务的接口层,包含传感器与执行器驱动,由于不同机器人硬件结构差异性较大,而控制功能与机器人硬件结构相关性比较高,因此也放入该层,该部分可以采用ros2-control方式实现适配,也可以自行开发控制程序,不做限制。
  • Hardware Layer:机器人本体,使用usb,以太网,串口与Interfece Layer进行数据通信。

Task Layer与Interfece Layer使用ros msg应该与机器人的具体硬件结构实现无关。

  • state ros msg:sensor_msgs/JointState
  • command ros msg:geometry_msgs/Twist, trajectory_msgs/JointTrajectory

Task Layer的功能包可以参考navigation2moveit2

  • navigation2的输入消息是目标点,输出消息是geometry_msgs/Twist,与机器人底盘具体实现无关
  • moveit2的输入消息是末端执行器目标点,输出消息是trajectory_msgs/JointTrajectory,适用于通用机械臂,而不是特定机械臂

@baiyeweiguang
Copy link
Contributor

baiyeweiguang commented Jul 25, 2024

  • 裁判系统可以单独作为一个功能提供

你说的是裁判系统给机器人提供的信息?还是仿真器的裁判系统实现?

与真实的裁判系统实现通信,数据发布到指定话题上(在雷达站上算刚需)。目前好像没找到特别好的,在上位机与裁判系统通信的开源,只在广工的rm_controls开源上看到一个ROS1版的,但实现的有点复杂,不太好用

@gezp
Copy link
Member Author

gezp commented Jul 25, 2024

与真实的裁判系统实现通信,数据发布到指定话题上(在雷达站上算刚需)。目前好像没找到特别好的,在上位机与裁判系统通信的开源,只在广工的rm_controls开源上看到一个ROS1版的,但实现的有点复杂,不太好用

看起来没问题,创建一个新包,例如rmoss_referee_bridge , 把裁判系统的数据封装为ros msg发布出去,裁判系统的消息与比赛规则相关性高,可以单独创建仓库进行维护,后面可以加入开发计划。

@gezp gezp pinned this issue Jul 25, 2024
@gezp
Copy link
Member Author

gezp commented Jul 25, 2024

rmoss_auto_aim模块重构的想法:
autoaim

其中rmoss_auto_aim应该只包含armor detector和armor tracker模块,作为一个perception功能包。

模块功能:

  • armor detector: 检测装甲板目标与位姿估计,输出一组装甲板消息。
  • armor tracker: 装甲板跟踪与预测,输出预测的最佳射击目标点等消息。
  • gimbal controller: 云台控制,包含弹道补偿功能,输入目标点,输出关节角度目标JointState或者JointTrajectory给MCU,与机器人的机械结构强相关,不同的机器人不一样,甚至有可能是双云台机器人。

参考了rm_auto_aim,其pipeline设计比较合理,这里只是解耦了perception和control模块,这样解耦的好处是perception模块无需关心硬件结构,只需要输出目标位置即可,gimbal controller也可以被能量机关这种需要射击的任务复用。同时perception和control模块之间也非常容易插入决策模块判断目标pose是否应该射击。

@Ericsii
Copy link
Member

Ericsii commented Aug 15, 2024

通讯部分的设想:

参考:

为了兼容不同队伍机器人会有不同的总线设计,需要一套能够兼容不同总线通讯协议的基础工具类,有一套统一的数据读取机制。我设想是直接基于 boost::asio 来设计一个通讯基类的接口。

RMOSS-Transporter drawio

  • 基础的数据类型为 DataFrame ,需要包含 DataFrame 签名(数据帧)的类型以及数据帧内字节数据
  • Transporter 作为通讯基类,仅提供 ros_control 中对于 hardware_interface 需要提供的 read 和 write 接口
  • SocketTransporter 为 Socket 通讯基类,使用 boost::asio 实现异步的数据读写操作
  • 实现一个新的可实例化的通讯类型可以从 SocketTransporter 派生来使用 asio 提供的异步读写接口,也可以直接从 Transporter 派生更为自由的实现操作
  • TransporterFactory 来便于直接从配置文件中读取配置字符数组来自动构造通讯类型。(此部分可以参考我之前实现的通讯协议解析工厂模式 buffer_processor_factory register_macro

这部分作为一个基础工具类同时为 ros_control 做无下位机控制和裁判系统通讯等功能提供支持

具体工厂模式如何读取配置文件的实现,应该可以参考一下 navigation2 中 plugin 的配置读取方式

@gezp
Copy link
Member Author

gezp commented Aug 15, 2024

为了兼容不同队伍机器人会有不同的总线设计,需要一套能够兼容不同总线通讯协议的基础工具类,有一套统一的数据读取机制

兼容不同通信方式可行,统一通信接口就行,比如现在rmoss_base中的Transporter就做的这件事,但是要统一通信数据格式比较困难,不同队伍有着不同数据格式的需求,这个感觉比较难统一,比如比如rm-vision中的rm_serial_driver直接使用结构体作为数据传输格式,简单有效。这也是我为什么想把rmoss_base更改为rmoss_transporter的原因,即仅提供通信接口,通信的数据处理不同队伍会有各自不同的实现。

Transporter 作为通讯基类,仅提供 ros_control 中对于 hardware_interface 需要提供的 read 和 write 接口

这里我感觉是不是要和 ros_control 的hardware_interface 解偶开来,Transporter 应该作为通用的消息传输接口(字节传输),Transporter 有Can, Serial Socket等方式,ros2_control 中 hardware_interface 通过使用Transporter 获得硬件交互能力,比如rm_controls/rm_hw 中也是使用CanBus(属于Transporter ),另外GPIO感觉比较特殊,感觉不应该继承Transporter基类,单独实现一个接口即可 ,rm_controls/rm_hw设计感觉就行。

@Ericsii
Copy link
Member

Ericsii commented Aug 15, 2024

Transporter 作为通讯基类,仅提供 ros_control 中对于 hardware_interface 需要提供的 read 和 write 接口

这里我感觉是不是要和 ros_control 的 hardware_interface 解偶开来,Transporter 应该作为通用的消息传输接口(字节传输),Transporter 有Can, Serial Socket等方式,ros2_control 中 hardware_interface 通过使用Transporter 获得硬件交互能力,比如rm_controls/rm_hw 中也是使用CanBus(属于Transporter ),另外GPIO感觉比较特殊,感觉不应该继承Transporter基类,单独实现一个接口即可 ,rm_controls/rm_hw设计感觉就行。

这里应该是我的表述有误,其实想法是 Transporter 使用类似 hardware_interface 的接口定义,这样如果后续想要做无下位机的方案可以比较方便的放到 ros_control 里面

@gezp
Copy link
Member Author

gezp commented Aug 15, 2024

这里应该是我的表述有误,其实想法是 Transporter 使用类似 hardware_interface 的接口定义,这样如果后续想要做无下位机的方案可以比较方便的放到 ros_control 里面

那感觉就是ros_control的内容了,有点像之前rmoss_base的设计目标了,硬件和ros接口之间的桥梁,需要设计数据格式,以及数据处理逻辑,设计上较难考虑周全。另外,我觉得Transporter定义还是得回归通信本身,最好解耦开来,至于是否需要统一接口,这个也有待讨论。

@Ericsii
Copy link
Member

Ericsii commented Aug 15, 2024

这里应该是我的表述有误,其实想法是 Transporter 使用类似 hardware_interface 的接口定义,这样如果后续想要做无下位机的方案可以比较方便的放到 ros_control 里面

那感觉就是ros_control的内容了,有点像之前rmoss_base的设计目标了,硬件和ros接口之间的桥梁,需要设计数据格式,以及数据处理逻辑,设计上较难考虑周全。另外,我觉得Transporter定义还是得回归通信本身,最好解耦开来,至于是否需要统一接口,这个也有待讨论。

这里并没有规定数据格式,按照UML图例 DataFrame 仅包含数据的元信息 encoding (或者别的名字)和原始的字节数据,具体如何拼接和解析二进制数据的协议并没有包含在这个 Transporter 设计中应该作为使用者来进行实现。是满足这里说的硬件通信和协议解耦的

@gezp
Copy link
Member Author

gezp commented Aug 16, 2024

这里并没有规定数据格式,按照UML图例 DataFrame 仅包含数据的元信息 encoding (或者别的名字)和原始的字节数据,具体如何拼接和解析二进制数据的协议并没有包含在这个 Transporter 设计中应该作为使用者来进行实现。是满足这里说的硬件通信和协议解耦的

从UML中,read和write函数并没有看到data参数,那么怎么利用Transporter去发送和读取DataFrame?我好像并没有看到,这里能不能解释一下?我理解read和write是处理read_buffer和write_buffer,但是好像没有加进去和读出来的接口,没太看明白这里是怎么工作的。

@Ericsii
Copy link
Member

Ericsii commented Aug 16, 2024

从UML中,read和write函数并没有看到data参数,那么怎么利用Transporter去发送和读取DataFrame?我好像并没有看到,这里能不能解释一下?我理解read和write是处理read_buffer和write_buffer,但是好像没有加进去和读出来的接口,没太看明白这里是怎么工作的。

这里是参照常见的一些通讯库的做法,在 Transporter 的构造时传入 read 和 write 的 buffer 的指针,调用这两个方法时就不用再传 data 了

@gezp
Copy link
Member Author

gezp commented Aug 28, 2024

rmoss_cam重构想法:

  • cam_server/cam_client框架略显繁琐,消息链路为raw data->cv::Mat->ros msg->cv::Mat,可以去掉cam_server/cam_client封装,简化为raw data->ros msg->cv::Mat方式。
  • 重点规范ros msg/srv接口,而不是统一程序API,提供一些通用相机工具类/函数,例如Support set and get camera parameters methods in CamClient #17 中功能。
  • 提供usb相机和虚拟相机功能(维持原有功能)。
  • 实现参数配置GUI,可以参考ros2_mindvision_camera

目前 rmoss_gz_cam已经去掉cam_server/cam_client包装,极大简化了程序,避免为了适配代码封装而产生大量繁琐且冗余的代码。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants