在Gazebo中添加悬浮模型后,利用键盘控制其移动方法

前段时间写了文章,通过修改sdf、urdf模型的方法,在Gazebo中添加悬浮模型方法 / Gazebo中模型如何不因重力下落:在Gazebo中添加悬浮模型方法 / Gazebo中模型如何不因重力下落:修改sdf、urdf模型_sagima_sdu的博客-CSDN博客

今天讲一下如何通过键盘来控制其移动:监听键盘输入并根据按键调整模型的位置,然后通过调用set_model_state函数来更新模型在Gazebo中的状态

程序举例:

首先,我们先通过一个程序,实现在指定的空间坐标生成一个指定的模型

(注意,如果要使用的话,需要修改程序中指定的模型名称和模型的路径)

# -*- coding: utf-8 -*-
#!/usr/bin/env python"""
Author:sagima使用Gazebo仿真环境中生成一个名为"aruco_cubo_hover"的模型
python model.py
程序运行在Python2.7环境下。
"""import os
import rospy
from gazebo_msgs.msg import ModelState
from gazebo_msgs.srv import DeleteModel, SpawnModel
from std_msgs.msg import Header
from geometry_msgs.msg import Pose, Point# 初始化ROS节点
rospy.init_node('spawn_aruco_cubo_hover', anonymous=True)# 定义生成模型的函数
def spawn_aruco_cubo_hover():model_name = "aruco_cubo_hover"model_path = "/home/sjh/project/Tiago_ws/src/pal_gazebo_worlds/models/aruco_cube_hover/aruco_cube_hover.sdf"# 在这里修改目标位置initial_pose = Pose(position=Point(x=0.8, y=0, z=1))# 从文件加载模型with open(model_path, "r") as f:model_xml = f.read()# 调用Gazebo的SpawnModel服务spawn_model = rospy.ServiceProxy('/gazebo/spawn_sdf_model', SpawnModel)resp_sdf = spawn_model(model_name, model_xml, "", initial_pose, "world")if resp_sdf.success:rospy.loginfo("模型 '{}' 生成成功。".format(model_name))else:rospy.logerr("模型 '{}' 生成失败。".format(model_name))# 调用生成模型的函数
if __name__ == '__main__':try:spawn_aruco_cubo_hover()except rospy.ROSInterruptException:pass

上面的程序没有问题的话,就可以为其加入通过键盘控制的功能了

# -*- coding: utf-8 -*-
#!/usr/bin/env python"""
Author:sagima使用Gazebo仿真环境中生成一个名为"aruco_cubo_hover"的模型,并通过键盘控制模型运动
python model_with_keyboard_control.py
程序运行在Python2.7环境下。
"""import os
import rospy
from gazebo_msgs.msg import ModelState
from gazebo_msgs.srv import SetModelState, GetModelState
from std_msgs.msg import Header
from geometry_msgs.msg import Pose, Point
import sys
import select
import tty
import termios# 初始化ROS节点
rospy.init_node('spawn_aruco_cubo_hover', anonymous=True)# 保存终端设置
old_settings = termios.tcgetattr(sys.stdin)
tty.setcbreak(sys.stdin.fileno())# 定义运动速度
move_speed = 0.1# 定义生成模型的函数
def spawn_aruco_cubo_hover(initial_pose):model_name = "aruco_cubo_hover"model_path = "/home/sjh/project/Tiago_ws/src/pal_gazebo_worlds/models/aruco_cube_hover/aruco_cube_hover.sdf"# 从文件加载模型with open(model_path, "r") as f:model_xml = f.read()# 调用Gazebo的SpawnModel服务spawn_model = rospy.ServiceProxy('/gazebo/spawn_sdf_model', SpawnModel)resp_sdf = spawn_model(model_name, model_xml, "", initial_pose, "world")if resp_sdf.success:rospy.loginfo("模型 '{}' 生成成功。".format(model_name))else:rospy.logerr("模型 '{}' 生成失败。".format(model_name))# 定义设置模型状态的函数
def set_model_state(model_name, pose):model_state = ModelState()model_state.model_name = model_namemodel_state.pose = poseset_model_state = rospy.ServiceProxy('/gazebo/set_model_state', SetModelState)set_model_state(model_state)# 中文提示
print("按下以下键盘按键来控制模型运动:")
print("W: 向前移动")
print("S: 向后移动")
print("A: 向左移动")
print("D: 向右移动")
print("Q: 上升")
print("E: 下降")
print("Ctrl+C: 退出程序")try:# 定义初始位置initial_pose = Pose(position=Point(x=0.8, y=0, z=1))# 主循环,持续监听键盘输入并控制模型运动while True:if select.select([sys.stdin], [], [], 0)[0] == [sys.stdin]:key = sys.stdin.read(1)if key == 'w':initial_pose.position.x += move_speedelif key == 's':initial_pose.position.x -= move_speedelif key == 'a':initial_pose.position.y += move_speedelif key == 'd':initial_pose.position.y -= move_speedelif key == 'q':initial_pose.position.z += move_speedelif key == 'e':initial_pose.position.z -= move_speedelif key == '\x03':  # Ctrl+Cbreak# 调用设置模型状态的函数set_model_state("aruco_cubo_hover", initial_pose)
except rospy.ROSInterruptException:pass
finally:# 恢复终端设置termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings)

注意,如果要使用的话,需要修改程序中指定的模型名称和模型的路径;同时如果需要修改按键,记得在中文提示中一并修改

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/70289.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解密 AI 客服;在不同硬件设备上运行大型语言模型的可能性

🦉 AI新闻 🚀 微软必应首席执行官称必应聊天优于OpenAI的GPT-4,但成本更高 摘要:微软必应的首席执行官米哈伊尔・帕拉欣表示,必应聊天表现优于OpenAI的GPT-4,但使用了更高成本的检索增强推理技术。必应聊…

设置bootstrap的modal垂直居中

效果: 代码: updateEmpModal 指的是我的模态框id$("#updateEmpModal").modal("show"); // show 方法调用之后立即触发该事件 $(#updateEmpModal).on(shown.bs.modal, function(){let $this $(this);let $modal_dialog $this.fi…

github拉取自己的私有仓库(Token方式、本地秘钥方式)

github拉取自己的私有仓库(Token方式、本地秘钥方式) 问题背景 日常开发和学习过程中,经常碰到需要从GitHub或者其他类似网站,拉取私有仓代码的需求。本文将总结常用的两种方式,Token方式和本地秘钥方式,方便后续查阅和优化。 …

【讨论】视频监控集中存储方案如何做?

视频监控集中存储是指将多个视频监控摄像头所捕捉到的视频信号集中存储于一个中央设备,这个中央设备可以是服务器、网络存储设备或其他专用设备。通过集中存储,可以避免因为存储设备分散而导致的管理不便和难以有效地管理和检索视频数据,同时…

爬虫逆向实战(七)--猿人学第十六题

一、数据接口分析 主页地址:猿人学第十六题 1、抓包 通过抓包可以发现数据接口是api/match/16 2、判断是否有加密参数 请求参数是否加密? 通过查看“载荷”模块可以看出m是加密参数 请求头是否加密? 无响应是否加密? 无cook…

机器学习深度学习——自注意力和位置编码(数学推导+代码实现)

👨‍🎓作者简介:一位即将上大四,正专攻机器学习的保研er 🌌上期文章:机器学习&&深度学习——注意力分数(详细数学推导代码实现) 📚订阅专栏:机器学习…

八股文之框架篇(Spring Boot、SSM)

文章目录 Spring中的单例bean是线程安全的吗什么是AOP,项目中有没有使用到AOPSpring中的事务是如何实现的Spring中事务失效的场景有哪些Bean的生命周期Spring中的循环依赖(循环引用)SpringMVC的执行流程SpringBoot自动配置原理Spring、Spring…

区分Dataloader和Dataset

① Dataset是一个抽象类,不能实例化,只能被其他子类继承 比如class Dia (Dataset): ② Dataloader用来帮助加载数据可以实例化

【轻量级神经网络】MobileNet网络详解

文章目录 1、深度卷积(Depthwise convolution)2、逐点卷积(Pointwise Convolution)3、深度可分离卷积(Depthwise Separable Convolution)4、Xception与MobileNet深度可分离卷积的区别 深度学习领域内努力促使神经网络向小型化发展。在保证模型准确率的同时体积更小,…

42.SpringBoot—原理篇

一、SpringBoot原理篇。 (1)自动配置。 (1.1)bean加载方式。 (1.1.1)xml方式。(适用自定义bean与第三方bean) (1.1.2)注解方式组件扫描。(适用于自定义bean&#xff…

C++QT教程3——手册4.11.1自带教程(笔记)——创建一个QT快速应用

文章目录 创建一个QT快速应用创建项目创建主视图添加应用逻辑为视图添加动画素材文件 参考文章 创建一个QT快速应用 本教程使用内置的QML类型,介绍了Qt Quick的基本概念。有关可以选择的用户界面选项的更多信息,请参阅用户界面。 本教程描述了如何使用…

File Upload

File Upload 文件上传功能是大部分WEB应用的常用功能,网站允许用户自行上传头像、照片、一些服务类网站需要用户上传证明材料的电子档、电商类网站允许用户上传图片展示商品情况等。然而,看似不起眼的文件上传功能如果没有做好安全防护措施,…