ROS2forUnity
公众号:特辣番茄炒鸡蛋
欢迎关注
官网
RobotecAI/ros2-for-unity: High-performance ROS2 solution for Unity3D
版本要求
Ubuntu
安装ROS2,跟ROS2的基础使用基本一致。
Unity
这个需要将ROS2forUnity下载到Unity,只需要将
ros2的unity仿真配置(ros2-for-unity)_unity ros2-CSDN博客
Dome(1)控制一个方块的旋转
Ubuntu端
实现一个ROS2节点,用于发送旋转角度的消息,可以使用Python和ROS2的rclpy
库来编写代码。以下是一个简单的ROS2发布者(Publisher)代码示例,用于发送旋转角度的消息。这个消息将被Unity中的ROS2ListenerExample类接收并处理。
ROS2 Publisher代码(Python)
1.创建ROS2工作空间
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws
2.创建一个ROS2包
ros2 pkg create --build-type ament_python my_ros2_package
3.编辑my_ros2_package
包中的setup.py
文件
确保setup.py
文件中包含以下内容:
from setuptools import setup
package_name = 'my_ros2_package'
setup(
name=package_name,
version='0.0.0',
packages=[package_name],
data_files=[
('share/ament_index/resource_index/packages',
['resource/' + package_name]),
('share/' + package_name, ['package.xml']),
],
install_requires=['setuptools'],
zip_safe=True,
maintainer='your_name',
maintainer_email='your_email@example.com',
description='ROS2 package for sending rotation angles',
license='Apache License 2.0',
tests_require=['pytest'],
entry_points={
'console_scripts': [
'rotation_publisher = my_ros2_package.rotation_publisher:main',
],
},
)
4.创建发布者脚本
在my_ros2_package
目录下创建一个rotation_publisher.py
文件,内容如下:
import rclpy
from rclpy.node import Node
from std_msgs.msg import String
class RotationPublisher(Node):
def __init__(self):
super().__init__('rotation_publisher')
self.publisher = self.create_publisher(String, 'chatter', 10)
timer_period = 1.0 # seconds
self.timer = self.create_timer(timer_period, self.timer_callback)
self.angle = 0.0
def timer_callback(self):
msg = String()
self.angle += 10.0 # 每次增加10度
msg.data = str(self.angle)
self.publisher.publish(msg)
self.get_logger().info(f'Published rotation angle: {msg.data} degrees')
def main(args=None):
rclpy.init(args=args)
rotation_publisher = RotationPublisher()
rclpy.spin(rotation_publisher)
rotation_publisher.destroy_node()
rclpy.shutdown()
5.构建和安装包
cd ~/ros2_ws
colcon build
source install/setup.bash
6.运行发布者节点
ros2 run my_ros2_package rotation_publisher
代码说明:
RotationPublisher
类:- 继承自
Node
,创建一个名为rotation_publisher
的节点。 - 创建一个发布者,发布到
chatter
话题,消息类型为std_msgs.msg.String
。 - 定义一个定时器,每秒调用一次
timer_callback
方法。 - 在
timer_callback
中,将角度值转换为字符串并发布到chatter
话题。
- 继承自
main
函数:- 初始化ROS2环境,创建并运行
RotationPublisher
节点。
- 初始化ROS2环境,创建并运行
Unity接收和处理
在Unity中,ROS2ListenerExample
类会监听chatter
话题,并接收发布者发送的角度值。当接收到角度值时,Unity中的方块会根据该角度值进行旋转。
Unity端
using System;
using UnityEngine;
using ROS2; // 确保这个命名空间包含了ROS2UnityComponent和ROS2Node的定义
using std_msgs.msg; // 确保这个命名空间包含了String消息类型的定义
namespace ROS2
{
public class turn : MonoBehaviour
{
private ROS2UnityComponent ros2Unity;
private ROS2Node ros2Node;
private ISubscription<std_msgs.msg.String> chatter_sub;
private float angleToRotate = 0.0f; // 用于存储旋转角度
void Start()
{
ros2Unity = GetComponent<ROS2UnityComponent>();
}
void Update()
{
if (ros2Node == null && ros2Unity.Ok())
{
ros2Node = ros2Unity.CreateNode("ROS2UnityListenerNode");
chatter_sub = ros2Node.CreateSubscription<std_msgs.msg.String>(
"chatter", OnMessageReceived);
}
}
private void OnMessageReceived(std_msgs.msg.String msg)
{
// 假设接收到的消息是一个字符串,表示旋转的角度(单位为度)
if (float.TryParse(msg.Data, out float angle))
{
angleToRotate = angle; // 存储角度,稍后在主线程中使用
}
else
{
Debug.LogError("Received message is not a valid angle: " + msg.Data);
}
}
void FixedUpdate()
{
if (angleToRotate != 0.0f)
{
// 将角度转换为弧度
float angleInRadians = angleToRotate * Mathf.Deg2Rad;
// 使方块绕着自己的中心旋转
transform.Rotate(0, 0, angleInRadians, Space.Self);
angleToRotate = 0.0f; // 重置角度
}
}
}
}
结果
BUG解决方案
1.Unity可以跑,ubuntu可以跑,但是Ubuntu找不到节点。
解决方案:
这个问题就是因为防火墙拦截了节点
打开防火墙和网络保护
选择高级设置
入站规则
找到关于Unity的规则,如果有拦截的就
属性
把阻止连接改为选择允许连接,点击确定,这样就能够跑了。