景县网站建设公司,如何建一个商业网站,mssql网站开发,网站展现形式生成模型
通过服务调用生成
还记得parameter_bridge 吗#xff1f;
我们在生成桥接的时候调用了这个cpp文件。 一个 parameter_bridge 实例用于消息传递#xff08;传感器数据#xff09;。之前的例子 另一个 parameter_bridge 实例用于服务桥接#xff08;动态生成模型…生成模型
通过服务调用生成
还记得parameter_bridge 吗
我们在生成桥接的时候调用了这个cpp文件。 一个 parameter_bridge 实例用于消息传递传感器数据。之前的例子 另一个 parameter_bridge 实例用于服务桥接动态生成模型。现在的例子 实现多开的方法
1. 启动消息桥接
用第一个 parameter_bridge 实例桥接消息话题例如传递传感器数据
ros2 run ros_gz_bridge parameter_bridge /scansensor_msgs/msg/LaserScangz.msgs.LaserScan功能桥接 Gazebo 和 ROS 2 的激光雷达数据。 2. 启动服务桥接
启动第二个 parameter_bridge 实例用于桥接服务例如生成模型
ros2 run ros_gz_bridge parameter_bridge /world/empty/createros_gz_interfaces/srv/SpawnEntity功能桥接 Gazebo 和 ROS 2 的服务允许通过 ROS 2 服务生成模型。 3. 发送请求生成模型
在服务桥接启动后使用以下命令发送生成模型的请求
ros2 service call /world/empty/create ros_gz_interfaces/srv/SpawnEntity \{name: my_robot, sdf: 完整的SDF内容, pose: {position: {x: 0.0, y: 0.0, z: 0.0}, orientation: {x: 0.0, y: 0.0, z: 0.0, w: 1.0}}}总结两种调用的区别
功能话题桥接服务桥接调用命令/scansensor_msgs/msg/LaserScangz.msgs.LaserScan/world/empty/createros_gz_interfaces/srv/SpawnEntity桥接对象ROS 2 和 Gazebo 的话题ROS 2 和 Gazebo 的服务桥接方向支持单向或双向GZ_TO_ROS、ROS_TO_GZ 或 BIDIRECTIONAL服务请求从 ROS 2 转发到 Gazebo返回响应使用场景数据流桥接如传感器数据动作桥接如动态生成模型 同时运行的效果
两个 parameter_bridge 实例可以独立运行并不会互相干扰。一个处理话题消息另一个处理服务请求。 parameter_bridge 中服务桥接的实现
在这个调用服务的过程中我十分好奇到底是哪一个地方起了作用。
关键实现代码 解析服务参数 if (config.ros_type_name.find(/srv/) ! std::string::npos) {std::string gz_req_type_name;std::string gz_rep_type_name;if (config.direction BridgeDirection::ROS_TO_GZ ||config.direction BridgeDirection::GZ_TO_ROS) {usage();return -1;}if (config.direction BridgeDirection::BIDIRECTIONAL) {delimPos arg.find(delim);if (delimPos std::string::npos || delimPos 0) {usage();return -1;}gz_req_type_name arg.substr(0, delimPos);arg.erase(0, delimPos delim.size());gz_rep_type_name std::move(arg);}try {bridge_node-add_service_bridge(config.ros_type_name,gz_req_type_name,gz_rep_type_name,config.ros_topic_name);} catch (std::runtime_error e) {std::cerr e.what() std::endl;}continue;
}解析传入参数判断是否为服务桥接ros_type_name 包含 /srv/。处理服务的请求类型和响应类型gz_req_type_name 和 gz_rep_type_name。 调用服务桥接方法 bridge_node-add_service_bridge(config.ros_type_name,gz_req_type_name,gz_rep_type_name,config.ros_topic_name);使用 RosGzBridge::add_service_bridge 方法注册服务桥接。桥接逻辑会将 ROS 2 的服务请求转发给 Gazebo 服务并将响应返回给 ROS 2 客户端。 服务桥接的核心逻辑 Gazebo 服务通过内部的 Gazebo Transport 提供功能。ROS 2 服务通过 rclcpp 提供功能。桥接会订阅 Gazebo 服务并将其暴露为一个 ROS 2 服务。响应流向 ROS 2 客户端 - ROS 2 服务。ROS 2 服务 - Gazebo 服务。Gazebo 服务 - ROS 2 服务 - ROS 2 客户端。 通过自带包生成
在ros_gz_sim里面有一个gz_spawn_model的东西它可以帮助我们在一个已经建成的gz中添加模型。
ros2 launch ros_gz_sim gz_spawn_model.launch.py world:empty file:$(ros2 pkg prefix --share ros_gz_sim_demos)/models/vehicle/model.sdf entity_name:my_vehicle x:5.0 y:5.0 z:0.5你可以打开这个文件看看哪个没有默认值没有默认值的需要你指定参数。一般是 world和file需要指定参数。
自定义配置
在功能包里面创建xml或者launch.py就行了
例如
launcharg nameworld default /arg namefile default /arg namemodel_string default /arg nametopic default /arg nameentity_name default /arg nameallow_renaming defaultFalse /arg namex default /arg namey default /arg namez default /arg nameroll default /arg namepitch default /arg nameyaw default /gz_spawn_model world$(var world)file$(var file)model_string$(var model_string)topic$(var topic)entity_name$(var entity_name)allow_renaming$(var allow_renaming)x$(var x)y$(var y)z$(var z)roll$(var roll)pitch$(var pitch)yaw$(var yaw)/gz_spawn_model
/launchfrom launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Nodedef generate_launch_description():# Declare argumentsreturn LaunchDescription([DeclareLaunchArgument(world, default_value, descriptionName of the Gazebo world),DeclareLaunchArgument(file, default_value, descriptionPath to the model file),DeclareLaunchArgument(model_string, default_value, descriptionModel description as a string),DeclareLaunchArgument(topic, default_value, descriptionGazebo topic to use),DeclareLaunchArgument(entity_name, default_value, descriptionName of the entity to spawn),DeclareLaunchArgument(allow_renaming, default_valueFalse, descriptionAllow renaming of the entity),DeclareLaunchArgument(x, default_value0.0, descriptionX position of the model),DeclareLaunchArgument(y, default_value0.0, descriptionY position of the model),DeclareLaunchArgument(z, default_value0.0, descriptionZ position of the model),DeclareLaunchArgument(roll, default_value0.0, descriptionRoll rotation of the model),DeclareLaunchArgument(pitch, default_value0.0, descriptionPitch rotation of the model),DeclareLaunchArgument(yaw, default_value0.0, descriptionYaw rotation of the model),# Gazebo spawn model nodeNode(packageros_gz_sim,executablegz_spawn_model,outputscreen,namespawn_model,parameters[{world: LaunchConfiguration(world)},{file: LaunchConfiguration(file)},{model_string: LaunchConfiguration(model_string)},{topic: LaunchConfiguration(topic)},{entity_name: LaunchConfiguration(entity_name)},{allow_renaming: LaunchConfiguration(allow_renaming)},{x: LaunchConfiguration(x)},{y: LaunchConfiguration(y)},{z: LaunchConfiguration(z)},{roll: LaunchConfiguration(roll)},{pitch: LaunchConfiguration(pitch)},{yaw: LaunchConfiguration(yaw)}]),])当然我们也可以简化一些
我们调用了parameter_bridge
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfigurationdef generate_launch_description():# 创建 LaunchDescriptionld LaunchDescription()# 声明参数ld.add_action(DeclareLaunchArgument(entity_name, default_valuemy_robot, descriptionName of the entity to spawn))ld.add_action(DeclareLaunchArgument(file, default_value/path/to/your/model.sdf, descriptionPath to the model file))ld.add_action(DeclareLaunchArgument(x, default_value0.0, descriptionX position of the model))ld.add_action(DeclareLaunchArgument(y, default_value0.0, descriptionY position of the model))ld.add_action(DeclareLaunchArgument(z, default_value0.0, descriptionZ position of the model))# 配置 parameter_bridge用于桥接 Gazebo 和 ROS 服务parameter_bridge_cmd Node(packageros_gz_bridge,executableparameter_bridge,arguments[/world/empty/createros_gz_interfaces/srv/SpawnEntity],outputscreen)# 添加到 LaunchDescriptionld.add_action(parameter_bridge_cmd)return ldXML 元素Python 替代arg name... /DeclareLaunchArgumentgz_spawn_model ... /Node通过 parameters 字段传递参数 同时启动
在官方教程中我找到了这一个代码
ros2 launch ros_gz_sim ros_gz_spawn_model.launch.py world:empty file:$(ros2 pkg prefix --share ros_gz_sim_demos)/models/vehicle/model.sdf entity_name:my_vehicle x:5.0 y:5.0 z:0.5 bridge_name:ros_gz_bridge config_file:path_to_your_YAML_file 他说可以同时桥接gz-ros和生成模型 关键参数的功能
world:empty 指定要加载的 Gazebo 世界为 empty空白世界。Gazebo 会在这个世界中加载模型。 file:$(ros2 pkg prefix --share ros_gz_sim_demos)/models/vehicle/model.sdf 指定要加载的模型文件路径。在这里加载的是 vehicle 模型的 SDF 文件。 entity_name:my_vehicle 模型的名称生成后的模型会被命名为 my_vehicle。 x:5.0 y:5.0 z:0.5 指定模型的初始位置 x模型在 Gazebo 世界中的 X 坐标。y模型在 Gazebo 世界中的 Y 坐标。z模型在 Gazebo 世界中的 Z 坐标。 bridge_name:ros_gz_bridge 定义桥接节点的名称为 ros_gz_bridge。这是 ros_gz_bridge 在 ROS 2 网络中的唯一标识。 config_file:path_to_your_YAML_file 指定一个 YAML 配置文件用于定义要桥接的话题和服务。 通用的桥接 YAML 文件
以下是一个桥接 YAML 配置文件实例。
网络收集可能会有错误。
bridge_config.yaml
# 桥接 Gazebo 服务到 ROS 2 服务
services:# 模型生成服务- ros_service_name: /world/empty/creategz_service_name: /gazebo/spawn_entityros_service_type: ros_gz_interfaces/srv/SpawnEntitygz_request_type: gz.msgs.EntityFactorygz_response_type: gz.msgs.Boolean# 模型删除服务- ros_service_name: /world/empty/deletegz_service_name: /gazebo/delete_entityros_service_type: ros_gz_interfaces/srv/DeleteEntitygz_request_type: gz.msgs.Entitygz_response_type: gz.msgs.Boolean# 世界控制服务- ros_service_name: /world/empty/controlgz_service_name: /gazebo/control_worldros_service_type: ros_gz_interfaces/srv/ControlWorldgz_request_type: gz.msgs.WorldControlgz_response_type: gz.msgs.Boolean# 桥接 Gazebo 和 ROS 2 的话题
topics:# 激光雷达数据- ros_topic_name: /scangz_topic_name: /gazebo/laser_scanros_type_name: sensor_msgs/msg/LaserScangz_type_name: gz.msgs.LaserScandirection: BIDIRECTIONAL# 摄像头图像数据- ros_topic_name: /camera/imagegz_topic_name: /gazebo/camera/imageros_type_name: sensor_msgs/msg/Imagegz_type_name: gz.msgs.Imagedirection: GZ_TO_ROS# 深度图像数据- ros_topic_name: /camera/depthgz_topic_name: /gazebo/camera/depth_imageros_type_name: sensor_msgs/msg/Imagegz_type_name: gz.msgs.Imagedirection: GZ_TO_ROS# 点云数据- ros_topic_name: /pointsgz_topic_name: /gazebo/point_cloudros_type_name: sensor_msgs/msg/PointCloud2gz_type_name: gz.msgs.PointCloudPackeddirection: GZ_TO_ROS# 机器人位置数据- ros_topic_name: /robot_posegz_topic_name: /gazebo/pose/inforos_type_name: geometry_msgs/msg/Posegz_type_name: gz.msgs.Posedirection: GZ_TO_ROS# 速度命令- ros_topic_name: /cmd_velgz_topic_name: /gazebo/cmd_velros_type_name: geometry_msgs/msg/Twistgz_type_name: gz.msgs.Twistdirection: ROS_TO_GZ# 关节状态数据- ros_topic_name: /joint_statesgz_topic_name: /gazebo/joint_statesros_type_name: sensor_msgs/msg/JointStategz_type_name: gz.msgs.Modeldirection: GZ_TO_ROS# TF 数据用于坐标变换- ros_topic_name: /tfgz_topic_name: /gazebo/tfros_type_name: tf2_msgs/msg/TFMessagegz_type_name: gz.msgs.Pose_Vdirection: GZ_TO_ROS# 世界状态数据- ros_topic_name: /world_stategz_topic_name: /gazebo/world_stateros_type_name: ros_gz_interfaces/msg/WorldStategz_type_name: gz.msgs.WorldStatisticsdirection: GZ_TO_ROS