提问人:jvmoraiscb 提问时间:11/17/2023 更新时间:11/17/2023 访问量:13
ROS2 Unity 项目中的异常行为:接收主题数据时出现问题
Anomalous Behavior in ROS2 Unity Project: Issue with Receiving Topic Data
问:
我正在使用这个库(https://github.com/RobotecAI/ros2-for-unity)在 Unity 中使用 ROS2 进行一个项目 (https://github.com/jvmoraiscb/rhcr)。
在虚拟机中,我运行一个节点,其中包含与控制器相关的主题(它发布位置并接收应施加的力)。该节点位于我有一段时间未修改的容器中。
然而,在上周,一个非常奇怪的错误开始发生,我不知道它可能是什么:当我在 Unity 和容器中运行程序时,控制器行为异常(好像它正在接收来自与强制相关的主题的垃圾)。但是,如果我打开另一个终端并运行“ros2 topic echo /force_vector”,控制器会停止移动(这是正常的,因为我没有在 Unity 中发送任何力值),并且项目正常工作。
这些是与控制节点相关的代码(我忽略了falcon.cpp,因为它只抽象了控制函数):
main.cpp:
#include <csignal>
#include "falcon_node.hpp"
// global pointers
bool* debug_mode_pt;
Falcon* falcon_pt;
void signal_handler(int sig) {
if (sig == SIGTSTP) {
if (*debug_mode_pt) {
*debug_mode_pt = false;
falcon_pt->print_info();
} else {
*debug_mode_pt = true;
}
}
}
int main(int argc, char* argv[]) {
// initialize falcon variables
auto falcon = Falcon();
auto debug_mode = false;
// initialize global pointers
debug_mode_pt = &debug_mode;
falcon_pt = &falcon;
// register custom handler to ctrl-z
signal(SIGTSTP, signal_handler);
// initialize ros variables
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<Falcon_Node>(falcon_pt, debug_mode_pt));
rclcpp::shutdown();
return 0;
}
falcon_node.cpp:
#include "falcon_node.hpp"
using namespace std;
using namespace chrono_literals;
Falcon_Node::Falcon_Node(Falcon* falcon, bool* debug_mode) : Node("falcon_node"), count_(0) {
falcon_ = falcon;
debug_mode_ = debug_mode;
timer_ = this->create_wall_timer(10ms, std::bind(&Falcon_Node::timer_callback, this));
position_vector_pub = this->create_publisher<geometry_msgs::msg::Vector3>("position_vector", 10);
right_button_pub = this->create_publisher<std_msgs::msg::Int16>("right_button", 10);
up_button_pub = this->create_publisher<std_msgs::msg::Int16>("up_button", 10);
center_button_pub = this->create_publisher<std_msgs::msg::Int16>("center_button", 10);
left_button_pub = this->create_publisher<std_msgs::msg::Int16>("left_button", 10);
force_vector_sub = this->create_subscription<geometry_msgs::msg::Vector3>("force_vector", 10, std::bind(&Falcon_Node::force_callback, this, std::placeholders::_1));
rgb_vector_sub = this->create_subscription<geometry_msgs::msg::Vector3>("rgb_vector", 10, std::bind(&Falcon_Node::rgb_callback, this, std::placeholders::_1));
printf("Please calibrate the controller: move it around and then press the center button.\n");
falcon_->rgb(true, false, false);
falcon_->calibrate();
falcon_->rgb(false, true, false);
falcon_->print_info();
}
void Falcon_Node::timer_callback() {
double x, y, z;
int button1, button2, button3, button4;
falcon_->update();
falcon_->get(&x, &y, &z, &button1, &button2, &button3, &button4);
if (*debug_mode_) {
printf("X: %+.2f | Y: %+.2f | Z: %+.2f | B1: %d | B2: %d | B3: %d | B4: %d\n", x, y, z, button1, button2, button3, button4);
}
auto pos = geometry_msgs::msg::Vector3();
pos.x = (float)x;
pos.y = (float)y;
pos.z = (float)z;
auto right = std_msgs::msg::Int16();
right.data = button1;
auto up = std_msgs::msg::Int16();
up.data = button2;
auto center = std_msgs::msg::Int16();
center.data = button3;
auto left = std_msgs::msg::Int16();
left.data = button4;
position_vector_pub->publish(pos);
right_button_pub->publish(right);
up_button_pub->publish(up);
center_button_pub->publish(center);
left_button_pub->publish(left);
}
void Falcon_Node::force_callback(const geometry_msgs::msg::Vector3::SharedPtr msg) {
falcon_->set(msg->x, msg->y, msg->z);
}
void Falcon_Node::rgb_callback(const geometry_msgs::msg::Vector3::SharedPtr msg) {
bool red = ((int)msg->x == 1) ? true : false;
bool green = ((int)msg->y == 1) ? true : false;
bool blue = ((int)msg->z == 1) ? true : false;
falcon_->rgb(red, green, blue);
}
这是 Unity 中节点的代码:
Ros2FalconUnityNode.cs
using UnityEngine;
namespace ROS2
{
public class Ros2FalconNode : MonoBehaviour
{
[SerializeField]
private FalconEnv falconEnv;
[SerializeField]
private string nodeName;
[SerializeField]
private string positionTopicName;
[SerializeField]
private string rightButtonTopicName;
[SerializeField]
private string upButtonTopicName;
[SerializeField]
private string centerButtonTopicName;
[SerializeField]
private string leftButtonTopicName;
[SerializeField]
private string forceTopicName;
[SerializeField]
private string rgbTopicName;
private ROS2UnityComponent ros2Unity;
private ROS2Node ros2Node;
private IPublisher<geometry_msgs.msg.Vector3> force_pub;
private IPublisher<geometry_msgs.msg.Vector3> rgb_pub;
private const int RIGHT = 1;
private const int UP = 2;
private const int CENTER = 3;
private const int LEFT = 4;
private int lastStatus_right = -1;
private int lastStatus_up = -1;
private int lastStatus_center = -1;
private int lastStatus_left = -1;
void Start()
{
ros2Unity = GetComponent<ROS2UnityComponent>();
if (ros2Node == null)
ros2Node = ros2Unity.CreateNode(nodeName);
if (ros2Unity.Ok())
{
ros2Node.CreateSubscription<geometry_msgs.msg.Vector3>(positionTopicName, msg => PositionHandler(msg.X, msg.Y, msg.Z));
ros2Node.CreateSubscription<std_msgs.msg.Int16>(rightButtonTopicName, msg => ButtonHandler(RIGHT, msg.Data));
ros2Node.CreateSubscription<std_msgs.msg.Int16>(upButtonTopicName, msg => ButtonHandler(UP, msg.Data));
ros2Node.CreateSubscription<std_msgs.msg.Int16>(centerButtonTopicName, msg => ButtonHandler(CENTER, msg.Data));
ros2Node.CreateSubscription<std_msgs.msg.Int16>(leftButtonTopicName, msg => ButtonHandler(LEFT, msg.Data));
force_pub = ros2Node.CreatePublisher<geometry_msgs.msg.Vector3>(forceTopicName);
rgb_pub = ros2Node.CreatePublisher<geometry_msgs.msg.Vector3>(rgbTopicName);
}
}
void Update()
{
if (ros2Unity.Ok())
{
ForceHandler();
RgbHandler();
}
}
void ForceHandler()
{
geometry_msgs.msg.Vector3 msg = new geometry_msgs.msg.Vector3
{
X = falconEnv.force.x,
Y = falconEnv.force.y,
Z = falconEnv.force.z
};
force_pub.Publish(msg);
}
void RgbHandler()
{
geometry_msgs.msg.Vector3 msg = new geometry_msgs.msg.Vector3
{
X = falconEnv.rgb.x,
Y = falconEnv.rgb.y,
Z = falconEnv.rgb.z
};
rgb_pub.Publish(msg);
}
void PositionHandler(double x, double y, double z)
{
falconEnv.position.x = (float)x;
falconEnv.position.y = (float)y;
falconEnv.position.z = (float)z;
}
void ButtonHandler(int button, int value)
{
if (button == RIGHT && value != lastStatus_right) {
if (lastStatus_right != -1)
falconEnv.RightButtonHandler();
lastStatus_right = value;
}
if (button == UP && value != lastStatus_up) {
if (lastStatus_up != -1)
falconEnv.UpButtonHandler();
lastStatus_up = value;
}
if (button == CENTER && value != lastStatus_center) {
if (lastStatus_center != -1)
falconEnv.CenterButtonHandler();
lastStatus_center = value;
}
if (button == LEFT && value != lastStatus_left) {
if (lastStatus_left != -1)
falconEnv.LeftButtonHandler();
lastStatus_left = value;
}
}
}
}
我尝试将项目恢复到一切正常的先前版本,尝试重新编译项目,但错误仍然存在。我也尝试使用ros2bag来检查状态,但是当我运行程序时,它订阅了该主题,并且项目再次开始正常工作。
有谁知道我能做些什么来解决这个问题?
答: 暂无答案
评论