0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于RT-Thread与K230(玄铁C908)的运动目标控制与追踪系统 | 技术集结

RT-Thread官方账号 ? 2025-08-29 17:04 ? 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

题目:运动目标控制与追踪系统 本项目基于 K230 平台实现运动目标位置复位、屏幕边框巡航、胶带正方形巡航、数字 8 循迹演示;并预留自动追踪红色光斑的扩展接口

目录


项目概述


题目要求—功能对照


硬件清单


接线与引脚映射


软件与运行环境


标定与坐标映射(关键)


代码结构与主要函数


使用方法


扩展:自动追踪红色光斑(对接题目(5))


时间与性能估算


常见问题


安全与注意事项


项目源码

项目概述


目标:在 1 m 处的白色屏幕(有效面积 ≥ 0.6×0.6 m?)上,用绿色激光光斑模拟“运动目标”,并按键触发不同的轨迹控制;同时给出像素→电机角度的标定方法。

平台:K230(摄像头、FPIOA、GPIO、UART)。

核心思路:

摄像头采图与显示;

像素坐标与双电机角度的双线性插值标定(pixel_to_angle);

通过串口(UART1)下发“使能 / 清零 / 限速位置模式”控制帧驱动两个电机。

使用手册:

K230:https://wiki.01studio.cc/docs/canmv_k230/

张大头步进电机https://www.yuque.com/zhangdatouzhikong/gzng3d

电机控制工具:https://pan.baidu.com/share/init?surl=rpwA7QtdAglsVxj_y77mmQ&pwd=x7dy

题目要求—功能对照


题目功能

本项目触发方式

代码入口

(1) 原点复位:绿色光斑能从屏幕任意位置回到原点(正方形左上角),误差 ≤ 2 cm

SW2短按

Reset_posi()

(2) 屏幕四周边线顺时针一周(≤ 30 s,光斑中心距边线 ≤ 2 cm)

SW3短按

Start_system()(按序发 5 个角点)

(3) 0.5×0.5 m 胶带正方形顺时针一周

与 (2) 同路径/同思想;将点位设在胶带线上(见 §6 标定)

Start_system() / 自定义点列

(4) 数字8贴于中心位置,顺时针一周

SW4短按

Reco_eight() + Eight_track()

(5) 一键切换自动追踪红色光斑(≤ 2 s 收敛,成功声光提示)

预留(需新增视觉检测与闭环控制)

见 §9 扩展建议

(6) 舵机控制不得加额外芯片

满足(全部由 K230 控制 UART、电机)

说明:

题目“原点为正方形左上角”,代码中已按此设定(Reset_posi() 将两个电机角度设为 (0,0))。

(3) 胶带巡航与 (2) 边框巡航本质相同,只需将轨迹点标定到胶带中心线上(§6)。

硬件清单


K230 开发板(带摄像头接口)

摄像头(RGB565,工作分辨率 320×240)

3D打印外壳 + 2 台步进电机(串口协议控制)

绿色激光笔(光斑直径 ≤ 1 cm)

红色激光笔(用于扩展项自动追踪)

4个按键(上拉输入)

接线与引脚映射


UART1:TXD=IO3,RXD=IO4(FPIOA.set_function)

按键(上拉输入):

SW1→IO35(使能/失能 切换)

SW2→IO34(原点复位)

SW3→IO33(边线/胶带巡航)

SW4→IO32(数字 8 轨迹)

电机地址:电机1:0x01、电机2: 0x02

软件与运行环境


固件 / SDK:K230 对应 Python 运行环境与 media.* 模块(摄像头、媒体)

主要依赖:time, os, sys, math, media.sensor, media.display, media.media, machine(UART/FPIOA/Pin)

串口参数:UART1,115200 bps

标定与坐标映射(关键)


代码通过 四点标定 + 双线性插值 将 像素 (x,y) 映射到 电机角度 (ax, ay):

# 获取电机角度defpixel_to_angle(x, y): # 像素的四角点 px_tl= (71,30) # 左上 px_tr= (248,29) # 右上 px_br= (246,206) # 右下 px_bl= (72,205) # 左下 # 对应的电机角度 ang_tl= (0.0,0.0) # 左上 ang_tr= (26.0,0.0) # 右上 ang_br= (26.2,25.8) # 右下 ang_bl= (-0.6,25.6) # 左下 # 把目标像素(x,y)映射到[0,1]×[0,1]的归一化坐标(u,v) u= (x - px_tl[0]) / (px_tr[0] - px_tl[0]) v= (px_tl[1] - y) / (px_tl[1] - px_bl[1]) u= max(0, min(1, u)) v= max(0, min(1, v)) # 对x轴角/y轴角分别做双线性插值 ax= (1-u)*(1-v)*ang_tl[0] + u*(1-v)*ang_tr[0] + u*v*ang_br[0] + (1-u)*v*ang_bl[0] ay= (1-u)*(1-v)*ang_tl[1] + u*(1-v)*ang_tr[1] + u*v*ang_br[1] + (1-u)*v*ang_bl[1] return(round(ax,1), round(ay,1))

(注:这个部分需要自行通过摄像头识别四个角点的像素坐标以及控制电机转动到四个角点并记录下角度,方便后续做像素→电机角度的映射)

u,v 为像素在四边形内的归一化坐标;

通过双线性插值得到 (ax, ay),并四舍五入到 0.1°;

下发控制前再放大 10 倍(协议以 0.1° 为单位):bx=int(ax*10)、by=int(ay*10)。

(注:放大10倍是因为命令里面位置角度:范围为00000000-FFFFFFFF,即0-4294967295,保留一位小数,值为1表示0.1°,值为10表示1°,以此类推)

如何满足 (2)/(3) 的“距边线≤2 cm”:

在标定时,将四角像素点精确对齐到屏幕上 0.5 m 正方形 的四个顶点;

巡航点列(x1..x4, y1..y4 或自定义数组)沿胶带中轴布置;

调整 speed 与采样密度,确保弧度/直线段逼近胶带路径。

代码结构与主要函数


串口协议:

Set_zero(addr):将当前位置角度清零;

# 将当前位置角度清零defSet_zero(addr): # addr=电机地址 cmd =bytearray(4) # 定义长度为4的指令帧 cmd[0] = addr # 地址(电机ID) cmd[1] = 0x0A # 功能码 cmd[2] = 0x6D # 辅助码 cmd[3] = 0x6B # 校验码 uart.write(cmd) # 通过串口发送这条指令

Enable_elect(addr, state):电机使能控制;

# 电机使能控制defEnable_elect(addr, state): # addr=电机地址,state=使能状态 cmd= bytearray(6) # 定义长度为6的指令帧 cmd[0] = addr # 地址(电机ID) cmd[1] = 0xF3 # 功能码 cmd[2] = 0xAB # 辅助码 cmd[3] = state # 使能状态:00/01分别表示不使能/使能 cmd[4] = 0x00 # 同步标志 cmd[5] = 0x6B # 校验码 uart.write(cmd) # 通过串口发送这条指令

Posi_ctrl(addr, vel, ang):直通限速位置模式控制。

# 直通限速位置模式控制defPosi_ctrl(addr, vel, ang): # addr=电机地址, vel=速度, ang=角度 ifang >50: # 角度限制 pass cmd= bytearray(12) # 定义长度为12的指令帧 cmd[0] = addr # 地址(电机ID) cmd[1] = 0xFB # 功能码 cmd[2] = 0x01 # 方向 cmd[3] = (vel >>8) &0xFF # 速度(高8位字节) cmd[4] = vel &0xFF # 速度(低8位字节) cmd[5] = (ang >>24) &0xFF # 位置角度(高8位字节bit24 - bit31) cmd[6] = (ang >>16) &0xFF # 位置角度(bit16 - bit23) cmd[7] = (ang >>8) &0xFF # 位置角度(bit8 - bit15) cmd[8] = ang &0xFF # 位置角度(低8位字节bit0 - bit7) cmd[9] = 0x01 # 运动模式 cmd[10] =0x00 # 同步标志 cmd[11] =0x6B # 校验码 uart.write(cmd) # 通过串口发送这条指令

系统参数:

addr_1/addr_2、speed、time_1/ time_2、预设角点 (x0..x4, y0..y4)

(x1..x4, y1..y4)这四个坐标是通过实践得出的,为了不完全脱离胶带稍微做了一些调整。

# 设置运动目标控制系统所需参数addr_1=0x01 # 电机1地址addr_2=0x02 # 电机2地址time_1=0.03 # 30mstime_2=2 # 2sspeed =30 # 速度state =1 # 电机状态x0=0 ; y0 = 0 # 原点x1=2 ; y1 = 3 # 左上x2=257; y2 = 3 # 右上x3=260; y3 = 256 # 右下x4=0 ; y4 = 255 # 左下

系统功能:

Clean_elect():双电机清零;

# 将电机xy值清零def Clean_elect(): Set_zero(addr_1) time.sleep(time_1) Set_zero(addr_2)

Enabled_elect(state):双电机使能;

# 不使能/使能电机def Enabled_elect(state): Enable_elect(addr_1,state) time.sleep(time_1) Enable_elect(addr_2,state)

Reset_posi():回到原点(左上角);

# 启动运动目标控制系统def Reset_posi(): Posi_ctrl(addr_1, speed, x0) time.sleep(time_1) Posi_ctrl(addr_2, speed, y0)

Start_system():按序到达 5 个角点,实现边框/胶带巡航;

# 启动运动目标控制系统def Start_system(): Posi_ctrl(addr_1, speed, x1) time.sleep(time_1) Posi_ctrl(addr_2, speed, y1) time.sleep(time_2) Posi_ctrl(addr_1, speed, x2) time.sleep(time_1) Posi_ctrl(addr_2, speed, y2) time.sleep(time_2) Posi_ctrl(addr_1, speed, x3) time.sleep(time_1) Posi_ctrl(addr_2, speed, y3) time.sleep(time_2) Posi_ctrl(addr_1, speed, x4) time.sleep(time_1) Posi_ctrl(addr_2, speed, y4) time.sleep(time_2) Posi_ctrl(addr_1, speed, x1) time.sleep(time_1) Posi_ctrl(addr_2, speed, y1)

(注:这部分的代码还未优化,比较冗余,这样写意义不大。可以修改成获取四个角点的像素点,通过pixel_to_angle(x, y)这个函数得到电机转动的角度进而控制电机运动)

pixel_to_angle():像素→角度(双线性插值);(详见 §6 标定)

get_motor_angles_from_pixel():单点下发;

# 传入像素坐标并返回电机角度defget_motor_angles_from_pixel(x, y): ax, ay = pixel_to_angle(x, y) bx =int(ax *10) # 电机控制需要乘以10 by =int(ay *10) # 电机控制需要乘以10 print(f"输入像素坐标: ({x},{y}) -> 电机角度: ({ax},{ay}) -> 换算角度: ({bx},{by})") Posi_ctrl(addr_1,100, bx) time.sleep(0.01) Posi_ctrl(addr_2,100, by) time.sleep(0.01)

Reco_eight():摄像头找圆(find_circles),采样 N=48 点/圆并缩放至 96% 半径;

# 识别数字8def Reco_eight(): # ----- 拍一张图 ----- for _ inrange(5): sensor.snapshot() img = sensor.snapshot() # 用于标记每个圆的采样点编号 point_number =1 scale_factor =0.96 # 检测圆形 for c in img.find_circles(threshold=6000, x_margin=10, y_margin=10, r_margin=10, r_min=35, r_max=45, r_step=4): # 画出圆 r = c.r() img.draw_circle(c.x(), c.y(), r, color=(255,0,0), thickness=2) print("找到圆: 圆心=(", c.x(),",", c.y(),") 半径=", c.r()) # ----- 在圆周上采样48个点 ----- N =48 for i inrange(N): theta =2* math.pi * i / N - math.pi /2 px =int(c.x() + r * math.cos(theta)) py =int(c.y() + r * math.sin(theta)) # 计算新的缩小后的点坐标 new_px =int(c.x() + (px - c.x()) * scale_factor) new_py =int(c.y() + (py - c.y()) * scale_factor) trajectory_points.append((new_px, new_py)) point_number +=1 # 增加点编号 # 显示结果 Display.show_image(img, x=round((lcd_width - sensor.width()) /2), y=round((lcd_height - sensor.height()) /2))

Eight_track(points, t):按“左圆上半圈→右圆上半圈→右圆下半圈→左圆下半圈”的顺/逆时针顺序形成 8 字轨迹。

# 数字8循迹def Eight_track(trajectory_points,times): # 顺时针走第一个圆的前半圈 for(x, y)intrajectory_points[:24]: get_motor_angles_from_pixel(x, y) time.sleep(times) # 延时times秒 # 顺时针走第二个圆的前半圈 for(x, y)intrajectory_points[48:72]: get_motor_angles_from_pixel(x, y) time.sleep(times) # 延时times秒 # 逆时针走第二个圆的后半圈 for(x, y)intrajectory_points[72:96]: get_motor_angles_from_pixel(x, y) time.sleep(times) # 延时times秒 # 逆时针走第一个圆的后半圈 for(x, y)intrajectory_points[24:48]: get_motor_angles_from_pixel(x, y) time.sleep(times) # 延时times秒 x,y = trajectory_points[1] get_motor_angles_from_pixel(x, y)

使用方法


上电与初始化:

上电前我们需要手动把电机置于原点;

代码开头完成 UART、按键、摄像头初始化;

默认 Enabled_elect(1) 使能电机并执行 Clean_elect(),记录当前位置为原点。

按键操作:

SW1:电机使能/失能切换;

SW2:回到原点(左上角);

SW3:沿预设边框/胶带点位顺时针巡航;

SW4:拍照识别两个圆,生成 8 字轨迹并沿轨迹运行(Eight_track(trajectory_points, 0.1))。

扩展:自动追踪红色光斑(对接题目(5))


当前代码暂未实现自动追踪红光斑,后续可以按照如下开发路径进行完善:

检测红色光斑:在摄像头图像做 HSV/阈值分割,寻找最大连通域质心 (xr, yr);

像素→角度:调用 pixel_to_angle(xr, yr) 得到期望角度 (ax, ay);

闭环控制:周期性下发 Posi_ctrl(vel, ang),或加入 PID(对误差 e=目标角-当前角);

收敛判定与提示:误差持续 < 阈值(例如 0.2°)且时间 < 2 s,触发蜂鸣器/LED 连续提示;

抗抖与安全:对质心做时间滤波,限制角速度与加速度。

时间与性能估算


边框巡航:Start_system() 在四边与对角点之间各等待 time_2 = 2 s,总时长约 8~10 s(远小于 30 s 限制)。如需更“贴边”,可在侧边插入更多中间点。

数字 8:每个圆 N=48 点,Eight_track(..., 0.1) 单圈约 48×2×0.1 = 9.6 s,可按评分需求调节 N 与 times。

常见问题


光斑不在边线上 / 偏差大:检查 §6 标定四点是否准确落在 0.5 m 正方形顶点;必要时重新测量角度对照表(ang_*)。

运动不连贯 / 抖动:适当降低 speed,增加过渡点;在串口下发间隙留足 time.sleep。

找不到圆 / 8 字不闭合:调节 find_circles 的 threshold / r_min / r_max;提高屏幕对比、降低环境光。

电机无响应:确认 Enable_elect(..., 1) 已使能;串口连线正确;地址 0x01/0x02 与实物一致。

安全与注意事项


激光直视有危险,请确保对人眼安全;

设备摆放与图示一致(屏幕 1 m 处),防止反射;

运行前先执行 Clean_elect(),避免机械撞限位。

项目源码


GitHub仓库地址:https://github.com/ruanqiuqiu/RSOC_K230_project

RT-Thread Github 开源仓库,欢迎撒个星(Star)支持,更期待你的代码贡献:https://github.com/RT-Thread/rt-thread

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 运动控制
    +关注

    关注

    4

    文章

    752

    浏览量

    33712
  • 追踪系统
    +关注

    关注

    0

    文章

    34

    浏览量

    9447
  • RT-Thread
    +关注

    关注

    32

    文章

    1453

    浏览量

    42428
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    RT-Thread BSP全面支持全系列RISC-V 处理器 | 技术集结

    RT-Thread标准版已全面适配E、R、C系列内核,并在C906内核上支持RT-Smar
    的头像 发表于 07-03 18:03 ?1905次阅读
    <b class='flag-5'>RT-Thread</b> BSP全面支持<b class='flag-5'>玄</b><b class='flag-5'>铁</b>全系列RISC-V 处理器 | <b class='flag-5'>技术</b><b class='flag-5'>集结</b>

    【BPI-CanMV-K230D-Zero开发板体验】香蕉派 K230D 视觉开发板开箱+CamMV 环境搭建

    D 基于开源 RISC-V 内核,拥有双核 C908 RISC-V CPU 核心 架构 主频 0 C908 64bit RISC-V 800MHz 1
    发表于 06-24 22:54

    【嘉楠堪智K230开发板试用体验】基于RT-THREAD上的PWM驱动开发

    K230 平台 PWM 驱动移植与实现详解 一、K230 上的 PWM 控制器资源概览 在 01studio K230 平台上,PWM 控制
    发表于 07-29 13:35

    RT-Thread全球技术大会:萤石研发团队使用RT-Thread技术挑战

    RT-Thread全球技术大会:研发团队使用RT-Thread技术挑战 ? ? ? ? 审核编辑:彭静
    的头像 发表于 05-27 11:36 ?1635次阅读
    <b class='flag-5'>RT-Thread</b>全球<b class='flag-5'>技术</b>大会:萤石研发团队使用<b class='flag-5'>RT-Thread</b>的<b class='flag-5'>技术</b>挑战

    RT-Thread全球技术大会:RT-Thread构建配置系统

    RT-Thread全球技术大会:RT-Thread构建配置系统,构建系统也称为组件自动化,通常需要通过脚本声明构建行为。 ? ? ? ? 审
    的头像 发表于 05-27 14:39 ?1595次阅读
    <b class='flag-5'>RT-Thread</b>全球<b class='flag-5'>技术</b>大会:<b class='flag-5'>RT-Thread</b>构建配置<b class='flag-5'>系统</b>

    RT-Thread全球技术大会:RT-Thread测试用例集合案例

    RT-Thread全球技术大会:RT-Thread测试用例集合案例 ? ? ? ? ? 审核编辑:彭静
    的头像 发表于 05-27 16:34 ?2465次阅读
    <b class='flag-5'>RT-Thread</b>全球<b class='flag-5'>技术</b>大会:<b class='flag-5'>RT-Thread</b>测试用例集合案例

    平头哥全新RISC-V高能效处理器C908实现能效突破

    11月3日,在2022云栖大会上,阿里平头哥发布全新RISC-V高能效处理器C908C908
    的头像 发表于 11-03 17:37 ?1430次阅读

    全新RISC-V高能效处理器C908,神经网络计算提升50%以上

    C908支持多核多簇架构,采用高效9级双发按序流水线,主频2 GHz,通过创新的微体系结构和指令融合等技术,实现能效的大幅提升。
    发表于 11-17 15:43 ?1301次阅读

    RT-Thread文档_RT-Thread SMP 介绍与移植

    RT-Thread文档_RT-Thread SMP 介绍与移植
    发表于 02-22 18:31 ?9次下载
    <b class='flag-5'>RT-Thread</b>文档_<b class='flag-5'>RT-Thread</b> SMP 介绍与移植

    嘉楠科技K230发布!支持Linux + RT-Thread Smart 双操作系统运行

    示例,帮助开发者快速上手芯片开发。此外, SDK 提供? Linux + RT-Thread Smart 双操作系统,以及相应的外设驱动代码。开发者可以 快速完成从硬件开发、底层软件开发到应用软件
    的头像 发表于 07-25 19:50 ?2742次阅读
    嘉楠科技<b class='flag-5'>K230</b>发布!支持Linux + <b class='flag-5'>RT-Thread</b> Smart 双操作<b class='flag-5'>系统</b>运行

    RT-Thread 联手构建端云一体解决方案,共拓物联网技术新生态

    在刚刚结束的RT-Thread全球技术峰会上,RT-Thread正式发布双方基于
    的头像 发表于 06-12 08:35 ?1235次阅读
    <b class='flag-5'>玄</b><b class='flag-5'>铁</b>与<b class='flag-5'>RT-Thread</b> 联手构建端云一体解决方案,共拓物联网<b class='flag-5'>技术</b>新生态

    RT-Thread Smart携手K230/K230D打造多核RISC-V高性能嵌入式操作系统

    在万物互联的智能时代,国产软硬件技术的突破正成为推动产业升级的核心动力。RT-ThreadSmart(简称:RT-Smart)操作系统与嘉楠科技K2
    的头像 发表于 03-17 16:35 ?1659次阅读
    <b class='flag-5'>RT-Thread</b> Smart携手<b class='flag-5'>K230</b>/<b class='flag-5'>K230</b>D打造多核RISC-V高性能嵌入式操作<b class='flag-5'>系统</b>

    搭载双核C908 ?RISC-V CPU,BPI-CanMV-K230D-Zero开发板试用

    K230D Zero ?开发板。这款创新的开发板是由嘉楠科技与香蕉派开源社区联合设计研发,搭载了先进的勘智 K230D 芯片。 K230D 芯片拥有双核
    的头像 发表于 06-05 16:49 ?775次阅读
    搭载双核<b class='flag-5'>玄</b><b class='flag-5'>铁</b><b class='flag-5'>C908</b> ?RISC-V CPU,BPI-CanMV-<b class='flag-5'>K230</b>D-Zero开发板试用

    加入RT-Thread 高级会员合作伙伴 | 战略新篇

    今天起,XuanTie正式成为RT-Thread高级会员合作伙伴。此次合作标志着双方将在嵌入式操作系统创新、RISC-V生态构建及行业应用落地等领域展开深度协同,加速推动开源
    的头像 发表于 06-23 20:22 ?622次阅读
    <b class='flag-5'>玄</b><b class='flag-5'>铁</b>加入<b class='flag-5'>RT-Thread</b> 高级会员合作伙伴 | 战略新篇

    RT-Thread携手,全面展示 RISC-V 生态最新成果,期待莅临!

    2025年7月16日-19日,第五届RISC-V中国峰会将在上海张江科学会堂举行。作为全球领先的开源实时操作系统(RTOS)提供商,RT-Thread将携手,在大会现场打造专属展位
    的头像 发表于 07-15 11:13 ?595次阅读
    <b class='flag-5'>RT-Thread</b>携手<b class='flag-5'>玄</b><b class='flag-5'>铁</b>,全面展示 RISC-V 生态最新成果,期待莅临!