ros2键盘实现车辆: 简单的油门_刹车_挡位_前后左右移动控制
参考:
- ROS python 实现键盘控制 底盘移动 https://blog.csdn.net/u011326325/article/details/131609340
- 游戏手柄控制
1.背景与需求
1.之前实现过 键盘控制 底盘移动的程序, 底盘是线速度控制, 效果还不错.
2.新的底盘 只支持油门控制, 使用线速度控制问题比较多, 和底盘适配不好;
- 机械开关, 不能频繁切换挡位
- 停止移动, 需要主动踩刹车, 不然由于车辆惯性会继续向前移动
2.功能需求
键位功能如下

特性介绍
- 按一下a, 转向-15度; 按一下d, 转向+15度
- 长按space , 刹车0.0->70.0 %, 每0.1s加10.0%刹车
- 按c 转向为0
- 按意挡位切换,油门为0
- q 退出
3.代码实现
在线代码:
话题定义: https://gitee.com/zero2200/7_ros-robot-example/blob/main/ros2/src/common/msg/CarControl.msg
键盘控制: https://gitee.com/zero2200/7_ros-robot-example/blob/main/ros2/src/12_car_control/12_car_control/keyborad_sim_ctrol_car.py
定义话题
CarControl.msg
float32 acc # 油门
float32 angle # 方向盘
float32 brake # 刹车
uint8 gear # 档位
键盘控制代码
#!/usr/bin/env python3
# coding:utf-8
"""
功能:实现输入w,s,a,d命令控制车辆:油门,刹车,左转,右转,挡位切换
"""import sys
import tty
import termios
import select
from enum import IntEnum
import threading# ROS
import rclpy
from rclpy.node import Node# Local
from common.msg import CarControl# import debugpy
# debugpy.listen(6688)
# debugpy.wait_for_client()
# debugpy.breakpoint()class Gear(IntEnum):P = 1 # P档R = 2 # 倒档N = 3 # 空档D = 4 # 前进档def Ang2Rad(angle) -> float:return angle * 0.01745def Rad2Ang(rad) -> float:return rad * 57.2958Angle_15 = Ang2Rad(15)
Angle_45 = Ang2Rad(45)
Compensation_Rad = 4.0class Noblock_terminal:def __init__(self):fd = sys.stdin.fileno()self.old_settings = termios.tcgetattr(fd)tty.setraw(sys.stdin.fileno(), termios.TCSANOW)def __exit__(self):if self.old_settings:self.stop_no_block()def get_char(self):ch = sys.stdin.read(1)# sys.stdout.write(ch)return chdef select_cmd(self, timeout=0.2):read_list = [sys.stdin]cmd = "0"read_ret, write_ret, err_ret = select.select(read_list, [], [], timeout)if read_ret:for fd in read_ret:if fd == sys.stdin:cmd = sys.stdin.read(1)else:print("unknow fd")else:# print("read timeout")passreturn cmddef stop_no_block(self):fd = sys.stdin.fileno()termios.tcsetattr(fd, termios.TCSADRAIN, self.old_settings)self.old_settings = Noneclass Sim_Action(Node):def __init__(self):self.init_ControlCMD()super().__init__("sim_control_car")self.pub_cmd = self.create_publisher(CarControl, "/vehicle_cmd", 1)def thread_init(self, method="planne_move"):# thread_inpuc_cmd = threading.Thread(target=self.choose_menu, daemon=True)thread_inpuc_cmd = threading.Thread(target=self.plane_move, daemon=True)thread_inpuc_cmd.start()def init_ControlCMD(self):data = CarControl()data.acc = 0.0data.angle = 0.0data.brake = 0.0data.gear = Gear.Pself.control_cmd = datadef choose_menu(self):help_str = """
1 车辆移动
2 车灯,清扫,垃圾倾倒,充电,加水控制,鸣笛
"""cmd = input(help_str)if cmd == "1":self.plane_move()elif cmd == "2":self.other_ctrol()def other_ctrol(self):"项目,产品 独有功能, 不公开"passdef publisher_cmdvel(self, speed, angle, gear, brake):msg = self.control_cmdmsg.acc = speedmsg.angle = anglemsg.brake = brakemsg.gear = gearself.pub_cmd.publish(msg)def plane_move(self):help_str = """
\033[80D w 加速
\033[80D a 右转+ d 左转+
\033[80D s 减速\033[80D i D档
\033[80D j N档 l P档:油门0,方向0
\033[80D k R档\033[80D 空格 刹车+油门0, c 方向回正
\033[80D q, Esc: 退出
\033[80D h 帮助
"""noblock_term = Noblock_terminal()msg = self.control_cmdspeed = msg.accangle = msg.anglebrake = msg.brakegear = msg.gearwhile True:cmd = noblock_term.select_cmd(timeout=0.1)# 前后左右移动if cmd == "w":speed += 2.0if speed > 50.0:speed = 50.0elif cmd == "s":speed -= 2.0if speed < 0.0:speed = 0.0elif cmd == "a":angle -= Angle_15elif cmd == "d":angle += Angle_15# 挡位elif cmd == "i":gear = Gear.Dspeed = 0.0elif cmd == "k":gear = Gear.Rspeed = 0.0elif cmd == "j":gear = Gear.Nelif cmd == "l":gear = Gear.Pspeed = 0.0# 刹车elif cmd == " ":speed = 0.0brake += 10.0if brake > 70.0:brake = 70.0elif cmd == "c":angle = 0.0elif cmd == "h":print(help_str)elif cmd == "q": # q 按键值breakelif ord(cmd) == 0x1B: # Esc 按键值break# 超时elif cmd == "0":if brake > 0.0:brake -= 10.0else:print("未知指令")print(help_str)print(f"\033[80D speed:{speed:.2f} angle:{angle:.2f} gear:{gear} brake:{brake:.2f}")self.publisher_cmdvel(speed, angle, gear, brake)print("exit 键盘控制")noblock_term.stop_no_block()sys.exit(0)def main(args=None):rclpy.init(args=args)sim = Sim_Action()sim.thread_init()rclpy.spin(sim)sim.destory_node()rclpy.shutdown()sim.move_control()if __name__ == "__main__":main()
实测
运行脚本python程序, 按i, 按w
查看话题输出 ros2 topic echo /vehicle_cmd
acc: 6.0
angle: 0.0
brake: 0.0
gear: 4
/—
acc: 8.0
angle: 0.0
brake: 0.0
gear: 4
对比 参考1 优势
- 老版本 线速度控制, 速度为0时自动驻车; 新版本 油门控车, 松开w继续油门前行, 按 空格space 刹车; --> fix 机械刹车, 一直踩刹车报故障
- 老版本 w前进, s后退 ; 新版本,需要i/k切换挡位–> fix 机械挡位频繁切换, 导致异常
相关文章:
ros2键盘实现车辆: 简单的油门_刹车_挡位_前后左右移动控制
参考: ROS python 实现键盘控制 底盘移动 https://blog.csdn.net/u011326325/article/details/131609340游戏手柄控制 1.背景与需求 1.之前实现过 键盘控制 底盘移动的程序, 底盘是线速度控制, 效果还不错. 2.新的底盘 只支持油门控制, 使用线速度控制问题比较多, 和底盘适配…...
ubuntu安装chrome无法打开问题
如果在ubuntu安装chrome后,点击chrome打开没反应,可以先试着在terminal上用命令打开 google-chrome 如果运行命令显示 Chrome has locked the profile so that it doesnt get corrupted. If you are sure no other processes are using this profile…...
CTF-RE 从0到N:Chacha20逆向实战 2024 强网杯青少年专项赛 EnterGame WP (END)
只想解题的看最后就好了,前面是算法分析 Chacha20 c语言是如何利用逻辑运算符拆分变量和合并的 通过百度网盘分享的文件:EnterGame_9acdc7c33f85832082adc6a4e... 链接:https://pan.baidu.com/s/182SRj2Xemo63PCoaLNUsRQ?pwd1111 提取码:1…...
vue3 ajax获取json数组排序举例
使用axios获取接口数据 可以在代码中安装axios包,并写入到package.json文件: npm install axios -S接口调用代码举例如下: const fetchScore async () > {try {const res await axios.get(http://127.0.0.1:8000/score/${userInput.v…...
web安全之信息收集
在信息收集中,最主要是就是收集服务器的配置信息和网站的敏感信息,其中包括域名及子域名信息,目标网站系统,CMS指纹,目标网站真实IP,开放端口等。换句话说,只要是与目标网站相关的信息,我们都应该去尽量搜集。 1.1收集域名信息 知道目标的域名之后,获取域名的注册信…...
报错:java: 无法访问org.springframework.boot.SpringApplication
idea报错内容: java: 无法访问org.springframework.boot.SpringApplication 报错原因: <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.4…...
线上+线下≠新零售,6大互通诠释新零售的核心要点-亿发
新零售,这个词汇在近年来频繁出现在我们的视野中,它不仅仅是线上与线下的简单相加,而是一场深刻的商业变革。本文将通过6大互通的核心要点,为您揭示新零售的真正内涵。 1. 商品的互联互通 新零售模式下,商品的互联互…...
GitHub Copilot革命性更新:整合顶尖AI模型,如何重塑开发体验?
在技术快速发展的今天,代码辅助工具已成为提升开发效率的利器。今天,我们带来了一个激动人心的消息——GitHub Copilot宣布引入多模型选择功能,这不仅是技术上的一次飞跃,更是对开发者工作流程的一次革新。 多模型选择:…...
AWS账户是否支持区域划分?
在云计算的世界中,亚马逊网络服务(AWS)凭借其全球化的基础设施和丰富的服务选项受到许多企业和开发者的青睐。一个常见的问题是:AWS账户是否支持区域划分?为了回答这个问题,我们九河云一起深入了解AWS的区域…...
Easy Excel 通过【自定义批注拦截器】实现导出的【批注】功能
目录 Easy Excel 通过 【自定义批注拦截器】实现导出的【批注】功能需求原型:相关数据:要导出的对象字段postman 格式导出对象VO 自定义批注拦截器业务代码: 拦截器代码解释:详细解释:格式优化: Easy Excel…...
整数对最小和(Java Python JS C++ C )
题目描述 给定两个整数数组array1、array2,数组元素按升序排列。 假设从array1、array2中分别取出一个元素可构成一对元素,现在需要取出k对元素, 并对取出的所有元素求和,计算和的最小值。 注意: 两对元素如果对应于array1、array2中的两个下标均相同,则视为同一对元…...
MySQL 启动失败问题分析与解决方案:`mysqld.service failed to run ‘start-pre‘ task`
目录 前言1. 问题背景2. 错误分析2.1 错误信息详解2.2 可能原因 3. 问题排查与解决方案3.1 检查 MySQL 错误日志3.2 验证 MySQL 配置文件3.3 检查文件和目录权限3.4 手动启动 MySQL 服务3.5 修复 systemd 配置文件3.6 验证依赖环境 4. 进一步优化与自动化处理结语 前言 在日常…...
谷歌浏览器Chrome打开百度很慢,其他网页正常的解决办法,试了很多,找到了适合的
最近不知怎么的,Chrome突然间打开百度很慢,甚至打不开。不光我一个人遇到这问题,我同事也遇到这个问题。开发中难免遇到问题,需要百度,现在是百度不了。 作为一名开发人员,习惯了使用Chrome进行开发&#…...
深度学习Pytorch中的模型保存与加载方法
深度学习:Pytorch中的模型保存与加载方法 在 PyTorch 中,模型的保存和加载对于模型的持久化和后续应用至关重要。这里详细介绍了两种主要方法:保存整个模型(包括架构和参数)和仅保存模型的状态字典。以下内容进一步完善了加载模型…...
小红书矩阵运营:怎么通过多个账号来提升品牌曝光?
在如今的社交媒体环境中,小红书作为一个以分享生活方式、购物心得为主的平台,已经成为品牌营销的热土。尤其是通过“小红书矩阵”,品牌能够精准触达不同的用户群体,提升曝光度和转化率。那么,如何通过多个账号进行矩阵…...
Llama-2-7b:vocab size:32000;embeddings:4096;hidden_layers是什么意思
目录 Llama-2-7b:vocab size:32000;embeddings:4096 vocab size:模型能解析词汇数量==n_vocab num_hidden_layers: 32 nanogpt隐藏层4 "initializer_range": 0.02 Token Embed是什么 举例说明 不同Chat版本的Token Embed(Token Embeddings) 区别 Llama…...
【moveit!】ROS学习笔记
参考:Movelt使用笔记-Movelt Setup Assistant-CSDN博客 MoveIt! 学习笔记12 - MoveIt! Setup Assistant 配置方法_ros moveit 添加home点-CSDN博客 一、使用Setup Assistant配置机械臂 (1)使用如下命令启动MoveIt Setup Assistant rosrun…...
【Leetcode 每日一题 - 补卡】3259. 超级饮料的最大强化能量
问题背景 来自未来的体育科学家给你两个整数数组 e n e r g y D r i n k A energyDrinkA energyDrinkA 和 e n e r g y D r i n k B energyDrinkB energyDrinkB,数组长度都等于 n n n。这两个数组分别代表 A A A、 B B B 两种不同能量饮料每小时所能提供的强化…...
【人工智能】使用Python实现序列到序列(Seq2Seq)模型进行机器翻译
解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 序列到序列(Sequence-to-Sequence, Seq2Seq)模型是解决序列输入到序列输出任务的核心架构,广泛应用于机器翻译、文本摘要和问答系统等自然语言处理任务中。本篇文章深入介绍 Seq2Seq 模型的原理及其核心组件(…...
量化交易系统开发-实时行情自动化交易-4.4.1.做市策略实现
19年创业做过一年的量化交易但没有成功,作为交易系统的开发人员积累了一些经验,最近想重新研究交易系统,一边整理一边写出来一些思考供大家参考,也希望跟做量化的朋友有更多的交流和合作。 接下来继续说说做市策略实现。 做市策…...
iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...
PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
Web后端基础(基础知识)
BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。 优点:维护方便缺点:体验一般 CS架构:Client/Server,客户端/服务器架构模式。需要单独…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...
