gstsreamer----------could not get plugin ioctl base:-22

本文介绍了解决视频压缩失败的方法,特别是当视频可以预览但无法压缩时的情况。通过对比不同内核模块,指出了缺失的模块,并提供了重新编译内核模块的具体步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//gstreamer官方网站

http://gstreamer.freedesktop.org/modules/qt-gstreamer.html


视频可以成功预览

sudo gst-launch-0.10 v4l2src  device=/dev/video3 sensor_name="adv7280m_a 3-0020" inputnum=1 ! video/x-r 


在视频不能压缩,但能够预览时,会出现这个问题:

dce.c:459 init error: could not get plugin ioctl base:-22

与可以压缩的内核对比lsmod出来的东西,发现缺少模块





这个其实是由于内核中一些模块没有装载成功所导致的,视频压缩时用到了这些模块(按装载的先后顺序)


virtio.ko
virtio_ring.ko
virtio_rpmsg_bus.ko

remoteproc.ko
omap_remoteproc.ko

rpmsg_omx.ko
rpmsg_resmgr.ko
rpmsg_resmgr_common.ko
omap_rpmsg_resmgr.ko

omapdce.ko
omaprpc.ko


如果上述模块没有全部装载,则会导致dce 初始化出错。

解决办法是在内核重新编译后,需要根据当前的内核源码重新编译这些模块。

模块编译命令:
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- M=drivers/virtio modules
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- M=drivers/remoteproc modules
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- M=drivers/rpmsg modules
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- M=drivers/staging/omaprpc modules
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- M=drivers/staging/omapdce modules

在编译模块时,可能会出现
WARNING: "set_xyz" [drivers/usb/test/xyz.ko] undefined!之类的问题
这是由于某些模块(假设为B模块)不仅依赖于内核uImage本身,而且还依赖于其他内核模块(假设为A模块),我们需要在编译A模块时产生的
Module.symvers追加到内核目录下的Module.symvers,用这个命令:
cat Module.symvers >> Kernel_DIR/Module.symvers

然后再编译B模块,就不会产生 undefined!之类的问题。
xyg@xyg-T6AD:~$ cd ~/ros2_ws colcon build --packages-select pca9685_hardware source install/setup.bash Starting >>> pca9685_hardware --- stderr: pca9685_hardware /home/xyg/ros2_ws/src/pca9685_hardware/src/pca9685_system_hardware.cpp:9:1: error: ‘CallbackReturn’ does not name a type 9 | CallbackReturn Pca9685SystemHardware::on_init(const hardware_interface::HardwareInfo& info) | ^~~~~~~~~~~~~~ /home/xyg/ros2_ws/src/pca9685_hardware/src/pca9685_system_hardware.cpp: In member function ‘virtual std::vector<hardware_interface::StateInterface> pca9685_hardware::Pca9685SystemHardware::export_state_interfaces()’: /home/xyg/ros2_ws/src/pca9685_hardware/src/pca9685_system_hardware.cpp:44:37: error: ‘HW_IF_POSITION’ is not a member of ‘hardware_interface’ 44 | hardware_interface::HW_IF_POSITION, | ^~~~~~~~~~~~~~ /home/xyg/ros2_ws/src/pca9685_hardware/src/pca9685_system_hardware.cpp: In member function ‘virtual std::vector<hardware_interface::CommandInterface> pca9685_hardware::Pca9685SystemHardware::export_command_interfaces()’: /home/xyg/ros2_ws/src/pca9685_hardware/src/pca9685_system_hardware.cpp:59:37: error: ‘HW_IF_POSITION’ is not a member of ‘hardware_interface’ 59 | hardware_interface::HW_IF_POSITION, | ^~~~~~~~~~~~~~ /home/xyg/ros2_ws/src/pca9685_hardware/src/pca9685_system_hardware.cpp: At global scope: /home/xyg/ros2_ws/src/pca9685_hardware/src/pca9685_system_hardware.cpp:67:1: error: ‘CallbackReturn’ does not name a type 67 | CallbackReturn Pca9685SystemHardware::on_activate(const rclcpp_lifecycle::State& previous_state) | ^~~~~~~~~~~~~~ /home/xyg/ros2_ws/src/pca9685_hardware/src/pca9685_system_hardware.cpp:126:1: error: ‘CallbackReturn’ does not name a type 126 | CallbackReturn Pca9685SystemHardware::on_deactivate(const rclcpp_lifecycle::State& previous_state) | ^~~~~~~~~~~~~~ /home/xyg/ros2_ws/src/pca9685_hardware/src/pca9685_system_hardware.cpp: In member function ‘virtual hardware_interface::return_type pca9685_hardware::Pca9685SystemHardware::read(const rclcpp::Time&, const rclcpp::Duration&)’: /home/xyg/ros2_ws/src/pca9685_hardware/src/pca9685_system_hardware.cpp:152:81: warning: unused parameter ‘time’ [-Wunused-parameter] 152 | return_type Pca9685SystemHardware::read(const rclcpp::Time& time, const rclcpp::Duration& period) | ~~~~~~~~~~~~~~~~~~~~^~~~ /home/xyg/ros2_ws/src/pca9685_hardware/src/pca9685_system_hardware.cpp:152:111: warning: unused parameter ‘period’ [-Wunused-parameter] 152 | ardware::read(const rclcpp::Time& time, const rclcpp::Duration& period) | ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~ /home/xyg/ros2_ws/src/pca9685_hardware/src/pca9685_system_hardware.cpp: In member function ‘virtual hardware_interface::return_type pca9685_hardware::Pca9685SystemHardware::write(const rclcpp::Time&, const rclcpp::Duration&)’: /home/xyg/ros2_ws/src/pca9685_hardware/src/pca9685_system_hardware.cpp:159:82: warning: unused parameter ‘time’ [-Wunused-parameter] 159 | eturn_type Pca9685SystemHardware::write(const rclcpp::Time& time, const rclcpp::Duration& period) | ~~~~~~~~~~~~~~~~~~~~^~~~ /home/xyg/ros2_ws/src/pca9685_hardware/src/pca9685_system_hardware.cpp:159:112: warning: unused parameter ‘period’ [-Wunused-parameter] 159 | rdware::write(const rclcpp::Time& time, const rclcpp::Duration& period) | ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~ gmake[2]: *** [CMakeFiles/pca9685_hardware.dir/build.make:76:CMakeFiles/pca9685_hardware.dir/src/pca9685_system_hardware.cpp.o] 错误 1 gmake[1]: *** [CMakeFiles/Makefile2:137:CMakeFiles/pca9685_hardware.dir/all] 错误 2 gmake: *** [Makefile:146:all] 错误 2 --- Failed <<< pca9685_hardware [2.25s, exited with code 2] Summary: 0 packages finished [2.39s] 1 package failed: pca9685_hardware 1 package had stderr output: pca9685_hardware not found: "/home/xyg/ros2_ws/install/pca9685_hardware/share/pca9685_hardware/local_setup.bash" xyg@xyg-T6AD:~/ros2_ws$ ros2 control list_hardware_components | grep PCA9685 # 应输出: pca9685_hardware/Pca9685SystemHardware [INFO] [1750735736.192545351] [_ros2cli_16699]: waiting for service /controller_manager/list_hardware_components to become available... [WARN] [1750735746.210548769] [_ros2cli_16699]: Could not contact service /controller_manager/list_hardware_components [INFO] [1750735746.210767288] [_ros2cli_16699]: waiting for service /controller_manager/list_hardware_components to become available... ^C 以下分别是pca9685_params.yaml:pca9685_hardware: ros__parameters: hardware: plugin: "pca9685_hardware/Pca9685SystemHardware" i2c_bus: "i2c-1" # 移除/dev/前缀,代码中会自动添加 i2c_address: "0x33" # I2C地址保持不变 channel_mapping: "5,7,9,11,13,15" # 使用逗号分隔的字符串格式 joints: - joint1 # 关节名称与机器人结构对应 - joint2 - joint3 - joint4 - joint5 - joint6然后是pca9685_system_hardware.hpp:#ifndef PCA9685_HARDWARE__PCA9685_SYSTEM_HARDWARE_HPP_ #define PCA9685_HARDWARE__PCA9685_SYSTEM_HARDWARE_HPP_ #include <hardware_interface/types/hardware_interface_return_values.hpp> #include <hardware_interface/system_interface.hpp> #include <rclcpp_lifecycle/state.hpp> #include <rclcpp/logger.hpp> #include <memory> #include <vector> #include <string> #include <fcntl.h> #include <linux/i2c-dev.h> #include <unistd.h> namespace pca9685_hardware { class Pca9685SystemHardware : public hardware_interface::SystemInterface { public: using CallbackReturn = hardware_interface::CallbackReturn; using ReturnType = hardware_interface::return_type; CallbackReturn on_init(const hardware_interface::HardwareInfo& info) override; std::vector<hardware_interface::StateInterface> export_state_interfaces() override; std::vector<hardware_interface::CommandInterface> export_command_interfaces() override; CallbackReturn on_activate(const rclcpp_lifecycle::State& previous_state) override; CallbackReturn on_deactivate(const rclcpp_lifecycle::State& previous_state) override; ReturnType read(const rclcpp::Time& time, const rclcpp::Duration& period) override; ReturnType write(const rclcpp::Time& time, const rclcpp::Duration& period) override; private: int i2c_fd_; std::string i2c_bus_; int i2c_address_; std::vector<int> channel_mapping_; std::vector<double> hw_commands_; std::vector<double> hw_states_; bool write_byte_data(int reg, uint8_t value); bool write_word_data(int reg, uint16_t value); uint8_t read_byte_data(int reg); }; } // namespace pca9685_hardware #endif // PCA9685_HARDWARE__PCA9685_SYSTEM_HARDWARE_HPP_ 然后是:pca9685_hardware_plugin.xml:<library path="libpca9685_hardware"> <class name="pca9685_hardware/Pca9685SystemHardware" type="pca9685_hardware::Pca9685SystemHardware" base_class_type="hardware_interface::SystemInterface"> <description>PCA9685 PWM控制器硬件接口</description> </class> </library> 还有:pca9685_system_hardware.cpp:#include "pca9685_hardware/pca9685_system_hardware.hpp" #include <hardware_interface/types/hardware_interface_return_values.hpp> #include <rclcpp/rclcpp.hpp> #include <cmath> namespace pca9685_hardware { CallbackReturn Pca9685SystemHardware::on_init(const hardware_interface::HardwareInfo& info) { if (SystemInterface::on_init(info) != CallbackReturn::SUCCESS) { return CallbackReturn::ERROR; } try { i2c_bus_ = info.hardware_parameters.at("i2c_bus"); i2c_address_ = std::stoi(info.hardware_parameters.at("i2c_address"), nullptr, 16); std::string channel_str = info.hardware_parameters.at("channel_mapping"); std::istringstream iss(channel_str); std::string token; while (std::getline(iss, token, ',')) { channel_mapping_.push_back(std::stoi(token)); } hw_commands_.resize(info.joints.size(), 0.0); hw_states_.resize(info.joints.size(), 0.0); return CallbackReturn::SUCCESS; } catch (const std::exception& e) { RCLCPP_ERROR(rclcpp::get_logger("pca9685_hardware"), "初始化失败: %s", e.what()); return CallbackReturn::ERROR; } } std::vector<hardware_interface::StateInterface> Pca9685SystemHardware::export_state_interfaces() { std::vector<hardware_interface::StateInterface> state_interfaces; for (size_t i = 0; i < hw_states_.size(); i++) { state_interfaces.emplace_back( hardware_interface::StateInterface( info_.joints[i].name, hardware_interface::HW_IF_POSITION, &hw_states_[i] ) ); } return state_interfaces; } std::vector<hardware_interface::CommandInterface> Pca9685SystemHardware::export_command_interfaces() { std::vector<hardware_interface::CommandInterface> command_interfaces; for (size_t i = 0; i < hw_commands_.size(); i++) { command_interfaces.emplace_back( hardware_interface::CommandInterface( info_.joints[i].name, hardware_interface::HW_IF_POSITION, &hw_commands_[i] ) ); } return command_interfaces; } CallbackReturn Pca9685SystemHardware::on_activate(const rclcpp_lifecycle::State& previous_state) { RCLCPP_INFO(rclcpp::get_logger("pca9685_hardware"), "激活硬件接口"); try { std::string device_path = "/dev/" + i2c_bus_; i2c_fd_ = open(device_path.c_str(), O_RDWR); if (i2c_fd_ < 0) { RCLCPP_ERROR(rclcpp::get_logger("pca9685_hardware"), "无法打开I2C设备: %s", device_path.c_str()); return CallbackReturn::ERROR; } if (ioctl(i2c_fd_, I2C_SLAVE, i2c_address_) < 0) { RCLCPP_ERROR(rclcpp::get_logger("pca9685_hardware"), "无法设置I2C地址: 0x%02X", i2c_address_); close(i2c_fd_); return CallbackReturn::ERROR; } // 初始化PCA9685 if (!write_byte_data(0x00, 0x01)) { // 复位 return CallbackReturn::ERROR; } usleep(50000); // 设置为普通模式 if (!write_byte_data(0x00, 0x00)) { return CallbackReturn::ERROR; } // 设置PWM频率为50Hz (20ms周期) uint8_t prescale = static_cast<uint8_t>(25000000.0 / (4096.0 * 50.0) - 1); uint8_t old_mode = read_byte_data(0x00); uint8_t new_mode = (old_mode & 0x7F) | 0x10; // 进入睡眠模式 if (!write_byte_data(0x00, new_mode)) { return CallbackReturn::ERROR; } if (!write_byte_data(0xFE, prescale)) { return CallbackReturn::ERROR; } if (!write_byte_data(0x00, old_mode)) { return CallbackReturn::ERROR; } usleep(50000); if (!write_byte_data(0x00, old_mode | 0x80)) { // 启用自动递增 return CallbackReturn::ERROR; } RCLCPP_INFO(rclcpp::get_logger("pca9685_hardware"), "硬件接口激活成功"); return CallbackReturn::SUCCESS; } catch (const std::exception& e) { RCLCPP_ERROR(rclcpp::get_logger("pca9685_hardware"), "激活失败: %s", e.what()); if (i2c_fd_ >= 0) { close(i2c_fd_); } return CallbackReturn::ERROR; } } CallbackReturn Pca9685SystemHardware::on_deactivate(const rclcpp_lifecycle::State& previous_state) { RCLCPP_INFO(rclcpp::get_logger("pca9685_hardware"), "停用硬件接口"); try { // 关闭所有PWM通道 for (size_t i = 0; i < 16; i++) { if (!write_word_data(0x06 + 4 * i, 0)) { RCLCPP_WARN(rclcpp::get_logger("pca9685_hardware"), "关闭通道 %zu 失败", i); } } if (i2c_fd_ >= 0) { close(i2c_fd_); i2c_fd_ = -1; } RCLCPP_INFO(rclcpp::get_logger("pca9685_hardware"), "硬件接口停用成功"); return CallbackReturn::SUCCESS; } catch (const std::exception& e) { RCLCPP_ERROR(rclcpp::get_logger("pca9685_hardware"), "停用失败: %s", e.what()); return CallbackReturn::ERROR; } } hardware_interface::return_type Pca9685SystemHardware::read(const rclcpp::Time& time, const rclcpp::Duration& period) { // 舵机通常没有位置反馈,所以我们将命令值作为状态返回 hw_states_ = hw_commands_; return ReturnType::OK; } hardware_interface::return_type Pca9685SystemHardware::write(const rclcpp::Time& time, const rclcpp::Duration& period) { try { for (size_t i = 0; i < hw_commands_.size(); i++) { if (i >= channel_mapping_.size()) { RCLCPP_WARN(rclcpp::get_logger("pca9685_hardware"), "通道映射越界: %zu", i); continue; } // 将弧度转换为角度 (0-180度) double angle_rad = hw_commands_[i]; double angle_deg = std::fmod(std::fmod(angle_rad, 2 * M_PI) + 2 * M_PI, 2 * M_PI); angle_deg = std::clamp(angle_deg * 180.0 / M_PI, 0.0, 180.0); // 计算PWM脉冲宽度 (500-2500us对应0-180度) uint16_t pulse_width = static_cast<uint16_t>(500 + (angle_deg / 180.0) * (2500 - 500)); uint16_t pwm_value = static_cast<uint16_t>(pulse_width * 4096.0 / 20000.0); // 设置PWM输出 int channel = channel_mapping_[i]; if (channel < 0 || channel > 15) { RCLCPP_WARN(rclcpp::get_logger("pca9685_hardware"), "无效通道: %d", channel); continue; } // 设置PWM值 (0为关闭时间,pwm_value为开启时间) if (!write_word_data(0x06 + 4 * channel, 0)) { RCLCPP_WARN(rclcpp::get_logger("pca9685_hardware"), "设置通道 %d 关闭时间失败", channel); } if (!write_word_data(0x08 + 4 * channel, pwm_value)) { RCLCPP_WARN(rclcpp::get_logger("pca9685_hardware"), "设置通道 %d 开启时间失败", channel); } } return ReturnType::OK; } catch (const std::exception& e) { RCLCPP_ERROR(rclcpp::get_logger("pca9685_hardware"), "写入失败: %s", e.what()); return ReturnType::ERROR; } } bool Pca9685SystemHardware::write_byte_data(int reg, uint8_t value) { uint8_t buf[2] = {static_cast<uint8_t>(reg), value}; if (::write(i2c_fd_, buf, 2) != 2) { RCLCPP_ERROR(rclcpp::get_logger("pca9685_hardware"), "I2C写入失败: reg=0x%02X, value=0x%02X", reg, value); return false; } return true; } bool Pca9685SystemHardware::write_word_data(int reg, uint16_t value) { uint8_t buf[3] = { static_cast<uint8_t>(reg), static_cast<uint8_t>(value & 0xFF), static_cast<uint8_t>((value >> 8) & 0xFF) }; if (::write(i2c_fd_, buf, 3) != 3) { RCLCPP_ERROR(rclcpp::get_logger("pca9685_hardware"), "I2C写入失败: reg=0x%02X, value=0x%04X", reg, value); return false; } return true; } uint8_t Pca9685SystemHardware::read_byte_data(int reg) { uint8_t buf = static_cast<uint8_t>(reg); if (::write(i2c_fd_, &buf, 1) != 1) { RCLCPP_ERROR(rclcpp::get_logger("pca9685_hardware"), "I2C写入寄存器失败: reg=0x%02X", reg); return 0; } if (::read(i2c_fd_, &buf, 1) != 1) { RCLCPP_ERROR(rclcpp::get_logger("pca9685_hardware"), "I2C读取失败: reg=0x%02X", reg); return 0; } return buf; } } // namespace pca9685_hardware #include "pluginlib/class_list_macros.hpp" PLUGINLIB_EXPORT_CLASS(pca9685_hardware::Pca9685SystemHardware, hardware_interface::SystemInterface) CMakeLists.txt:cmake_minimum_required(VERSION 3.8) project(pca9685_hardware) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_compile_options(-Wall -Wextra -Wpedantic) endif() find_package(ament_cmake REQUIRED) find_package(hardware_interface REQUIRED) find_package(rclcpp REQUIRED) find_package(rclcpp_lifecycle REQUIRED) find_package(pluginlib REQUIRED) add_library( ${PROJECT_NAME} SHARED src/pca9685_system_hardware.cpp ) target_include_directories( ${PROJECT_NAME} PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include> ) ament_target_dependencies( ${PROJECT_NAME} "hardware_interface" "rclcpp" "rclcpp_lifecycle" "pluginlib" ) # 导出插件描述文件(确保resource目录存在) pluginlib_export_plugin_description_file(hardware_interface resource/pca9685_hardware_plugin.xml) install( TARGETS ${PROJECT_NAME} DESTINATION lib ) install( DIRECTORY include/ DESTINATION include ) # 安装插件描述文件(明确指定resource目录) install( FILES resource/pca9685_hardware_plugin.xml DESTINATION share/${PROJECT_NAME} ) ament_package() package.xml:<?xml version="1.0"?> <?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema-instance"?> <package format="3"> <name>pca9685_hardware</name> <version>0.0.1</version> <description>PCA9685 PWM Servo Driver Hardware Interface for ROS 2</description> <maintainer email="xyg@example.com">xyg</maintainer> <license>Apache License 2.0</license> <!-- 核心依赖 --> <depend>hardware_interface</depend> <depend>rclcpp</depend> <depend>pluginlib</depend> <depend>controller_manager</depend> <depend>rclcpp_lifecycle</depend> <!-- 测试依赖 --> <test_depend>ament_cmake</test_depend> <test_depend>ament_cmake_copyright</test_depend> <test_depend>ament_cmake_clang_format</test_depend> <test_depend>ament_cmake_cppcheck</test_depend> <!-- 移除所有Python相关依赖 --> <!-- 原test_depend已删除: ament_flake8, ament_pep257, python3-pytest --> <export> <!-- 改为ament_cmake编译类型 --> <build_type>ament_cmake</build_type> <!-- 硬件接口插件描述文件 --> <hardware_interface plugin="${prefix}/resource/plugin_description.xml" /> </export> </package> 以上是各个文件内容以及启动日志报错内容
最新发布
06-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值