亚博microros小车-原生ubuntu支持系列 27、手掌控制小车运动
背景知识
本节跟上一个测试类似:亚博microros小车-原生ubuntu支持系列:26手势控制小车基础运动-CSDN博客
都是基于MediaPipe hands做手掌、手指识别的。
为了方便理解,在贴一下手指关键点分布。手掌位置就是靠第9点来识别的。
2、程序说明
本节案例在机器人主控上可能会运行速度很卡顿,可以识别到手掌之后先把小车架起来测试,这样效果会好一些。
小车会根据手掌在画面中的位置,控制底盘的运动。
手掌在画面上方->小车前进
手掌在画面下方->小车后退
手掌在画面左方->小车左移
手掌在画面下方->小车右移
3 启动命令
启动小车代理、图像代理
sudo docker run -it --rm -v /dev:/dev -v /dev/shm:/dev/shm --privileged --net=host microros/micro-ros-agent:humble udp4 --port 8090 -v4
sudo docker run -it --rm -v /dev:/dev -v /dev/shm:/dev/shm --privileged --net=host microros/micro-ros-agent:humble udp4 --port 9999 -v4
终端输入,
ros2 run yahboom_esp32ai_car RobotCtrl
不太好区别,加上指点图
我大概用画笔简单示意下。判断标准可以自行调整x,y的值,运行日志
ohu@bohu-TM1701:~/yahboomcar/yahboomcar_ws$ ros2 run yahboom_esp32ai_car RobotCtrl
WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
I0000 00:00:1739176022.123238 464141 gl_context_egl.cc:85] Successfully initialized EGL. Major : 1 Minor: 5
I0000 00:00:1739176022.187429 464194 gl_context.cc:369] GL version: 3.2 (OpenGL ES 3.2 Mesa 23.2.1-1ubuntu3.1~22.04.3), renderer: Mesa Intel(R) UHD Graphics 620 (KBL GT2)
start it
INFO: Created TensorFlow Lite XNNPACK delegate for CPU.
W0000 00:00:1739176026.985982 464181 inference_feedback_manager.cc:114] Feedback manager requires a model with a single signature inference. Disabling support for feedback tensors.
W0000 00:00:1739176027.850109 464183 inference_feedback_manager.cc:114] Feedback manager requires a model with a single signature inference. Disabling support for feedback tensors.
W0000 00:00:1739176027.890610 464180 landmark_projection_calculator.cc:186] Using NORM_RECT without IMAGE_DIMENSIONS is only supported for the square ROI. Provide IMAGE_DIMENSIONS or use PROJECTION_MATRIX.
x 295
value: x:0.2,y:0.2
x 277
value: x:0.2,y:0.2
x 280
value: x:0.2,y:0.2
x 612
value: x:0.0,y:-0.2
x 622
value: x:0.0,y:-0.2
x 622
value: x:0.0,y:-0.2
x 614
value: x:0.0,y:-0.2
x 620
value: x:0.0,y:-0.2
x 607
value: x:0.0,y:-0.2
x 588
value: x:0.0,y:-0.2
x 586
value: x:0.0,y:-0.2
x 569
value: x:0.0,y:-0.2
x 562
value: x:0.0,y:-0.2
x 564
value: x:0.0,y:-0.2
x 550
value: x:0.0,y:-0.2
x 537
value: x:0.0,y:-0.2
x 463
value: x:0.0,y:-0.2
x 384
value: x:0.0,y:-0.2
x 313
value: x:0.0,y:0.0
x 262
value: x:0.0,y:0.2
x 231
value: x:0.0,y:0.2
代码
#!/usr/bin/env python3
# encoding: utf-8
import threading
import cv2 as cv
import numpy as np
from yahboom_esp32ai_car.media_library import *
import time
import rclpy
from rclpy.node import Node
from std_msgs.msg import Int32, Bool,UInt16
from cv_bridge import CvBridge
from sensor_msgs.msg import Image, CompressedImagefrom rclpy.time import Time
import datetimeclass HandCtrlArm(Node):def __init__(self,name):super().__init__(name)self.pub_Servo1 = self.create_publisher(Int32,"servo_s1" , 10)self.pub_Servo2 = self.create_publisher(Int32,"servo_s2" , 10)self.PWMServo_X = 0self.PWMServo_Y = 45self.s1_init_angle = Int32()self.s1_init_angle.data = self.PWMServo_Xself.s2_init_angle = Int32()self.s2_init_angle.data = self.PWMServo_Yself.media_ros = Media_ROS()#确保角度正常处于中间for i in range(10):self.pub_Servo1.publish(self.s1_init_angle)self.pub_Servo2.publish(self.s2_init_angle)time.sleep(0.1)self.hand_detector = HandDetector()self.arm_status = Trueself.locking = Trueself.init = Trueself.pTime = 0self.add_lock = self.remove_lock = 0self.event = threading.Event()self.event.set()def process(self, frame):frame, lmList, bbox = self.hand_detector.findHands(frame)if len(lmList) != 0:threading.Thread(target=self.arm_ctrl_threading, args=(lmList,bbox)).start()else:self.media_ros.pub_vel(0.0,0.0,0.0)self.media_ros.pub_imgMsg(frame)return framedef arm_ctrl_threading(self, lmList,bbox):if self.event.is_set():self.event.clear()fingers = self.hand_detector.fingersUp(lmList)self.hand_detector.draw = True#gesture = self.hand_detector.get_gesture(lmList)self.arm_status = Falsepoint_x = lmList[9][1]point_y = lmList[9][2]print("x",point_x)if point_y >= 270: x = -0.2elif point_y <= 150: x = 0.2else: x = 0.0if point_x >= 350: y = -0.2elif point_x <= 300: y = 0.2else: y = 0.0self.media_ros.pub_vel(x,0.0,y)print(f'value: x:{x},y:{y}')self.arm_status = Trueself.event.set()class MY_Picture(Node):def __init__(self, name):super().__init__(name)self.bridge = CvBridge()self.sub_img = self.create_subscription(CompressedImage, '/espRos/esp32camera', self.handleTopic, 1) #获取esp32传来的图像self.handctrlarm = HandCtrlArm('handctrl')self.last_stamp = Noneself.new_seconds = 0self.fps_seconds = 1def handleTopic(self, msg):self.last_stamp = msg.header.stamp if self.last_stamp:total_secs = Time(nanoseconds=self.last_stamp.nanosec, seconds=self.last_stamp.sec).nanosecondsdelta = datetime.timedelta(seconds=total_secs * 1e-9)seconds = delta.total_seconds()*100if self.new_seconds != 0:self.fps_seconds = seconds - self.new_secondsself.new_seconds = seconds#保留这次的值start = time.time()frame = self.bridge.compressed_imgmsg_to_cv2(msg)frame = cv.resize(frame, (640, 480))action = cv.waitKey(1) & 0xFFframe = self.handctrlarm.process(frame)if action == ord('q'):self.handctrlarm.media_ros.cancel()end = time.time()fps = 1 / ((end - start)+self.fps_seconds)text = "FPS : " + str(int(fps))cv.putText(frame, text, (10,20), cv.FONT_HERSHEY_SIMPLEX, 0.8, (0,255,255), 2)cv.imshow('frame', frame)def main():rclpy.init() esp_img = MY_Picture("My_Picture")print("start it")try:rclpy.spin(esp_img)except KeyboardInterrupt:passfinally:esp_img.destroy_node()rclpy.shutdown()
主要逻辑:其实获取到的就是咱们手掌中指的第一个关节的坐标(第9点),通过判断这个坐标在画面中的位置来发送给底盘xy方向上的速度,即可实现控制。
补充一个节点通信图
相关文章:

亚博microros小车-原生ubuntu支持系列 27、手掌控制小车运动
背景知识 本节跟上一个测试类似:亚博microros小车-原生ubuntu支持系列:26手势控制小车基础运动-CSDN博客 都是基于MediaPipe hands做手掌、手指识别的。 为了方便理解,在贴一下手指关键点分布。手掌位置就是靠第9点来识别的。 2、程序说明…...
STM32 HAL库 CANbus通讯(C语言)
#include "main.h" #include "stm32f1xx_hal.h"CAN_HandleTypeDef hcan; CAN_TxHeaderTypeDef TxHeader; CAN_RxHeaderTypeDef RxHeader; uint8_t TxData[8]; uint8_t RxData[8]; uint32_t TxMailbox;void CAN_Init(void) {// 使能CAN时钟__HAL_RCC_CAN1_C…...
ML.NET库学习005:基于机器学习的客户细分实现与解析
文章目录 ML.NET库学习005:基于机器学习的客户细分实现与解析项目主要目的和原理目的原理 项目概述实现的主要功能主要流程步骤使用的主要函数方法关键技术 主要功能和步骤功能详细解读详细步骤解析 数据集及其处理步骤数据集处理步骤关键处理步骤原理1. 数据清洗与…...

(2/100)每日小游戏平台系列
新增一个猜单词小游戏! ------------------------------------------------------------------------------------------------------------------ 猜单词游戏玩法 游戏规则: 游戏会从一个预设的单词列表中随机选择一个单词。玩家有 6 次机会来猜测单…...
【Linux Oracle】杂货铺 日常实用2024
1.跨服务器移动文件 passwd=^T^bxxxx `/usr/bin/expect <<-EOF set timeout -1 spawn scp -r ${BATCH_TIME} sxnhtc@192.168.3.x:${EXP_MCRO_DIR}/ expect "*password:" send "$passwd\r" interact expect eof EOF` curl -k -X GET https://192.16…...
浏览器的缓存方式几种
浏览器的缓存方式主要分为以下几种: 1. 强制缓存(强缓存 / Memory Cache & Disk Cache) 通过 Expires 或 Cache-Control 头部控制。在缓存有效期内,浏览器直接使用缓存,不发起请求。 关键HTTP头: Ex…...

黑马React保姆级(PPT+笔记)
目录 一、react基础 1.进程 2、优势 3、市场 4、搭建脚手架 认识目录 核心依赖(右边两个react) 去除非必要 运行原理: 总结 5、JSX 本质 高频场景 注意编辑 渲染列表 总结 条件渲染 简单情况 复杂情况 事件绑定&#x…...

2025web寒假作业二
一、整体功能概述 该代码构建了一个简单的后台管理系统界面,主要包含左侧导航栏和右侧内容区域。左侧导航栏有 logo、管理员头像、导航菜单和安全退出按钮;右侧内容区域包括页头、用户信息管理内容(含搜索框和用户数据表格)以及页…...

三、OSG学习笔记-应用基础
前一章节:二、OSG学习笔记-入门开发-CSDN博客https://blog.csdn.net/weixin_36323170/article/details/145513874 一、 OsgGA: 界面事件处理空间,处理操作各种操作器的最大名字空间; GUIEventHandler: ui 事件操作类 注意:在启…...

CTFHub-RCE系列wp
目录标题 引言什么是RCE漏洞 eval执行文件包含文件包含php://input读取源代码远程包含 命令注入无过滤过滤cat过滤空格过滤目录分隔符过滤运算符综合过滤练习 引言 题目共有如下类型 什么是RCE漏洞 RCE漏洞,全称是Remote Code Execution漏洞,翻译成中文…...
Linux ping不通百度但浏览器可以打开百度的的解决方法
问题描述:使用ping命令ping www.baidu.com,提示的地址为ipv6地址,但该地址ping不通,但使用浏览器直接打开百度网址可以打开。 问题可能的原因:(1)虚拟机上ipv6为自动模式,影响了ipv4寻址&#…...
Redis中的某一热点数据缓存过期了,此时有大量请求访问怎么办?
1、提前设置热点数据永不过期 2、分布式中用redis分布式锁(锁可以在多个 JVM 实例之间协调)、单体中用synchronized(锁只在同一个 JVM 内有效) 编写服务类 import com.redisson.api.RLock; import com.redisson.api.RedissonCli…...

低成本+高性能+超灵活!Deepseek 671B+Milvus重新定义知识库搭建
“老板说,这个项目得上Deepseek,还得再做个知识库...” 还有哪个开发者,最近没听到这样的抱怨? Deepseek爆火,推理端的智能提速,算力成本急剧下降,让不少原本不想用大模型,用不起大模型的企业&a…...

TCP服务器与客户端搭建
一、思维导图 二、给代码添加链表 【server.c】 #include <stdio.h> #include <sys/socket.h> #include <sys/types.h> #include <fcntl.h> #include <arpa/inet.h> #include <unistd.h> #include <stdlib.h> #include <string.…...
PDF 文件的安全功能概述
由于安全问题始终存在,我们希望重点介绍 PDF 文件格式提供的一些安全功能。如果您希望控制或限制用户可以执行的操作,这些功能可以启用。本文将介绍可以阻止哪些类型的操作,以及可以实施哪些不同的身份验证技术来提高 PDF 的安全性。 可以控制…...
在Linux上部署Jenkins的详细指南
引言 在当今快速迭代的软件开发环境中,持续集成和持续交付(CI/CD)变得越来越重要。Jenkins作为一个开源自动化服务器,能够帮助开发者更高效地进行代码集成、测试和部署。本文将详细介绍如何在Linux系统上安装和配置Jenkins。 准…...

碳纤维复合材料制造的六西格玛管理实践:破解高端制造良率困局的实战密码
碳纤维复合材料制造的六西格玛管理实践:破解高端制造良率困局的实战密码 在全球碳中和与高端制造升级的双重驱动下,碳纤维复合材料行业正经历前爆发式增长。航空航天、新能源汽车、风电叶片等领域对碳纤维产品的性能稳定性提出近乎苛刻的要求࿰…...
Day83:图形的绘制
Python 提供了多种绘图工具,其中最常用的是 Turtle(海龟绘图)和 Matplotlib(数据可视化)。今天,我们主要介绍 Turtle,它可以轻松绘制各种几何图形、艺术图案和动画。 1. Turtle 库简介 Turtle 是 Python 内置的绘图工具,主要用于教学、趣味绘画和简单图形的创建。 基…...

C# Dll嵌入到.exe
将dll属性作为 嵌入的资源 修改引用属性为不复制 增加dll识别来源 AppDomain.CurrentDomain.AssemblyResolve new ResolveEventHandler(CurrentDomain_AssemblyResolve);private static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, Reso…...
o3-mini、Gemini 2 Flash、Sonnet 3.5 与 DeepSeek 在 Cursor 上的对决
最新的 OpenAI 模型 o3-mini 已于 1 月 31 日(星期五)发布,并已在 Cursor 上架。不久后,Gemini 2 Flash 也会陆续登场。 上周,对 DeepSeek V3、DeepSeek R1 以及 Claude 3.5 Sonnet 做过类似测试。那次测试结果显示&am…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...

测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...

【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...

P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...