news 2026/10/30 1:12:17

基于RK3588与NPU的仿生人头:从机械结构到AI交互全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于RK3588与NPU的仿生人头:从机械结构到AI交互全解析

1. 项目缘起与整体设计思路

1.1 为什么选择RK3588做仿生人头的主控

做仿生人头这个想法其实在我脑子里转了很久。早些年用STM32或者ESP32做过一些简单的舵机控制项目,但一旦涉及到实时视觉识别、语音交互、多路电机协同,这些MCU的算力就完全不够看了。你要么外挂一个上位机,要么加一块树莓派做视觉处理,整个系统臃肿不说,延迟还特别大。后来RK3588的开发板价格逐渐下来,我搞了一块鲁班猫5回来试水,发现这颗芯片简直就是为这类项目量身定做的。

RK3588的核心配置我这里简单过一下:八核CPU(4个A76大核加4个A55小核),Mali-G610 MP4的GPU,最关键的是内置了6TOPS算力的NPU。这个NPU是重点,它意味着你可以在本地跑YOLOv8这样的目标检测模型,不需要把图像传到云端或者另一台机器上处理。对于仿生人头来说,摄像头采集到画面之后,直接在板子上做推理,识别到人脸或者物体之后立刻驱动舵机做出反应,整个链路的延迟可以压到很低。

另外RK3588的接口丰富程度也是我选它的重要原因。多路MIPI CSI摄像头接口、多路I2C和SPI、PWM输出、USB3.0、千兆网口,基本上你能想到的外设它都能接。仿生人头需要同时驱动眼球舵机、嘴巴舵机、颈部舵机,还要接摄像头、麦克风阵列、扬声器,这些接口需求RK3588一块板子全搞定,不需要额外的扩展板。

1.2 仿生人头的机械结构设计考量

机械结构这块我前前后后改了四版。第一版用的是纯3D打印的PLA材质,结果发现舵机一动作整个头壳就跟着共振,看起来像在发抖。后来换成PETG打印,壁厚从2mm加到3.5mm,内部加了加强筋,才把结构刚性提上来。

头部的自由度设计是这样的:颈部两个自由度(水平旋转和俯仰),眼球两个自由度(左右和上下),嘴巴一个自由度(开合),眉毛一个自由度(抬降)。总共六个舵机。这个自由度数量是我权衡之后的结果——再多的话机械结构复杂度急剧上升,而且控制算法也要跟着复杂化;再少的话表情表达能力就不够了。

舵机选型上,颈部和眼球用的是金属齿轮的数字舵机,型号是MG996R和SG90的混合搭配。MG996R扭矩大,负责颈部的俯仰和水平旋转;SG90体积小重量轻,塞在眼球后面刚好。嘴巴和眉毛用的是更小的微型舵机,扭力不需要太大,但响应速度要快。

注意:舵机的供电一定要和RK3588的供电分开。我一开始图省事直接从开发板的5V引脚取电,结果舵机一动作板子就重启。后来单独用了一块LM2596降压模块从12V锂电池降压到6V给舵机供电,问题才解决。舵机的瞬时电流可以到2A以上,开发板的供电根本扛不住。

1.3 系统架构的总体设计

整个系统的架构我分成了三层:感知层、决策层、执行层。

感知层包括摄像头和麦克风阵列。摄像头用的是IMX415模组,通过MIPI CSI接口连接到RK3588,支持4K分辨率。麦克风阵列用的是四麦环形阵列,通过USB声卡接入。感知层负责采集原始的音视频数据。

决策层跑在RK3588上,分为视觉处理线程和语音处理线程。视觉线程用NPU跑YOLOv8做目标检测和人脸检测,语音线程做关键词唤醒和简单的语音指令识别。两个线程的结果汇总到一个状态机里,状态机根据当前检测到的内容决定应该做出什么表情和动作。

执行层就是六个舵机加一个扬声器。舵机通过PCA9685驱动板控制,PCA9685通过I2C和RK3588通信。扬声器通过I2S接口的功放板驱动。

这个三层架构的好处是各层之间解耦,调试的时候可以单独测试每一层。比如你可以先不管视觉,手动发指令让舵机动起来,确认机械结构没问题之后再接入视觉识别。

2. 核心硬件选型与接线实操

2.1 RK3588开发板的对比与最终选择

市面上RK3588的开发板我前后用过三块:鲁班猫5、友善电子的NanoPC-T6、还有一块不知名厂商的工控板。最后项目里用的是鲁班猫5,原因有几个。

鲁班猫5的文档和社区支持是最好的。它的Wiki上从系统烧录到各种外设的适配都有详细说明,遇到问题在论坛上提问也基本有人回复。NanoPC-T6的硬件做工更好,但资料相对分散,有些外设的适配要自己摸索。那块工控板就更不用说了,连个像样的原理图都没有。

接口布局上,鲁班猫5的MIPI CSI接口位置比较合理,接上摄像头排线之后不会和别的接口打架。它的40pin GPIO排针和树莓派兼容,这意味着很多树莓派的扩展板可以直接拿来用,省了不少事。

内存版本我选的是8GB LPDDR4x的版本。跑YOLOv8加上语音处理,4GB其实也够用,但考虑到后面可能还要加别的功能,8GB留点余量。存储用的是64GB的eMMC,系统装在eMMC上,模型文件和数据放在外挂的TF卡里。

2.2 摄像头模组的适配与调试

摄像头这块我踩了不少坑。一开始买的是市面上常见的OV5647模组,结果发现RK3588的MIPI CSI驱动对OV5647的支持不太好,画面出来是绿的。后来换成IMX415才正常。

IMX415的适配需要在设备树里做配置。鲁班猫5的官方系统已经自带了IMX415的驱动,但默认是没有启用的。你需要修改/boot/uEnv.txt文件,把对应的overlay打开。具体操作是找到overlays=这一行,加上rk3588-imx415这个参数,然后重启。

重启之后用v4l2-ctl --list-devices命令检查摄像头有没有被识别到。正常的话应该能看到rkisp相关的设备节点。然后用v4l2-ctl --device /dev/video0 --stream-mmap --stream-count=1 --stream-to=test.raw抓一帧原始数据,再用ffmpeg转成图片看看画面是否正常。

实操心得:MIPI摄像头的排线非常脆弱,插拔的时候一定要小心。我就因为反复插拔把排线的金手指弄断了一根,导致画面时不时出现横纹。后来换了根新排线,用热熔胶把接口处固定住,再也没出过问题。

2.3 舵机驱动板PCA9685的接线与配置

PCA9685是一块16通道的PWM驱动板,通过I2C和主控通信。RK3588的I2C接口有好几路,我用的是I2C-7,对应的设备节点是/dev/i2c-7。

接线很简单:VCC接3.3V,GND接GND,SDA和SCL分别接RK3588的对应引脚。舵机的电源单独走一路,PCA9685的V+引脚接6V电源正极,GND接电源负极。注意PCA9685的逻辑电和舵机电要共地,否则PWM信号会不稳定。

软件配置上,首先确认I2C设备被识别到:i2cdetect -y 7,如果看到地址0x40就说明PCA9685已经在线了。然后安装Python的adafruit-circuitpython-pca9685库,就可以用Python脚本控制舵机了。

舵机的PWM频率设置成50Hz,对应周期20ms。脉宽范围一般是500us到2500us,对应舵机角度0到180度。但不同型号的舵机这个范围会有差异,需要实际测试。我的做法是先用一个简单的脚本让舵机从500us慢慢增加到2500us,观察舵机的实际转动范围,记录下对应的极限脉宽值,避免舵机堵转烧毁。

2.4 麦克风阵列与扬声器的接入

麦克风阵列用的是ReSpeaker的四麦环形阵列,通过USB接入。这个阵列的好处是自带硬件回声消除和波束成形,拾音效果比单个麦克风好很多。接入之后用arecord -l确认声卡被识别到,然后用arecord -D plughw:1,0 -f cd test.wav录一段音频测试。

扬声器用的是I2S功放板,芯片是MAX98357A。接线是BCLK、LRC、DIN三根信号线加上VCC和GND。在设备树里启用I2S输出之后,用aplay -D plughw:0,0 test.wav测试放音。

这里有个细节要注意:麦克风和扬声器同时工作的时候会有回声。虽然ReSpeaker自带回声消除,但效果有限。我的做法是在软件层面加了一个简单的静音逻辑——扬声器播放的时候暂停麦克风采集,播放完了再恢复。这样虽然不能实现真正的全双工对话,但对于仿生人头这种交互场景来说够用了。

3. 软件环境搭建与AI模型部署

3.1 系统烧录与基础环境配置

鲁班猫5的官方系统镜像可以从官网下载,有Ubuntu 22.04和Debian 11两个版本。我选的是Ubuntu 22.04,因为它的软件源更丰富,安装各种依赖库更方便。

烧录工具用的是RKDevTool,这是瑞芯微官方的烧录工具。操作步骤是:按住板子上的Maskrom按钮,用Type-C线连接到电脑,然后打开RKDevTool,选择对应的镜像文件,点击“执行”开始烧录。整个过程大概需要五到十分钟。

烧录完成之后第一次启动,系统会要求设置用户名和密码。设置完成之后先更新软件源:sudo apt update && sudo apt upgrade。然后安装一些基础工具:sudo apt install python3-pip python3-opencv v4l-utils i2c-tools。

注意:RK3588的NPU驱动和RKNN Toolkit的版本要匹配。鲁班猫5的官方系统里已经预装了RKNPU2的驱动,版本是1.5.0。如果你自己编译内核或者换了系统,一定要确认驱动版本和RKNN Toolkit的版本对应,否则模型推理会报错。

3.2 RKNN Toolkit2的安装与模型转换

RKNN Toolkit2是瑞芯微提供的模型转换和推理工具。它的作用是把PC上训练好的模型(比如ONNX格式)转换成RK3588 NPU能识别的RKNN格式。

安装RKNN Toolkit2建议在PC上的Ubuntu环境里进行,因为转换过程需要x86架构。安装命令是pip install rknn-toolkit2。安装完成之后,写一个转换脚本:

from rknn.api import RKNN rknn = RKNN() rknn.config(mean_values=[[0, 0, 0]], std_values=[[255, 255, 255]], target_platform='rk3588') rknn.load_onnx(model='yolov8n.onnx') rknn.build(do_quantization=True, dataset='./dataset.txt') rknn.export_rknn('./yolov8n.rknn')

这里有几个关键参数需要解释。mean_values和std_values是归一化参数,要和训练时的预处理保持一致。do_quantization=True表示做量化,把FP32的模型转成INT8,这样推理速度会快很多,但精度会有一定损失。dataset.txt是量化校准用的数据集列表,里面放几十张代表性图片的路径就行。

量化之后的模型精度损失一般在1%到3%之间,对于目标检测来说完全可以接受。如果你对精度要求特别高,可以不做量化,但推理速度会慢一倍左右。

3.3 YOLOv8模型在NPU上的部署与推理

模型转换好之后,把RKNN文件拷到RK3588上,就可以用RKNN Toolkit2的Python API做推理了。核心代码如下:

from rknnlite.api import RKNNLite import cv2 import numpy as np rknn = RKNNLite() rknn.load_rknn('yolov8n.rknn') rknn.init_runtime(core_mask=RKNNLite.NPU_CORE_0) cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() if not ret: break img = cv2.resize(frame, (640, 640)) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) outputs = rknn.inference(inputs=[img]) boxes = post_process(outputs) for box in boxes: cv2.rectangle(frame, (box[0], box[1]), (box[2], box[3]), (0, 255, 0), 2) cv2.imshow('result', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break

core_mask参数可以指定用哪个NPU核心。RK3588有三个NPU核心,可以单独用也可以组合用。单独用一个核心的时候功耗低,三个核心一起用性能最强但发热也大。仿生人头这个场景我用的是单核,因为YOLOv8n本身就不大,单核跑个30帧足够了。

实测下来,YOLOv8n在RK3588单核NPU上的推理速度大概是25到30毫秒一帧,也就是30到40FPS。加上前后处理的时间,整个链路大概能跑到20FPS左右。对于仿生人头的交互来说,这个帧率完全够用。

3.4 语音交互模块的实现

语音这块我用的方案是:Snowboy做关键词唤醒,Vosk做离线语音识别。Snowboy虽然已经停止维护了,但它的唤醒效果确实好,而且资源占用低。Vosk是一个轻量级的离线语音识别引擎,支持中文,模型大小大概50MB。

唤醒词我设置的是“你好”,检测到唤醒词之后开始录音,录到静音超过1秒就停止,然后把音频送给Vosk做识别。识别结果是一个字符串,根据字符串的内容触发不同的动作。比如识别到“点头”就让颈部舵机做点头动作,识别到“摇头”就做摇头动作。

这个方案的优点是全离线,不需要联网,响应速度也快。缺点是识别准确率有限,特别是环境噪音大的时候。我的做法是在Vosk的识别结果上加了一层模糊匹配,比如“点头”和“点一下头”都能匹配到同一个动作。

4. 机械结构与舵机控制的实操细节

4.1 3D打印件的后处理与装配

3D打印出来的零件不能直接就用,需要做后处理。首先是去除支撑材料,用斜口钳把大块的支撑剪掉,然后用砂纸打磨残留的部分。打磨的时候从粗砂纸(400目)开始,逐步换到细砂纸(1000目),最后表面会很光滑。

然后是螺纹孔的处理。3D打印的螺纹孔精度不够,直接拧螺丝会滑丝。我的做法是用丝锥重新攻一遍螺纹,M3的孔用M3的丝锥,M2的孔用M2的丝锥。攻丝的时候加点润滑油,慢慢转,不要用力过猛。

舵机的安装要用舵机支架。我用的是金属舵机支架,比塑料的结实很多。舵机和支架之间垫一层橡胶垫片,可以减少振动传递。舵机臂和机械结构之间的连接用球头拉杆,这样即使舵机轴和机械结构的运动平面不完全垂直,也能顺畅传动。

实操心得:装配的时候不要一次性把所有螺丝都拧紧。先全部拧到半紧状态,调整好各个部件的位置之后再逐个拧紧。特别是眼球这种需要精确对中的部件,如果先拧紧了一边,另一边就很难对齐了。

4.2 舵机角度标定与动作序列设计

舵机装好之后第一件事是标定角度。因为每个舵机的安装位置和机械限位都不一样,你不能直接假设1500us脉宽就对应机械中位。标定的方法是:先给舵机1500us的脉宽,观察机械结构的位置,如果不在中位就调整舵机臂的安装角度。然后再测试500us和2500us,确认机械结构不会碰到限位。

标定完成之后,把每个舵机的极限角度记录下来,在软件里做限幅。比如颈部水平旋转的机械限位是负60度到正60度,那软件里就限制在负55度到正55度,留5度的余量,防止舵机堵转。

动作序列的设计我用了一个简单的方法:把每个动作定义成一个关键帧列表,每个关键帧包含六个舵机的目标角度和执行时间。比如“点头”这个动作:

nod_action = [ {'neck_pitch': 0, 'duration': 0.3}, {'neck_pitch': 20, 'duration': 0.3}, {'neck_pitch': 0, 'duration': 0.3}, {'neck_pitch': 20, 'duration': 0.3}, {'neck_pitch': 0, 'duration': 0.3}, ]

执行的时候用线性插值让舵机平滑过渡到目标角度,而不是瞬间跳过去。这样动作看起来更自然,也不会因为突然的加速度导致机械结构抖动。

4.3 多舵机协同控制的实现

六个舵机同时动的时候,如果每个舵机都单独发指令,会出现不同步的问题。比如眼球转过去了,脖子还没转,看起来就很奇怪。解决方法是做一个统一的时间轴调度器。

调度器的逻辑是这样的:所有舵机的目标角度和当前角度都放在一个共享的数据结构里,一个独立的线程以50Hz的频率更新所有舵机的PWM输出。每个舵机根据自己的当前角度和目标角度,以及设定的运动速度,计算出这一帧应该输出的角度。这样所有舵机都是在同一个时间基准下运动,同步性很好。

import time import threading from adafruit_pca9685 import PCA9685 class ServoController: def __init__(self): self.pca = PCA9685() self.pca.frequency = 50 self.servos = {} self.lock = threading.Lock() def set_target(self, name, angle, speed=60): with self.lock: self.servos[name]['target'] = angle self.servos[name]['speed'] = speed def update_loop(self): while True: with self.lock: for name, servo in self.servos.items(): current = servo['current'] target = servo['target'] speed = servo['speed'] step = speed * 0.02 if abs(target - current) < step: servo['current'] = target else: servo['current'] += step if target > current else -step self.set_pwm(servo['channel'], servo['current']) time.sleep(0.02)

这个调度器跑起来之后,你只需要调用set_target设置目标角度,剩下的交给调度器处理。动作序列的执行就是按时间顺序调用set_target。

5. 视觉识别与交互逻辑的整合

5.1 人脸检测与追踪的实现

人脸检测我用的是YOLOv8的人脸检测模型,和通用目标检测模型是同一个架构,只是训练数据换成了人脸数据集。检测到人脸之后,根据人脸在画面中的位置计算眼球和颈部应该转动的角度。

计算逻辑是这样的:假设画面宽度是640像素,人脸中心在x=400的位置,那么人脸偏离画面中心的比例是(400-320)/320=0.25。把这个比例映射到颈部水平旋转的角度范围(负55度到正55度),得到的目标角度就是0.25乘以55,约等于14度。眼球的角度在此基础上再乘以一个系数,让眼球先转,脖子后转,看起来更自然。

追踪的时候加了一个死区,人脸偏离中心小于5%的时候不动作,避免人脸轻微移动就导致头部频繁转动。还加了一个低通滤波,对目标角度做平滑处理,防止头部抖动。

5.2 表情动作与视觉事件的联动

视觉识别到不同的事件,触发不同的表情动作。我定义了这几个联动规则:

视觉事件触发动作动作描述
检测到人脸注视眼球和颈部转向人脸方向
人脸靠近微笑嘴巴舵机做出微笑弧度
人脸远离疑惑眉毛抬起,头部轻微倾斜
检测到特定物体点头颈部做点头动作
无人脸超过10秒待机头部缓慢左右扫视

这些规则的参数都可以在配置文件里调整。比如“人脸靠近”的判定阈值,我设置的是人脸框面积占画面面积的比例超过15%就触发。这个阈值需要根据实际使用场景调整,太敏感会导致误触发,太迟钝又没反应。

5.3 语音指令与动作的映射

语音指令的映射表是这样的:

command_map = { '点头': 'nod', '摇头': 'shake', '眨眼': 'blink', '微笑': 'smile', '左转': 'turn_left', '右转': 'turn_right', '抬头': 'look_up', '低头': 'look_down', }

识别到指令之后,从映射表里找到对应的动作名称,然后调用动作执行函数。动作执行函数从动作库里加载对应的关键帧序列,交给舵机调度器执行。

这里有个细节:动作执行的时候要加一个互斥锁,防止两个动作同时执行导致舵机指令冲突。比如正在做点头动作的时候又来了一个摇头指令,要么排队等待,要么直接忽略。我选择的是排队等待,这样连续指令不会丢失。

6. 常见问题与排查技巧实录

6.1 系统层面的典型问题

问题一:系统启动后摄像头不识别

现象是/dev/video0不存在,或者存在但打不开。排查步骤:先用dmesg | grep imx415看内核日志里有没有摄像头相关的报错。如果有“probe failed”之类的信息,多半是设备树配置不对。检查/boot/uEnv.txt里的overlay参数是否正确,排线是否插紧。

问题二:NPU推理报错“init runtime failed”

这个一般是RKNN模型和驱动版本不匹配导致的。先用cat /sys/kernel/debug/rknpu/version查看NPU驱动版本,然后确认RKNN Toolkit2的版本是否对应。如果不对应,要么升级驱动,要么用对应版本的Toolkit重新转换模型。

问题三:舵机抖动严重

舵机抖动的原因可能有几个:电源功率不够、PWM信号受干扰、机械结构共振。先检查电源,用万用表测舵机供电电压在舵机动作时是否稳定。如果电压跌落超过0.5V,说明电源功率不够,需要换更大功率的电源。如果电源没问题,检查PWM信号线是否和电机线捆在一起,分开走线试试。

6.2 视觉识别相关的排查

问题:检测框闪烁不稳定

这是目标检测的常见问题,帧与帧之间的检测结果有跳动。解决方法是在后处理里加跟踪算法,比如ByteTrack或者简单的IOU匹配。我的做法是用一个简单的滑动窗口,对最近5帧的检测框做平均,这样输出就稳定多了。

问题:画面颜色偏绿或偏紫

这是摄像头白平衡没校准好。IMX415支持自动白平衡,但有时候自动模式会跑偏。可以在v4l2里手动设置白平衡参数:v4l2-ctl -d /dev/video0 --set-ctrl=white_balance_automatic=0 --set-ctrl=red_balance=1200 --set-ctrl=blue_balance=1200。具体数值需要根据实际画面调整。

6.3 机械结构相关的排查

问题:舵机动作时有异响

异响一般是舵机堵转或者齿轮打滑。先检查机械结构有没有卡死的地方,用手轻轻转动舵机臂,感觉有没有阻力。如果有阻力,找到卡住的位置,调整机械结构。如果机械结构顺畅但还有异响,可能是舵机内部的齿轮磨损了,需要更换舵机。

问题:头部动作时整个结构晃动

这是结构刚性不足的表现。检查各个连接点的螺丝是否拧紧,特别是舵机支架和头壳的连接处。如果螺丝已经拧紧但还是晃,考虑在关键部位增加加强筋或者换用更厚的材料。

6.4 常见问题速查表

问题现象可能原因排查方法解决方案
摄像头不识别设备树未配置dmesg查看内核日志修改uEnv.txt启用overlay
NPU推理失败版本不匹配查看驱动和Toolkit版本统一版本或重新转换模型
舵机抖动电源功率不足万用表测动作时电压更换大功率电源
检测框闪烁无跟踪算法观察连续帧检测结果加滑动窗口平均
画面偏色白平衡跑偏对比实际颜色手动设置白平衡参数
舵机异响机械卡死或齿轮磨损手动转动舵机臂调整结构或更换舵机
头部晃动结构刚性不足检查螺丝和连接点加加强筋或换材料
语音识别率低环境噪音大在不同噪音环境下测试加降噪或改用唤醒词方案

7. 项目扩展方向与个人经验分享

7.1 可以继续深挖的几个方向

这个项目做完之后,我觉得还有几个方向可以继续扩展。第一个是加入情感识别,通过摄像头分析人脸表情,判断对方的情绪状态,然后做出相应的表情回应。这个可以在NPU上再跑一个轻量级的表情分类模型,和YOLOv8并行推理。

第二个方向是加入更多的自由度。现在只有六个舵机,表情表达能力有限。如果加到十个或者十二个自由度,可以做出更丰富的表情,比如皱眉、嘴角上扬、耳朵转动等。但自由度增加之后,机械结构的设计难度和控制算法的复杂度都会大幅上升。

第三个方向是加入无线通信模块,让仿生人头可以通过WiFi或者蓝牙接收外部指令。这样你可以用手机APP或者电脑远程控制它,也可以接入智能家居系统,让它根据家里的状态做出反应。

7.2 我在这个项目里踩过的坑

最大的坑是电源设计。我一开始觉得舵机和开发板用同一个电源就行了,结果舵机一动作板子就重启。后来单独给舵机供电,又发现舵机的瞬时电流会把电源电压拉低,导致舵机自己也不稳定。最后用了大容量的锂电池加上大电容滤波,才彻底解决。

第二个坑是散热。RK3588跑NPU推理的时候发热量不小,特别是夏天室温高的时候,板子温度能到70度以上。后来加了一个小风扇对着散热片吹,温度才降到50度左右。如果你要把仿生人头做成封闭的结构,散热一定要提前考虑。

第三个坑是舵机的精度。SG90这种廉价舵机的角度精度很差,重复定位精度可能有正负5度。对于眼球这种需要精细控制的部位,建议用金属齿轮的数字舵机,精度会好很多。虽然贵一点,但效果完全不一样。

7.3 给想复现这个项目的朋友的建议

如果你也想做一个类似的仿生人头,我的建议是分阶段来。第一阶段先把机械结构做出来,用手动的方式测试舵机动作,确认机械结构没问题。第二阶段再接入RK3588,把摄像头和NPU推理跑通。第三阶段最后做视觉和动作的联动。

不要一上来就想把所有功能都做完,那样很容易卡在某个环节上失去信心。每个阶段都有明确的验收标准,比如第一阶段的标准是六个舵机都能顺畅动作,没有卡顿和异响。第二阶段的标准是摄像头画面正常,YOLOv8能稳定检测到人脸。第三阶段的标准是检测到人脸之后头部能正确转向。

另外,文档和代码的版本管理很重要。我中间改了好几次机械结构,如果没有记录,后面都忘了哪个版本对应哪个参数。建议用Git管理代码,用文件夹加日期的方式管理机械结构的3D模型文件。

最后再分享一个小技巧:调试舵机动作的时候,可以先用一个简单的Web界面手动控制每个舵机,把想要的动作角度记录下来,然后再把这些角度写成动作序列。这样比直接写代码调角度直观多了,效率也高很多。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/30 1:12:14

西门子PLC编程语言选型指南:LAD、FBD、STL实战对比与切换技巧

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/30 1:12:06

浏览器即开即用:ESP32在线仿真、烧录与调试全攻略

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/30 1:12:00

低功耗蓝牙4.0协议栈深度解析:从PHY/LL到连接参数调优实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/30 1:10:45

低功耗蓝牙芯片技术盘点:国产SoC选型与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/30 1:09:40

ESP32-S3桌面状态终端技术栈选型:BLE、JSON与Arduino框架实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/30 1:08:54

视频掉帧排查全链路:从带宽计算到主机优化,换相机不是万能药

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华