Gazebo Fortress 中无法获取旋转物体的实时位置
-
可以把我的模型简单地理解为一个风车。
我在旋转轴上加了一个 JointController 插件,通过 ros topic 发布速度以控制它的旋转。
但是现在这个 joint 并不旋转,而是连接的 child link 在旋转。
这导致了我无法通过 /tf 获取风车扇叶上某点的实时位置,我通过 /tf 或者 /static_tf 获取的都是静止的,没有旋转的扇叶点的三维坐标。
我在 Rviz2 里面观察我的风车也能看到,它没有在旋转。但是在 Gazebo 中能观察到旋转。
以下是我的 xacro 文件。我通过
robot_description = ParameterValue(Command(['xacro ', buff_model_path]), value_type=str) robot_state_publisher_node = Node( package='robot_state_publisher', executable='robot_state_publisher', parameters=[{'robot_description': robot_description}] ) joint_state_publisher_node = Node( package='joint_state_publisher', executable='joint_state_publisher', name='joint_state_publisher', parameters=[{'robot_description': robot_description}] ) spawn_entity_cmd = Node( package='ros_gz_sim', executable='create', arguments=['-name', 'buff', '-topic', 'robot_description', '-x', '0.0', '-y', '0.0', '-z', '0.0'], output='screen' )
将其发布到我的世界里。
<?xml version="1.0"?> <robot name="buff" xmlns:xacro="http://www.ros.org/wiki/xacro"> <xacro:property name="M_PI" value="3.1415926535"/> <xacro:property name="fan_arm_length" value="0.7"/> <gazebo> <plugin filename="gz-sim-joint-controller-system" name="gz::sim::systems::JointController"> <joint_name>base_horizon_base_axle</joint_name> <initial_velocity>1.0471975512</initial_velocity> <topic>/changeBuffSpeed</topic> </plugin> </gazebo> <xacro:macro name="base_cube" params="name a b c mass"> <link name="${name}"> <visual name="visual"> <geometry> <box size="${a} ${b} ${c}"/> </geometry> </visual> <collision name="collision"> <geometry> <box size="${a} ${b} ${c}"/> </geometry> </collision> <inertial> <mass value="${mass}"/> <origin rpy="0 0 0" xyz="0 0 0"/> <inertia ixx="${mass*(b*b + c*c)/12}" ixy="0" ixz="0" iyy="${mass*(a*a + c*c)/12}" iyz="0" izz="${mass*(a*a + b*b)/12}"/> </inertial> </link> <gazebo reference="${name}"> <material>Gazebo/Red</material> <!-- 修正重力标签语法 --> <gravity>true</gravity> </gazebo> </xacro:macro> <xacro:macro name="joint" params="parent child type xyz rpy"> <joint name="${parent}_${child}" type="${type}"> <parent link="${parent}"/> <child link="${child}"/> <origin xyz="${xyz}" rpy="${rpy}"/> <axis xyz="0 0 1"></axis> </joint> </xacro:macro> <xacro:macro name="base_cylinder" params="name radius length"> <link name="${name}"> <visual name="visual"> <geometry> <cylinder radius="${radius}" length="${length}"/> </geometry> </visual> <collision name="collision"> <geometry> <cylinder radius="${radius}" length="${length}"/> </geometry> </collision> <inertial> <mass value="1"/> <origin rpy="0 0 0" xyz="0 0 0"/> <inertia ixx="1e-6" ixy="0" ixz="0" iyy="1e-6" iyz="0" izz="1e-6"/> </inertial> </link> </xacro:macro> <xacro:macro name="withPNG_cylinder" params="name radius length mesh"> <link name="${name}"> <visual name="visual"> <geometry> <mesh filename="$(find sim)/model/${mesh}"/> </geometry> </visual> <collision name="collision_${name}"> <geometry> <cylinder radius="${radius}" length="${length}"/> </geometry> </collision> <inertial> <mass value="1"/> <origin rpy="0 0 0" xyz="0 0 0"/> <inertia ixx="1e-6" ixy="0" ixz="0" iyy="1e-6" iyz="0" izz="1e-6"/> </inertial> </link> </xacro:macro> <xacro:macro name="buff_fan" params="prefix reflect fan_id special"> <xacro:base_cube name="${prefix}_fan_arm_${fan_id}" a="${fan_arm_length}" b="0.050" c="0.04" mass="1.0"/> <xacro:base_cube name="${prefix}_fan_${fan_id}" a="0.372" b="0.372" c="0.05" mass="1.0"/> <xacro:withPNG_cylinder name="${prefix}_fan_hitArea_${fan_id}" radius="0.15" length="0.05" mesh="targets.dae"/> <xacro:joint parent="R_logo_${prefix}" child="${prefix}_fan_arm_${fan_id}" type="fixed" xyz="${-cos((fan_id-1)*72/180*M_PI)*fan_arm_length/2} ${-sin((fan_id-1)*72/180*M_PI)*fan_arm_length/2} ${special}" rpy="0 0 ${72*(fan_id-1)/180*M_PI}" /> <xacro:joint parent="${prefix}_fan_arm_${fan_id}" child="${prefix}_fan_${fan_id}" type="fixed" xyz="${-fan_arm_length/2} 0 0" rpy="0 0 0" /> <xacro:joint parent="${prefix}_fan_${fan_id}" child="${prefix}_fan_hitArea_${fan_id}" type="fixed" xyz="0 0 ${0.00001*reflect}" rpy="0 0 0"/> </xacro:macro> <xacro:base_cylinder name="base_axle" radius="0.008" length="0.2"/> <xacro:macro name="buff" params="prefix reflect"> <xacro:withPNG_cylinder name="R_logo_${prefix}" radius="0.106" length="0.05" mesh="R_logo.dae"/> <xacro:joint parent="base_axle" child="R_logo_${prefix}" type="fixed" xyz="0 0 ${reflect*0.1}" rpy="0 0 0"/> <xacro:buff_fan reflect="${reflect}" prefix="${prefix}" fan_id="1" special="0"/> <xacro:buff_fan reflect="${reflect}" prefix="${prefix}" fan_id="2" special="0"/> <xacro:buff_fan reflect="${reflect}" prefix="${prefix}" fan_id="3" special="0"/> <xacro:buff_fan reflect="${reflect}" prefix="${prefix}" fan_id="4" special="0"/> <xacro:buff_fan reflect="${reflect}" prefix="${prefix}" fan_id="5" special="0"/> </xacro:macro> <xacro:base_cube name="base" a="3.00" b="3.00" c="0.10" mass="9.0"/> <xacro:base_cube name="base_left" a="0.15" b="0.15" c="2.60" mass="1.0"/> <xacro:base_cube name="base_right" a="0.15" b="0.15" c="2.60" mass="1.0"/> <xacro:base_cube name="base_horizon" a="0.15" b="1.80" c="0.15" mass="1.0"/> <link name="world"/> <joint name="fixed" type="fixed"> <parent link="world"/> <child link="base"/> </joint> <xacro:joint parent="base" child="base_horizon" type="fixed" xyz="0 0.0 2.6" rpy="0 0 0"/> <xacro:joint parent="base_horizon" child="base_left" type="fixed" xyz="0 -0.9 -1.3" rpy="0 0 0"/> <xacro:joint parent="base_horizon" child="base_right" type="fixed" xyz="0 0.9 -1.3" rpy="0 0 0"/> <xacro:joint parent="base_horizon" child="base_axle" type="continuous" xyz="0 0.0 0.0" rpy="0 ${M_PI/2} 0"/> <xacro:buff prefix="front" reflect=" 1"/> <xacro:buff prefix="back" reflect="-1"/> </robot>
或者有什么别的插件可以获取扇叶点的实时位置吗?
-
针对您在Gazebo Fortress中遇到的问题,即无法获取旋转物体(风车扇叶)的实时位置,这里提供几种可能的解决方案和考虑因素:
1. 确认JointController插件的配置和使用
首先,确保您的
JointController
插件已正确配置并加载到Gazebo中。从您的描述来看,插件似乎能够控制旋转轴的速度,因为您在Gazebo中观察到了旋转。但是,需要确认以下几点:- 插件名称和文件名:确保
filename
属性中的插件名称与您的系统中实际存在的插件文件名相匹配。在您的xacro文件中,使用的是gz-sim-joint-controller-system
,请确认这是否正确。 - Joint名称:确认
joint_name
属性中的名称与您的URDF/SDF文件中定义的旋转轴名称相匹配。 - 话题名称:确保您发布速度到的话题名称与插件中定义的话题名称相匹配。
2. 检查TF变换的发布
由于您在Rviz中观察到的风车没有旋转,这可能是由于TF变换没有正确发布。请检查以下几点:
- TF树:使用
rosrun tf view_frames
和evince frames.pdf
命令查看当前的TF树,确认是否存在从旋转轴到扇叶的TF变换。 - 静态TF与动态TF:确认您是否使用了正确的TF类型。在您的情况下,由于扇叶是旋转的,应该使用动态TF而不是静态TF。
- 发布频率:检查TF变换的发布频率是否足够高,以捕捉旋转的动态变化。
3. 考虑使用其他插件或方法
如果上述方法都无法解决问题,您可以考虑使用其他插件或方法来获取扇叶的实时位置。例如:
- 自定义插件:编写一个自定义的Gazebo插件,该插件可以定期获取扇叶的位置并发布到ROS话题上。这需要一定的编程知识,但提供了很大的灵活性。
- 使用传感器:在Gazebo中添加一个虚拟的传感器(如摄像头或激光雷达),该传感器可以捕捉扇叶的位置信息。然后,您可以使用计算机视觉或点云处理算法来提取扇叶的位置。
- ROS 2与Gazebo Fortress的集成:由于您使用的是Gazebo Fortress,可以考虑利用ROS 2与Gazebo的紧密集成来获取更丰富的信息和更好的性能。例如,使用ROS 2的
rclpy
或rclcpp
库来编写一个节点,该节点可以订阅Gazebo发布的主题并处理扇叶的位置信息。
4. 调试和测试
在进行任何更改后,请确保进行充分的调试和测试。这包括:
- 在Gazebo中观察:直接在Gazebo中观察更改后的行为,确保旋转和TF变换都按预期工作。
- 使用Rviz:在Rviz中加载TF树并观察扇叶的位置是否更新。
- 发布和订阅话题:使用
rostopic echo
和rostopic pub
命令来测试和验证话题的发布和订阅。
综上所述,解决您的问题可能需要综合考虑多个方面,包括插件配置、TF变换的发布、自定义插件或方法的使用以及调试和测试。希望这些建议对您有所帮助!
以上为生成回答,仅供参考~
- 插件名称和文件名:确保