news 2026/9/3 10:32:00

基于STM32与OpenMV的智能网球捡球小车:嵌入式视觉与无线控制实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于STM32与OpenMV的智能网球捡球小车:嵌入式视觉与无线控制实战

简介:这是一套面向计算机科学、电子信息工程及自动化专业本科生的智能系统综合实践资源,适用于课程设计、期末大作业或毕业设计选题,解决网球运动场景中自动识别与拾取网球的实际问题。资源包共1254个文件,涵盖562个C源码、245个头文件(h)、125个XML配置、27个Java文件(APP逻辑)及23个CRF/22个O等编译中间文件,完整包含STM32固件、OpenMV图像处理算法、Android APP工程及WiFi通信协议栈,压缩包大小为42.47MB。已有61人学习下载,资源结构清晰:含IAR/Keil工程(uvprojx、axf、hex)、语音识别模型(baidu_speech_grammar.bsg)、数学库(arm_cortexM3l_math.a)、测试图像(test1.bmp)及启动脚本(gradlew.bat),便于读者快速部署、调试并理解多模块协同机制。

1. 项目缘起:从“捡球”这件小事说起

不知道你有没有过这样的经历:在网球场上挥汗如雨,一个漂亮的底线抽击之后,球飞到了场地的另一端。几轮下来,场地四周散落着十几个网球,弯腰去捡不仅打断了练习的节奏,对腰也是个不小的负担。传统的捡球器要么需要手动推着走,要么就是大型的、昂贵的专业设备。我的毕设课题,就是源于这个非常具体且真实的痛点——如何用相对低成本、易实现的技术,做一个能自动识别并收集网球的智能小车。

这不仅仅是一个简单的“遥控车加个筐”的项目。它涉及到机器视觉在动态环境下的目标识别与追踪、嵌入式系统对电机和机械结构的实时精准控制、无线通信在移动设备与固定主机间的稳定数据传输,以及一个手机APP作为直观的人机交互界面。整个系统可以看作是一个微缩版的“仓储AGV”(自动导引运输车)或“服务机器人”,其技术栈覆盖了嵌入式开发、图像处理、无线通信和移动应用开发等多个软硬件领域,综合性极强。

对于电子、自动化、计算机相关专业的同学来说,这样一个项目作为毕业设计课程设计,含金量是相当高的。它避开了纯软件项目的“虚空造轮”,也避免了纯硬件项目的“焊板子调参”的单一性,迫使你必须进行跨领域的系统集成与调试,这正是工程实践的核心。接下来,我就把自己从零开始搭建这套“智能网球车捡球系统”的全过程、核心原理、踩过的坑以及一些实用的技巧,毫无保留地分享出来。

2. 系统架构总览:一张图看懂所有模块如何协同工作

在动手写一行代码、焊一个元件之前,我们必须把系统的“骨架”——也就是架构——梳理清楚。这决定了后续开发是否顺畅,模块间会不会“打架”。我的系统核心架构可以概括为“一体两翼,视觉导航,无线遥控”。

一体,指的是以STM32F407微控制器为核心的主控板。它就像整个系统的大脑,负责协调所有外围模块:接收来自手机APP的指令,解析来自OpenMV的视觉数据,生成控制两个直流电机的PWM信号以实现差速转向,同时通过WiFi模块与手机保持通信。选择STM32F407,主要是看中了其丰富的定时器资源(用于多路PWM生成)、足够的SRAM和Flash(用于运行轻量级算法和存储程序)、以及多个串口(UART)用于同时连接WiFi模块和OpenMV。

两翼,分别是感知侧翼通信侧翼

  • 感知侧翼OpenMV Cam H7。这是一个集成了MicroPython解释器的机器视觉模块,核心是一颗STM32H7芯片和一颗摄像头。它的任务非常专一:通过摄像头实时捕捉前方图像,运行我预先写好的网球识别算法(基于颜色阈值和圆形霍夫变换),一旦识别到网球,就计算出网球在图像中的坐标(x, y)以及大概的像素面积(作为距离的粗略参考),然后通过串口将这些数据打包发送给STM32主控。
  • 通信侧翼ESP8266 WiFi模块。我选用的是AT指令固件的ESP-01S模块。它充当了STM32接入无线网络的“网卡”。STM32通过串口向ESP8266发送AT指令,使其连接到手机APP创建的热点(或同一个路由器网络)。连接建立后,双方通过TCP协议进行Socket通信。手机APP发送的“前进”、“左转”、“自动寻球”等指令,以及STM32回传的小车状态(如电池电压、是否捡到球),都通过这个通道传输。

手机APP则是整个系统的指挥中心和状态显示器。我使用Android Studio开发,界面简洁,包含方向控制按钮、模式切换开关(手动/自动)、实时视频流显示区域(接收来自OpenMV通过WiFi传输的MJPEG流)、以及状态信息栏。在自动模式下,APP只发送一个“开始自动寻球”的指令,之后小车就依靠OpenMV的视觉反馈自主运行。

整个数据流是这样的:手机APP下达指令 -> ESP8266接收并通过串口传给STM32 -> STM32解析指令 -> 若为手动模式,直接控制电机;若为自动模式,STM32读取OpenMV的串口数据 -> 根据网球位置(偏左、偏右、居中)和大小(远、近)计算出左右电机的速度差 -> 驱动小车朝向网球移动,直到机械机构将球收入囊中。

注意:这里存在一个关键设计抉择——视频流传输的路径。方案一:OpenMV将图像处理结果(坐标数据)给STM32,同时将原始视频流通过其自带的WiFi芯片直接发送给手机APP。方案二:所有数据(指令、视频流、状态)都通过ESP8266这一个通道。我选择了方案一,因为让OpenMV独立传输视频流可以极大减轻STM32和主通信通道的负担,避免视频数据堵塞控制指令。OpenMV Cam H7本身支持在运行脚本的同时开启RTSP或MJPEG流服务器,非常方便。

3. 硬件选型与电路设计:为什么是它们,而不是别的

硬件是系统的躯体,选型不当会让软件开发者举步维艰。以下是我的核心部件选型理由和关键的电路连接细节。

3.1 主控制器:STM32F407VET6为什么不是更简单的STM32F103?因为F103的串口和定时器资源可能捉襟见肘。我们需要至少两个串口(UART)分别与WiFi模块和OpenMV通信,可能还需要一个用于调试打印。F407有多个UART,绰绰有余。同时,F407更高的主频(168MHz)能更从容地处理数据解析、电机控制算法和可能的传感器融合(虽然本项目未用)。为什么不是单片机?因为STM32的生态(HAL库、标准库)和开发工具(Keil、STM32CubeIDE)能极大提升开发效率。

3.2 视觉模块:OpenMV Cam H7这是本项目成功的关键。尝试过用STM32直接驱动OV7670摄像头并运行图像算法,但无论是资源消耗还是开发难度都呈指数级上升。OpenMV将复杂的图像传感器驱动、图像缓存、基础算法库都封装好了,我只需要用Python(MicroPython)写几十行代码,专注于“识别黄色圆形物体”这个业务逻辑。其find_blobs函数(颜色阈值)结合find_circles函数(霍夫圆变换)能非常稳定地在网球场上识别出网球。H7版本性能更强,能处理更高分辨率的图像。

3.3 通信模块:ESP8266-01S选择它纯粹是因为成本低、资料多、AT指令稳定。也有考虑过直接使用ESP32,其功能更强大(可以同时承担WiFi和图像处理),但这会增加系统的复杂度和功耗,且与OpenMV功能重叠。我们的架构是“各司其职”,ESP8266就安心做好无线透传的工作。需要注意的是,ESP-01S的GPIO很少,我们只用到其UART(TX/RX)和电源引脚,将其设置为Station模式连接手机热点。

3.4 电机与驱动:直流减速电机 + TB6612FNG驱动芯片小车底盘我直接采购了现成的两轮差速驱动机器人底盘,自带编码器(虽然本项目未用于闭环控制)。电机驱动芯片的选择上,抛弃了古老的L298N(发热大、效率低),选择了TB6612FNG。它体积小、效率高、内置保护电路。与STM32的连接非常简单:两个PWM引脚控制速度(利用STM32的定时器输出PWM),两个GPIO引脚控制方向(正转/反转)。

3.5 电源管理:这是最容易忽略的坑整个系统涉及多块板子:STM32核心板(3.3V)、OpenMV(3.3V或5V,需仔细看手册)、ESP8266(3.3V)、TB6612(电机驱动电压,建议7-12V)。绝对不能用一个电源直接并联给所有模块供电!尤其是电机启动和急停时会产生巨大的电压尖峰和电流波动,会直接干扰甚至烧毁脆弱的数字电路。 我的方案是:

  1. 一块12V的锂电池组作为总电源。
  2. 12V直接供给TB6612的VMOT引脚(电机电源)。
  3. 通过一个DC-DC降压模块(12V转5V),将5V供给OpenMV(如果它支持5V)和另一个稳压模块
  4. 使用一个AMS1117-3.3或效率更高的DC-DC降压模块(5V转3.3V),产生纯净的3.3V,同时供给STM32、ESP8266和TB6612的逻辑供电部分(VCC)。 这样形成了级联的电源隔离,电机电路的噪声被限制在了前级,保证了核心控制电路的稳定。

关键电路连接示意图(文字描述):

  • STM32 PA9 (TX) -> ESP8266 RX
  • STM32 PA10 (RX) -> ESP8266 TX (注意:此处需要逻辑电平匹配,STM32是3.3V,ESP8266也是3.3V,直连即可。如果遇到通信不稳定,可串联一个220欧姆电阻)
  • STM32 PA2 (TX) -> OpenMV RX
  • STM32 PA3 (RX) -> OpenMV TX
  • STM32 TIM1_CH1 (PA8) -> TB6612 PWMA
  • STM32 TIM1_CH2 (PA9) -> TB6612 PWMB
  • STM32 PC0, PC1 -> TB6612 AIN1, AIN2 (控制电机A方向)
  • STM32 PC2, PC3 -> TB6612 BIN1, BIN2 (控制电机B方向)
  • 所有模块的GND必须共地,这是通信的基础。

4. 下位机核心:STM32的软件设计思路与避坑指南

STM32的程序是整个系统的调度中心。我使用STM32CubeMX进行引脚初始化和生成HAL库工程框架,这能节省大量配置外设的时间。

4.1 多任务处理与状态机虽然系统没有上RTOS(实时操作系统),但我们需要模拟出多任务协作的效果。主循环while(1)中,我采用一个简单的状态机(State Machine)来管理小车的工作模式:

typedef enum { MODE_MANUAL, // 手动遥控模式 MODE_AUTO_SEARCH, // 自动寻球模式 MODE_PICKING, // 正在捡球(机械臂动作,本项目简化版为直接驶过) MODE_RETURN // 返回起始点(可选功能) } SystemMode_t;

在自动寻球模式(MODE_AUTO_SEARCH)下,程序的核心任务就是:

  1. 读取OpenMV数据:定时(例如每50ms)检查串口是否有来自OpenMV的数据帧。数据帧需要自定义一个简单的协议,例如$,x,y,area,*\r\n,其中x,y是球心坐标,area是像素面积。使用串口空闲中断(Idle Interrupt)加DMA的方式是最优雅的,可以高效地接收不定长数据。
  2. 解析与坐标转换:OpenMV返回的(x, y)是图像像素坐标(比如160x120分辨率下的值)。我们需要将其转换为小车的转向指令。我采用了一种简单的比例控制:
    • 设定图像中心线CENTER_X = 80
    • 计算偏差error = x - CENTER_X
    • 控制量:turn_speed = Kp * error(Kp为比例系数)。
    • 最终速度:left_speed = base_speed - turn_speed; right_speed = base_speed + turn_speed;这样,当球在左边(x<80),error为负,左边轮子减速,右边轮子加速,小车左转。
  3. 距离判断area值可以粗略反映距离。设定一个阈值AREA_THRESHOLD,当area大于该阈值,认为球已经很近,可以触发“捡球”动作(例如小车直行1秒,利用前部的铲子或滚轮机构将球收入车筐),然后切换状态。

4.2 与ESP8266的AT指令通信这是软件部分最容易出bug的地方。ESP8266的AT指令必须严格按顺序发送,并等待其返回“OK”或具体数据。我将其封装成一个状态机:

typedef enum { WIFI_STATE_INIT, WIFI_STATE_AT, WIFI_STATE_CWMODE, WIFI_STATE_CONNECT_AP, WIFI_STATE_GET_IP, WIFI_STATE_START_TCP, WIFI_STATE_READY } WifiState_t;

在初始化阶段,依次发送ATAT+CWMODE=1(Station模式)、AT+CWJAP="SSID","password"AT+CIFSR(获取IP)、AT+CIPSTART="TCP","手机IP",端口号。每个指令后,都需要解析串口返回的数据,超时或错误都需要重试。务必注意的是,AT指令的结尾必须是\r\n,且每条指令的响应时间可能不同,需要设置合理的超时时间。

4.3 电机控制与PID(进阶)基础版本使用简单的比例控制转向已经可以工作。但如果希望小车运动更平滑、更精准,可以引入PID控制器。这里以转向PID为例:

  • 设定值(Setpoint):图像中心坐标CENTER_X
  • 测量值(Input):识别到的网球x坐标。
  • 输出(Output):电机的速度差。
  • PID计算output = Kp*error + Ki*integral + Kd*derivative。 将output限制在一个合理范围,然后叠加到基础速度上。Ki(积分项)可以消除静态误差(让球始终对准中心),Kd(微分项)可以预测变化趋势,防止振荡。参数Kp, Ki, Kd需要在实际场地上反复调试,这是一个“玄学”过程。

踩坑实录:电机干扰导致串口通信乱码。现象是,每当电机启动或变速时,OpenMV或ESP8266的串口数据就会偶尔出错。排查后发现,虽然电源做了隔离,但电机驱动板与STM32核心板之间的排线距离过长且未加屏蔽,电机产生的大电流变化引发了电磁干扰。解决方案:1. 缩短连接线,并尽量使用双绞线。2. 在电机电源线两端并联一个0.1uF的瓷片电容和一个100uF的电解电容,进行滤波。3. 在STM32的串口RX引脚对地加一个10pF-100pF的小电容,滤除高频噪声。立竿见影。

5. “眼睛”的算法:OpenMV上的网球识别与追踪

OpenMV的编程是在其自带的IDE中,使用MicroPython。代码逻辑清晰,主要分为初始化、主循环图像处理、数据发送三部分。

5.1 初始化与颜色阈值设定

import sensor, image, time, pyb from pyb import UART sensor.reset() sensor.set_pixformat(sensor.RGB565) # 彩色图像 sensor.set_framesize(sensor.QVGA) # 320x240, 平衡速度与精度 sensor.skip_frames(time = 2000) # 等待感光元件稳定 clock = time.clock() uart = UART(3, 115200) # 使用UART3,与STM32通信 # 定义网球的颜色阈值 (在RGB色彩空间下) # 这是一个关键步骤!需要在实际灯光环境下用IDE的“阈值编辑器”工具选取 yellow_threshold = (45, 75, 10, 50, 20, 70) # (L_min, L_max, A_min, A_max, B_min, B_max) in LAB color space

LAB颜色空间比RGB对光照变化更鲁棒。阈值的选取需要将摄像头对准网球,在OpenMV IDE中打开“工具 -> 机器视觉 -> 阈值编辑器”,拖动滑块直到网球区域为白色,背景为黑色。这个过程可能需要针对室内、室外、晴天、阴天进行微调。

5.2 主循环:寻找色块与圆形

while(True): clock.tick() img = sensor.snapshot() # 抓取一帧图像 # 方法1:先找色块(速度快,但可能把其他黄色物体误认为球) blobs = img.find_blobs([yellow_threshold], pixels_threshold=100, area_threshold=100, merge=True) if blobs: largest_blob = max(blobs, key=lambda b: b.pixels()) # 找最大的色块 img.draw_rectangle(largest_blob.rect()) # 画框 img.draw_cross(largest_blob.cx(), largest_blob.cy()) # 画中心十字 # 方法2:在色块区域进行圆形检测(提高准确率) # 可以只对色块所在的矩形区域进行霍夫圆变换,节省计算量 roi = largest_blob.rect() circles = img.find_circles(threshold=2000, x_margin=10, y_margin=10, r_margin=10, r_min=10, r_max=100, roi=roi) if circles: # 找到了圆形,认为这是网球 c = circles[0] img.draw_circle(c.x(), c.y(), c.r(), color=(0, 255, 0)) # 画绿色圆 # 准备发送的数据:x坐标, y坐标, 圆的面积(近似距离) data_to_send = "$,%d,%d,%d*" % (c.x(), c.y(), c.r()*c.r()*3.14) uart.write(data_to_send) else: # 是黄色但不是圆,可能误判,发送特定数据 uart.write("$,0,0,0*") else: # 没找到黄色,发送零数据 uart.write("$,0,0,0*")

5.3 优化与抗干扰策略

  1. 多特征融合:单纯的颜色阈值在复杂地面(如有枯叶)下容易误判。结合圆形检测可以极大提升准确率。网球的形状是相对标准的圆形。
  2. 区域兴趣(ROI):不需要对整个图像进行圆形检测,那样太慢。只在找到的黄色色块区域进行检测,大大减少了计算量。
  3. 滤波与跟踪:可以加入简单的滤波器,比如对连续几帧的球心坐标进行平均,或者使用卡尔曼滤波预测球的位置,能让小车的运动更平滑,避免因单帧识别抖动导致的“抽搐”。
  4. 曝光调整:在强光或暗光下,自动曝光可能失效。可以尝试使用sensor.set_auto_exposure(False)sensor.set_auto_gain(False)来手动设置曝光和增益,或者使用sensor.set_auto_whitebal(False)关闭白平衡,让颜色更稳定。

6. 手机APP开发:Android上的控制与监视界面

APP的功能相对直接,但要做好稳定性和用户体验。我使用Java开发,核心是三个部分:UI布局、网络通信(TCP Client)、视频流显示。

6.1 界面布局一个简单的布局包含:

  • 方向控制区:一个类似游戏手柄的十字按钮,或者四个独立的方向按钮(前、后、左、右)。按钮按下时发送对应的指令字符(如FBLR),释放时发送停止指令(S)。
  • 模式切换:一个Switch或RadioButton,用于切换“手动模式”和“自动模式”。
  • 视频显示区:一个TextureViewSurfaceView,用于渲染从OpenMV传来的MJPEG流。
  • 状态显示:几个TextView,用于显示连接状态、接收到的STM32回传数据(如电池电量)。

6.2 网络通信在Android中,网络操作必须在子线程中进行。我使用SocketBufferedReader/BufferedWriter

// 连接线程 private class ConnectThread extends Thread { private String serverIp; private int serverPort; public ConnectThread(String ip, int port) { this.serverIp = ip; this.serverPort = port; } @Override public void run() { try { socket = new Socket(serverIp, serverPort); outputStream = socket.getOutputStream(); inputStream = socket.getInputStream(); // 通知主线程连接成功,更新UI // 启动一个线程持续读取STM32发来的状态信息 new ReceiveThread().start(); } catch (IOException e) { // 连接失败,通知主线程 } } } // 发送指令方法 public void sendCommand(final String cmd) { if (outputStream != null) { new Thread(new Runnable() { @Override public void run() { try { outputStream.write(cmd.getBytes()); outputStream.flush(); } catch (IOException e) { e.printStackTrace(); } } }).start(); } }

6.3 MJPEG视频流显示OpenMV可以通过/mjpeg地址提供MJPEG流。在Android端,我们可以使用MjpegInputStream这个开源类来解析这种特殊的流(它本质是一系列连续的JPEG图片)。然后在一个独立的线程中不断读取流,并将解码后的Bitmap更新到TextureView上。

// 简化示例 MjpegInputStream mjpegIs = MjpegInputStream.read(socket.getInputStream()); Bitmap bmp; while ((bmp = mjpegIs.readMjpegFrame()) != null) { // 将bmp设置到ImageView或TextureView runOnUiThread(() -> imageView.setImageBitmap(bmp)); }

6.4 注意事项

  • 权限:别忘了在AndroidManifest.xml中添加网络权限:<uses-permission android:name="android.permission.INTERNET" />
  • IP地址配置:APP需要知道ESP8266连接后获取到的IP地址。一个简单的方法是让手机和ESP8266连接同一个路由器,在APP里固定服务器的IP(路由器分配给ESP8266的IP)。或者,可以让手机开启热点,ESP8266连接手机热点,此时手机的IP通常是192.168.43.1(常见AP模式地址)。
  • 心跳包:为了保持TCP长连接,防止因网络不稳定或NAT超时导致断开,APP可以定时(如每5秒)向小车发送一个心跳包(如字符H),STM32收到后原样回复。如果一段时间收不到回复,则触发重连机制。

7. 系统联调与实战测试:从实验室到网球场的挑战

当所有模块单独测试通过后,最激动人心也最令人头疼的联调就开始了。这个过程会暴露无数设计时未曾考虑的问题。

7.1 分阶段集成

  1. STM32 + 电机驱动:先让小车能听话地前后左右移动。测试PWM输出是否正常,电机转向是否正确。
  2. STM32 + ESP8266:让STM32能通过AT指令连接手机热点,并建立TCP连接。用手机上的网络调试助手(如TCP Client)发送字符,控制小车运动。这一步验证了通信链路。
  3. STM32 + OpenMV:断开WiFi,将OpenMV的数据打印到串口助手,同时让STM32解析这些数据并直接控制电机转向。用一个黄色的球在摄像头前移动,观察小车是否能跟随。
  4. OpenMV独立视频流:配置OpenMV,使其在运行识别脚本的同时,开启MJPEG服务器。在手机浏览器输入OpenMV的IP地址,看能否看到视频流。
  5. 全系统整合:将所有模块连接。手机APP连接OpenMV的视频流,并通过TCP向STM32发送指令。测试手动模式。最后,切换到自动模式,观察整套系统是否工作。

7.2 真实场景测试与调参实验室的桌面和真实的网球场是天壤之别。带到球场后,我遇到了以下问题:

  • 光照影响:早晨、中午、傍晚的光照色温完全不同,导致OpenMV的颜色阈值失效。解决方案:采用更鲁棒的LAB颜色空间,并在代码中加入简单的自动白平衡动态阈值调整逻辑。比如,可以识别场地绿色作为背景,动态计算黄色相对于绿色的阈值范围。
  • 地面干扰:球场边界线、广告牌、观众的衣服都可能含有黄色。解决方案:强化形状判断。结合圆形检测和色块的大小比例(网球在图像中的大小是有限的)。还可以加入多帧验证,只有连续3-5帧都识别为网球,才认为是真目标。
  • 小车运动导致的图像模糊:小车在移动时,摄像头拍摄的图像会模糊,影响识别。解决方案:1. 在OpenMV代码中尝试提高快门速度(减少曝光时间),但这需要更好的光照条件。2. 让小车采用“走-停-看”的策略:移动一小段距离,停下来识别一帧图像,根据结果决定下一步移动。虽然效率降低,但识别率大幅提升。
  • 通信距离与延迟:在户外,WiFi信号可能不稳定。解决方案:1. 使用外置天线的ESP8266模块。2. 在通信协议中加入序号和应答机制。APP发送的每条指令带一个序号,STM32收到后需要回复一个包含相同序号的确认包。如果APP在一定时间内没收到确认,则重发指令。3. 视频流如果卡顿,可以尝试降低OpenMV的图像分辨率(如从QVGA降到QQVGA)和帧率。

7.3 机械结构与捡球策略我的简易版本是在小车前部安装了一个用塑料板弯成的“铲子”,小车径直驶向网球,利用铲子的弧度将球兜起来,滚入后部的网兜。更复杂的方案可以加入小型舵机控制的机械臂。但无论哪种,都需要在STM32的程序中设计一个简单的“捡球序列”:当OpenMV检测到球面积足够大(距离很近)时,小车不是直接撞上去,而是先微调姿态对准,然后缓慢直行一小段距离,确保球被铲起,再后退或转弯,继续寻找下一个目标。

8. 项目总结与扩展思考

回顾整个项目,从电路设计、PCB焊接(如果自己画板的话)、嵌入式C编程、Python图像算法到Android开发,几乎把大学里学的核心课程都串了起来。最大的收获不是做出了一个能捡球的车,而是掌握了解决一个复杂系统工程问题的方法论:如何分解需求、如何选型、如何设计接口、如何分模块调试、如何解决棘手的干扰问题。

这个项目还有巨大的扩展空间:

  • 路径规划与多球任务:当前是“看到一个追一个”。可以升级为让小车记住已搜索过的区域,规划高效的“Z”字形路径覆盖整个球场,并记录已捡球的位置和数量。
  • SLAM与建图:引入一个激光雷达(如RPLIDAR A1)和IMU,在STM32上跑一个简化的SLAM算法(如Cartographer),让小车能构建球场地图并实现自主导航,而不仅仅依赖视觉。
  • 云端管理与多机协作:通过4G模块将小车状态上传到云端服务器,用户可以通过网页远程查看球场情况和控制小车。甚至可以设想多台小车协同工作,由云端服务器分配任务。
  • 能源优化:加入电池电量监测,实现低电量自动回充(需要定位和路径规划支持)。

对于想尝试的同学,我的建议是:从最简单的版本开始。先实现手机遥控小车移动,再加上视觉识别让小车跟随一个色块,最后再整合成完整的自动捡球系统。每完成一步,都能给你带来正反馈,避免一开始就陷入复杂的多线程调试中。硬件上,尽量使用现成的模块和开发板,把精力集中在软件逻辑和算法集成上。这个项目最迷人的地方,就在于你看着自己写的代码,让一堆冰冷的硬件“活”了过来,去完成一个具体的任务——这种成就感,是无与伦比的。

本文还有配套的精品资源,点击获取

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

MAS 微软激活脚本:Windows 与 Office 免费激活完整指南

MAS 微软激活脚本&#xff1a;Windows 与 Office 免费激活完整指南 【免费下载链接】Microsoft-Activation-Scripts Open-source Windows and Office activator featuring HWID, Ohook, TSforge, and Online KMS activation methods, along with advanced troubleshooting. 项…

作者头像 李华
网站建设 2026/9/3 10:28:35

C语言按位与运算符:从掩码判断到工程避坑指南

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

作者头像 李华
网站建设 2026/9/3 10:28:08

MATLAB构建滚动轴承与齿轮复合故障仿真信号:从原理到工程实践

简介&#xff1a;本资源是一套面向机械故障诊断研究者与信号处理初学者的MATLAB复合故障仿真工具包&#xff0c;聚焦滚动轴承与齿轮两类关键部件同时发生故障的建模与信号生成问题&#xff0c;有效支撑故障机理分析、诊断算法验证等科研与工程实践。压缩包共7个文件&#xff0c…

作者头像 李华
网站建设 2026/9/3 10:28:04

DXTEEN《Our Sky》表演视频:高清中字版获取与播放全攻略

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

作者头像 李华
网站建设 2026/9/3 10:27:09

免账户P2P AI聊天架构解析:Python实现加密同步最小原型

看到 PearPie 这类“私密 AI 会话 P2P 同步 无账户”方向时&#xff0c;很多开发者第一反应是&#xff1a;这不就是把聊天记录从中心服务器搬走吗&#xff1f;其实没那么简单。传统 AI 聊天应用里&#xff0c;“账户”不仅承担登录功能&#xff0c;还负责云同步、订阅计费、内…

作者头像 李华
网站建设 2026/9/3 10:26:54

从零构建RISC-V五级流水线CPU:设计原理、实现与FPGA验证

简介&#xff1a;本资源为面向计算机体系结构课程实践与期末大作业的RISC-V五级流水线CPU设计完整实现包&#xff0c;适用于本科高年级或研究生阶段数字系统设计学习者&#xff0c;解决从指令集理解、流水线建模到RTL实现与功能验证的一体化实践难题。压缩包共119个文件&#x…

作者头像 李华