From ac4c6c28161317aa1a0741c432924feb515c41ec Mon Sep 17 00:00:00 2001 From: Robofish <1683502971@qq.com> Date: Wed, 9 Apr 2025 00:53:41 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0ps2=E6=89=8B=E6=9F=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ps2_controller/CMakeLists.txt | 22 ++++ src/ps2_controller/package.xml | 20 +++ src/ps2_controller/src/ps2_reader.cpp | 123 ++++++++++++++++++ src/rc_msgs/msg/Ps2Data.msg | 5 + .../src/unitree_motor_serial_driver.cpp | 10 +- 5 files changed, 173 insertions(+), 7 deletions(-) create mode 100644 src/ps2_controller/CMakeLists.txt create mode 100644 src/ps2_controller/package.xml create mode 100644 src/ps2_controller/src/ps2_reader.cpp diff --git a/src/ps2_controller/CMakeLists.txt b/src/ps2_controller/CMakeLists.txt new file mode 100644 index 0000000..c9e2c8a --- /dev/null +++ b/src/ps2_controller/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.5) +project(ps2_controller) + +# Default to C++17 +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 17) +endif() + +# Find dependencies +find_package(ament_cmake REQUIRED) +find_package(rclcpp REQUIRED) +find_package(rc_msgs REQUIRED) # 添加对 rc_msgs 的依赖 + +add_executable(ps2_reader src/ps2_reader.cpp) + +ament_target_dependencies(ps2_reader rclcpp rc_msgs) # 添加 rc_msgs 依赖 + +install(TARGETS + ps2_reader + DESTINATION lib/${PROJECT_NAME}) + +ament_package() \ No newline at end of file diff --git a/src/ps2_controller/package.xml b/src/ps2_controller/package.xml new file mode 100644 index 0000000..93ef87f --- /dev/null +++ b/src/ps2_controller/package.xml @@ -0,0 +1,20 @@ + + + + ps2_controller + 0.0.0 + TODO: Package description + robofish + TODO: License declaration + + ament_cmake + + rclcpp + rc_msgs + ament_lint_auto + ament_lint_common + + + ament_cmake + + diff --git a/src/ps2_controller/src/ps2_reader.cpp b/src/ps2_controller/src/ps2_reader.cpp new file mode 100644 index 0000000..9635192 --- /dev/null +++ b/src/ps2_controller/src/ps2_reader.cpp @@ -0,0 +1,123 @@ +#include +#include +#include +#include +#include +#include +#include "rc_msgs/msg/ps2_data.hpp" // 引入 Ps2Data 消息类型 + +class PS2ControllerNode : public rclcpp::Node +{ +public: + PS2ControllerNode() : Node("ps2_controller_node") + { + this->declare_parameter("device", "/dev/input/js0"); + device_path_ = this->get_parameter("device").as_string(); + + joystick_fd_ = open(device_path_.c_str(), O_RDONLY | O_NONBLOCK); + if (joystick_fd_ < 0) + { + RCLCPP_ERROR(this->get_logger(), "Failed to open device: %s", device_path_.c_str()); + return; + } + + RCLCPP_INFO(this->get_logger(), "Connected to device: %s", device_path_.c_str()); + + ps2_data_ = std::make_shared(); + publisher_ = this->create_publisher("ps2_data", 10); + + timer_ = this->create_wall_timer( + std::chrono::milliseconds(10), // 100Hz + std::bind(&PS2ControllerNode::publishData, this)); + } + + ~PS2ControllerNode() + { + if (joystick_fd_ >= 0) + { + close(joystick_fd_); + } + } + +private: + void publishData() + { + readJoystick(); + publisher_->publish(*ps2_data_); + } + + void readJoystick() + { + struct js_event event; + while (read(joystick_fd_, &event, sizeof(event)) > 0) + { + switch (event.type & ~JS_EVENT_INIT) + { + case JS_EVENT_BUTTON: + handleButtonEvent(event); + break; + case JS_EVENT_AXIS: + handleAxisEvent(event); + break; + default: + break; + } + } + } + + void handleButtonEvent(const js_event &event) + { + switch (event.number) + { + case 10: ps2_data_->select = event.value; break; + case 11: ps2_data_->start = event.value; break; + case 6: ps2_data_->l1 = event.value; break; + case 8: ps2_data_->l2 = event.value; break; + case 7: ps2_data_->r1 = event.value; break; + case 9: ps2_data_->r2 = event.value; break; + case 3: ps2_data_->x = event.value; break; + case 4: ps2_data_->y = event.value; break; + case 0: ps2_data_->a = event.value; break; + case 1: ps2_data_->b = event.value; break; + default: + break; + } + } + + void handleAxisEvent(const js_event &event) + { + constexpr float MAX_AXIS_VALUE = 32767.0f; // 最大轴值 + constexpr float MIN_AXIS_VALUE = -32768.0f; // 最小轴值 + + auto normalize = [](int value) -> float { + return static_cast(value) / MAX_AXIS_VALUE; + }; + + switch (event.number) + { + case 0: ps2_data_->lx = normalize(event.value); break; + case 1: ps2_data_->ly = normalize(event.value); break; + case 2: ps2_data_->rx = normalize(event.value); break; + case 3: ps2_data_->ry = normalize(event.value); break; + case 6: ps2_data_->left_right = normalize(event.value); break; + case 7: ps2_data_->up_down = normalize(event.value); break; + default: + break; + } + } + + std::string device_path_; + int joystick_fd_; + rclcpp::TimerBase::SharedPtr timer_; + rclcpp::Publisher::SharedPtr publisher_; + std::shared_ptr ps2_data_; +}; + +int main(int argc, char *argv[]) +{ + rclcpp::init(argc, argv); + auto node = std::make_shared(); + rclcpp::spin(node); + rclcpp::shutdown(); + return 0; +} \ No newline at end of file diff --git a/src/rc_msgs/msg/Ps2Data.msg b/src/rc_msgs/msg/Ps2Data.msg index 2b52c1c..0761847 100644 --- a/src/rc_msgs/msg/Ps2Data.msg +++ b/src/rc_msgs/msg/Ps2Data.msg @@ -15,6 +15,11 @@ bool r2 # 四种模式 uint8 mode # 0:手柄控制 1:键盘控制 2:自瞄 3:手动瞄准 +bool x +bool y +bool a +bool b + bool select bool start diff --git a/src/unitree_motor_serial_driver/src/unitree_motor_serial_driver.cpp b/src/unitree_motor_serial_driver/src/unitree_motor_serial_driver.cpp index f93a059..38f978d 100644 --- a/src/unitree_motor_serial_driver/src/unitree_motor_serial_driver.cpp +++ b/src/unitree_motor_serial_driver/src/unitree_motor_serial_driver.cpp @@ -14,7 +14,7 @@ namespace unitree_motor_serial_driver bool connection_success = false; int attempts = 0; - + timer_count_ = 0; // 其余代码保持不变 timer_ = this->create_wall_timer( std::chrono::microseconds(1000), std::bind(&MotorControlNode::control_motor, this)); @@ -56,15 +56,11 @@ void MotorControlNode::control_motor() cmd.dq = motor[i].cmd.dq; cmd.tau = motor[i].cmd.tau; - if (timer_count_ > 100) + if (timer_count_ = 100) { Motor_Ctrl_Offline(&motor[i]); - timer_count_ = 0; - } - else - { - timer_count_++; } + timer_count_++; // 添加异常处理以防止程序崩溃 try {