MSPM0開發學習筆記:二維云臺畫圖(2025電賽 附源代碼及引腳配置)

前言

今年的電賽(2025),很多題都與云臺相關,因此為備戰電賽,博主這邊也是準備了一個由兩個42步進電機驅動的云臺并提前進行調試,避免賽題出來之后手忙腳亂的,這邊的兩個42步進電機采用同一個驅動模塊進行驅動(D36A),主控肯定采用MSPM0G3507。然后3D打印了一個二維云臺的結構并進行組裝。本章博客主要是講這個云臺進行繪圖的思路以及代碼。激光還沒有安裝上去,目前只是云臺的循跡代碼


如果無法很好的復現博客里的代碼,可以私信作者博取源代碼,電賽期間都在線

一、硬件選擇

主控:MSPM0G3507
驅動:D36A雙路步進電機驅動
電機:42步進電機*2

二、硬件連線

硬件連線部分在上一篇博客里面已經說過了,可以直接去上一篇里面看,這邊附上鏈接
MSPM0開發學習筆記:D36A驅動的42步進電機二維云臺(2025電賽 附源代碼及引腳配置)

三、軟件代碼

軟件部分采用C語言實現,IDE采用keil,基于逐飛庫進行編寫
這邊先進行一下簡單的參數說明,便于理解后面的思路

參數含義以及作用
current_x目前的X坐標
current_y目前的Y坐標
target_x需要移動到的X坐標
target_y需要移動到的Y坐標
move_x需要移動的X距離
move_y需要移動的Y距離
point_count繪制圓形時候的點數

驅動—電機

代碼實現如下:

函數一:限幅函數

#define MAX_ANGLE_X  1000.0f   
#define MIN_ANGLE_X -1000.0f   
#define MAX_ANGLE_Y  1000.0f  
#define MIN_ANGLE_Y -1000.0f  float limit_angle(float angle, float min, float max) {if (angle < min) return min;if (angle > max) return max;return angle;
}

函數二:激光云臺繪制正方形

// Function to draw a square trajectory
// Parameters:
//   x_len - length of the square's X-axis dimension
//   y_len - length of the square's Y-axis dimension
//   MOVE_SPEED - speed of movement between points
void draw_square(int x_len, int y_len, int MOVE_SPEED) {// Structure to store X and Y angle coordinatestypedef struct {float x_angle;  // X-axis angle positionfloat y_angle;  // Y-axis angle position} Point;// Invert Y-axis length (likely for coordinate system adjustment)y_len = y_len * -1;// Calculate half-lengths for easier coordinate calculationfloat x_len_2 = x_len / 2;float y_len_2 = y_len / 2;// Define square vertices relative to origin (0,0)// Coordinates form a square shape when connected sequentiallyPoint square_points[] = {{-1 * x_len_2, y_len_2},    // Top-left corner{x_len_2, y_len_2},         // Top-right corner{x_len_2, -1 * y_len_2},    // Bottom-right corner{-1 * x_len_2, -1 * y_len_2},// Bottom-left corner{-1 * x_len_2, y_len_2},    // Back to top-left to close the square{0.0f, 0.0f}                // Final point: return to origin};// Calculate total number of points in the square trajectoryuint8 point_count = sizeof(square_points) / sizeof(Point);  // Initialize current position at origin (0,0)float current_x = 0;float current_y = 0;// Move to each defined point in sequencefor (uint8 i = 0; i < point_count; i++) {// Ensure target angles stay within allowed rangefloat target_x = limit_angle(square_points[i].x_angle, MIN_ANGLE_X, MAX_ANGLE_X);float target_y = limit_angle(square_points[i].y_angle, MIN_ANGLE_Y, MAX_ANGLE_Y);// Calculate relative movement from current position to targetfloat move_x = target_x - current_x;float move_y = target_y - current_y;// Update current position to target coordinatescurrent_x = target_x;current_y = target_y;// Send movement command to both axesd36a_set_angle_both(move_x, move_y, MOVE_SPEED);// Pause 300ms after reaching each pointsystem_delay_ms(300);}// Pause 2 seconds after completing the squaresystem_delay_ms(2000);
}

一、函數定義:draw_square函數接收三個參數,分別是正方形的 X 軸長度(x_len)、Y 軸長度(y_len)和移動速度(MOVE_SPEED)。
二、數據結構:定義了Point結構體用于存儲坐標點的 X 和 Y 角度值。
三、坐標處理:
1、將 Y 軸長度取負值(為了調整坐標系方向)
2、計算半長(x_len_2, y_len_2),用于確定正方形頂點坐標
3、坐標定義:定義了正方形的 4 個頂點坐標和原點(0,0)坐標以中心點為原點,通過半長計算得出四個頂點位置
4、最后回到一個點 (0,0) 用于回到起點
四、繪制邏輯:
1、遍歷所有定義的坐標點
2、對每個目標點進行角度限制(通過limit_angle函數確保在有效范圍內)
3、計算當前位置到目標點的移動量
4、調用d36a_set_angle_both函數移動到目標點(同時設置 X 和 Y 方向角度)
5、每個點移動后延遲 300 毫秒,繪制完成后延遲 2000 毫秒

函數三:激光云臺繪制圓形

// Function to draw a circle trajectory
// Parameters:
//   r - radius of the circle
//   MOVE_SPEED - speed of movement between points
//   point_count - number of points to use for drawing the circle (more = smoother)
void draw_circle(int r, int MOVE_SPEED, const uint8 point_count) {// Structure to store X and Y angle coordinatestypedef struct {float x_angle;  // X-axis angle positionfloat y_angle;  // Y-axis angle position} Point;// Array to store circle points (extra element to close the loop)Point circle_points[point_count + 1];  // Calculate coordinates for each point on the circlefor (uint8 i = 0; i < point_count; i++) {// Convert angle from degrees to radians (full circle = 2π radians)float rad = 2 * 3.1415926f * i / point_count;// Calculate X and Y positions using trigonometric functions// cosine for X-axis, sine for Y-axis to form circular pathcircle_points[i].x_angle = r * cosf(rad); circle_points[i].y_angle = r * sinf(rad);  }// Close the circle by duplicating the first point as the last pointcircle_points[point_count] = circle_points[0];// Initialize current position at origin (0,0)float current_x = 0.0f;  float current_y = 0.0f; // Move to each calculated point in sequencefor (uint8 i = 0; i <= point_count; i++) {// Ensure target angles stay within allowed rangefloat target_x = limit_angle(circle_points[i].x_angle, MIN_ANGLE_X, MAX_ANGLE_X);float target_y = limit_angle(circle_points[i].y_angle, MIN_ANGLE_Y, MAX_ANGLE_Y);// Calculate relative movement from current position to targetfloat move_x = target_x - current_x;float move_y = target_y - current_y;// Update current position to targetcurrent_x = target_x;current_y = target_y;// Send movement command to both axesd36a_set_angle_both(move_x, move_y, MOVE_SPEED);// Optional delay between point movements// system_delay_ms(10);}// Return to origin (0,0) after completing the circlefloat target_x = 0;float target_y = 0;// Calculate movement from last circle point to originfloat move_x = target_x - current_x;float move_y = target_y - current_y;// Update current position to origincurrent_x = target_x;current_y = target_y;// Send final movement command to return to origind36a_set_angle_both(move_x, move_y, MOVE_SPEED);// Pause for 2 seconds after completing the circlesystem_delay_ms(2000);  
}

通過三角函數(X 軸用余弦、Y 軸用正弦)計算圓周上指定數量的點的坐標,這些點基于圓周的等角度增量分布。函數會按順序在這些點之間移動(帶速度控制),同時確保角度在有效范圍內;通過回到第一個點來閉合圓形軌跡,最后返回原點,結束時短暫暫停。點的數量越多,繪制的圓越平滑。
以下是函數中涉及的公式:

  1. 弧度計算(將圓周等分為指定數量的點)
    rad=2×π×ipoint_count\text{rad} = 2 \times \pi \times \frac{i}{\text{point\_count}} rad=2×π×point_counti?
    其中,iii 為當前點的索引(0 到 point_count-1),point_count\text{point\_count}point_count 為圓周上的總點數,rad\text{rad}rad 為對應角度的弧度值。
  2. X軸坐標計算
    x_angle=r×cos?(rad)x\_angle = r \times \cos(\text{rad}) x_angle=r×cos(rad)
    其中,rrr 為圓的半徑,cos?(rad)\cos(\text{rad})cos(rad) 為弧度對應的余弦值。
  3. Y軸坐標計算
    y_angle=r×sin?(rad)y\_angle = r \times \sin(\text{rad}) y_angle=r×sin(rad)
    其中,sin?(rad)\sin(\text{rad})sin(rad) 為弧度對應的正弦值。

四、總結

這邊給的都是一些簡單圖形的繪制代碼,但是思路都是通用的,復雜圖形也可以復用這一套邏輯。大家參考參考就好

如果無法很好的復現博客里的代碼,可以私信作者博取源代碼,電賽期間都在線

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/91375.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/91375.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/91375.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

借助 Wisdom SSH 的 AI 助手構建 Linux 開發環境

借助Wisdom SSH的AI助手構建Linux開發環境 在Linux系統的開發場景中&#xff0c;快速、準確地搭建開發環境至關重要。Wisdom SSH憑借其強大的AI助手&#xff0c;能極大簡化這一過程&#xff0c;其官網為ssh.wisdomheart.cn。以下以在Ubuntu 22.04服務器上構建Python開發環境&am…

Python 程序設計講義(44):組合數據類型——集合類型:創建集合

Python 程序設計講義&#xff08;44&#xff09;&#xff1a;組合數據類型——集合類型&#xff1a;創建集合 目錄Python 程序設計講義&#xff08;44&#xff09;&#xff1a;組合數據類型——集合類型&#xff1a;創建集合一、集合的特征二、創建集合&#xff1a;使用set()函…

10 - 大語言模型 —Transformer 搭骨架,BERT 裝 “雙筒鏡”|解密雙向理解的核心

目錄 1、為什么 BERT 能 “懂” 語言&#xff1f;先看它的 “出身” 2、核心邏輯 2.1、“自學階段”—— 預訓練&#xff0c;像嬰兒學說話一樣積累語感 2.1.1、簡述 2.1.2、核心本事&#xff1a;“雙向注意力”&#xff0c;像人一樣 “聚焦重點” 2.2、“專項復習”—— …

【Spring Boot 快速入門】四、MyBatis

目錄MyBatis&#xff08;一&#xff09;入門簡介MyBatis 入門LombokMyBatis 基礎操作數據準備刪除預編譯新增更新查詢XML 映射文件MyBatis&#xff08;一&#xff09;入門 簡介 MyBatis 是一款 優秀的持久層框架&#xff0c;它支持 自定義 SQL、存儲過程以及高級映射&#xf…

Spring IOC 基于Cglib實現含構造函數的類實例化策略

作者&#xff1a;小凱 分享、讓自己和他人都能有所收獲&#xff01; 一、前言 技術成長&#xff0c;是對場景設計細節不斷的雕刻&#xff01; 你覺得自己的技術什么時候得到了快速的提高&#xff0c;是CRUD寫的多了以后嗎&#xff1f;想都不要想&#xff0c;絕對不可能&#xf…

composer 常用命令

### 設置鏡像源全局設置composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/當個項目設置composer config repo.packagist composer https://mirrors.aliyun.com/composer/恢復官方源composer config -g --unset repos.packagist### 常用源阿里云…

【python】Python爬蟲入門教程:使用requests庫

Python爬蟲入門教程&#xff1a;使用requests庫 爬蟲是數據獲取的重要手段&#xff0c;下面我將通過一個完整的示例&#xff0c;教你如何使用Python的requests庫編寫一個簡單的爬蟲。我們將以爬取豆瓣電影Top250為例。 【python】網絡爬蟲教程 - 教你用python爬取豆瓣電影 Top…

OpenCV圖像縮放:resize

圖像縮放是圖像處理中的基礎操作之一。無論是圖像預處理、數據增強還是圖像金字塔構建&#xff0c;cv::resize 都是我們最常用的函數之一。但你是否注意到&#xff0c;在 OpenCV 中同時還存在一個名為 cv::Mat::resize 的方法&#xff1f;這兩個函數雖然名字類似&#xff0c;但…

汽車、航空航天、適用工業虛擬裝配解決方案

一、現狀在制造業數字化轉型浪潮中&#xff0c;傳統裝配過程仍面臨諸多挑戰&#xff1a;物理樣機試錯成本高、裝配周期冗長、工藝優化依賴經驗、跨部門協作效率低下……如何打破“試錯-返工”的惡性循環&#xff1f;目前總裝工藝通過DELMIA、NX、Creo等工程軟件進行工藝裝配驗證…

頁面跳轉和前端路由的區別

傳統方式&#xff1a;通過改變瀏覽器地址欄的 URL 來實現window.location.href /new-page<a href"/new-page">跳轉到新頁面</a>會導致整個頁面重新加載會觸發瀏覽器向服務器發送新的請求頁面狀態不會保留&#xff0c;所有資源重新加載可以避免新上線的內…

C/C++核心知識點詳解

C/C核心知識點詳解 1. 變量的聲明與定義&#xff1a;內存分配的本質區別 核心概念 在C/C中&#xff0c;變量的聲明和定義是兩個完全不同的概念&#xff1a; 聲明&#xff08;Declaration&#xff09;&#xff1a;告訴編譯器變量的名稱和類型&#xff0c;但不分配內存空間定義&a…

物聯網發展:從概念到應用的演變歷程

物聯網的發展歷程是一部技術革新與社會需求共同驅動的進化史&#xff0c;其演變可劃分為概念萌芽、技術積累、應用拓展和智能融合四個階段&#xff0c;每個階段均以關鍵技術突破或社會需求變革為標志&#xff0c;最終形成萬物互聯的智能生態。以下是具體演變歷程&#xff1a;一…

一個人開發一個App(數據庫)

后端要保存數據&#xff0c;我還是選擇了關系型數據庫Mysql, 因為其它的不熟悉。 flutter端這次我選擇的是ObjectBox&#xff0c;以前都是直接用的sqlite3&#xff0c;看對比ObjectBox效率比sqlite3高許多&#xff0c;這次前端為了用戶體驗&#xff0c;我需要緩存數據&#xff…

天銘科技×藍卓 | “1+2+N”打造AI驅動的汽車零部件行業智能工廠

7月24日&#xff0c;杭州天銘科技股份有限公司&#xff08;簡稱 “天銘科技”&#xff09;與藍卓數字科技有限公司&#xff08;簡稱 “藍卓”&#xff09;簽訂全面戰略合作協議。天銘科技董事長張松、副總經理艾鴻冰&#xff0c;藍卓副董事長譚彰等領導出席簽約儀式&#xff0c…

技術復盤報告:Vue表格中多行文本字段數據保存丟失問題

1. 問題背景 在一個基于 Vue 2.0 和 ElementUI 的復雜數據維護頁面中&#xff0c;用戶報告了一個偶發但嚴重的問題&#xff1a;在表格中編輯一個多行文本&#xff08;textarea&#xff09;字段時&#xff0c;輸入的內容有時會在點擊“保存”后丟失。 具體表現&#xff1a; 前端…

#C語言——學習攻略:深挖指針路線(四)--字符指針變量,數組指針變量,二維數組傳參的本質,函數指針變量,函數指針數組

&#x1f31f;菜鳥主頁&#xff1a;晨非辰的主頁 &#x1f440;學習專欄&#xff1a;《C語言學習》 &#x1f4aa;學習階段&#xff1a;C語言方向初學者 ?名言欣賞&#xff1a;"暴力解法是上帝給的&#xff0c;優化解法是魔鬼教的。" 目錄 1. 字符指針變量 1.1 使…

SpringBoot收尾+myBatis plus

一、數據傳遞返回值為:字符串package com.apesource.springboot_web_04.controller;import com.apesource.springboot_web_04.pojo.Emp; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;/*** 返回值為:字符…

基于 Spring Boot 實現動態路由加載:從數據庫到前端菜單的完整方案

在后臺管理系統中&#xff0c;不同用戶角色往往擁有不同的操作權限&#xff0c;對應的菜單展示也需動態調整。動態路由加載正是解決這一問題的核心方案 —— 根據登錄用戶的權限&#xff0c;從數據庫查詢其可訪問的菜單&#xff0c;封裝成前端所需的路由結構并返回。本文將詳細…

VitePress學習-自定義主題

VitePress-自定義主題 代碼倉庫 基礎了解 初始化項目的時候選擇 custom theme 運行后會發現頁面挺丑的。 如果想要用默認主題怎么辦呢&#xff0c;修改Layout。 使用默認主題的Layout <script setup lang"ts"> import { useData } from vitepress; impo…

【GEO從入門到精通】生成式引擎與其他 AI 技術的關系

2.1.3 生成式引擎與其他 AI 技術的關系生成式引擎作為人工智能領域的創新力量&#xff0c;與其他 AI 技術緊密相連&#xff0c;相互促進&#xff0c;共同推動 生成式引擎優化&#xff08;GEO&#xff09; 的發展。這些技術使生成式引擎能夠為消費者提供更加個性化和精準的內容。…