嵌入式硬件篇---手柄控制控制麥克納姆輪子


文章目錄

  • 前言
  • 1. 變量定義
  • 2. 搖桿死區設置
  • 3. 模式檢查
  • 4. 搖桿數據處理
    • 4.1 右搖桿垂直值(psx_buf[7])
    • 4.2 右搖桿水平值(psx_buf[8])
    • 4.3 左搖桿水平值(psx_buf[5])
    • 4.4 左搖桿垂直值(psx_buf[6])
  • 5. 電機轉速更新
  • 6. 保存當前轉速值
  • 7. 原理總結
  • 8. 參數轉化示例
    • 假設
    • 計算
    • 最終電機轉速


前言

這段代碼的作用是通過PS2手柄的搖桿數據來控制小車的四個電機轉速。下面我將詳細解釋這段代碼的邏輯、PS2手柄的參數如何轉化為小車轉速,以及其背后的原理。


1. 變量定義

float car_left1=0, car_right1=0, car_left2=0, car_right2=0;
static float car_left1_bak = 0, car_right1_bak = 0, car_left2_bak = 0, car_right2_bak = 0;

car_left1, car_right1, car_left2, car_right2:分別表示小車四個電機的目標轉速。
car_left1_bak, car_right1_bak, car_left2_bak, car_right2_bak:用于保存上一次的電機轉速值,用于判斷是否需要更新電機轉速。

2. 搖桿死區設置

static u8 num = 10;

num 是一個閾值,用于設置搖桿的“死區”。當搖桿的值變化小于 num 時,忽略這些微小的變化,避免電機頻繁調整。

搖桿的原始值范圍是 0~255中間值是 127。如果搖桿的值與 127 的差值小于 num,則認為搖桿處于“中立”位置。

3. 模式檢查

if (psx_buf[1] != PS2_LED_RED)return;

psx_buf[1] 是PS2手柄的當前模式(例如紅燈模式或綠燈模式)。
如果當前模式不是紅燈模式(PS2_LED_RED),則直接返回,不處理搖桿數據

4. 搖桿數據處理

PS2手柄的搖桿數據存儲在 psx_buf 數組中:
psx_buf[5]:左搖桿的水平值(X軸)。
psx_buf[6]:左搖桿的垂直值(Y軸)。
psx_buf[7]:右搖桿的水平值(X軸)。
psx_buf[8]:右搖桿的垂直值(Y軸)。
搖桿值的范圍是 0~255,中間值是 127。通過計算搖桿值與 127 的差值,可以確定搖桿的偏移方向和幅度。

4.1 右搖桿垂直值(psx_buf[7])

if (abs_int(127 - psx_buf[7]) > num)
{car_left1 = car_left1 - (0x7f - psx_buf[7]) * 2;car_right1 = car_right1 + (0x7f - psx_buf[7]) * 2;car_left2 = car_left2 - (0x7f - psx_buf[7]) * 2;car_right2 = car_right2 + (0x7f - psx_buf[7]) * 2;
}

右搖桿的垂直值控制小車的前后運動。
(0x7f - psx_buf[7]):計算搖桿值與中立值 127 的差值。
如果搖桿向上推(psx_buf[7] < 127),差值為正,小車向前運動。
如果搖桿向下拉(psx_buf[7] > 127),差值為負,小車向后運動。
將差值放大,增加電機轉速的靈敏度。
通過調整 car_left1, car_right1, car_left2, car_right2 的值,控制四個電機的轉速。

4.2 右搖桿水平值(psx_buf[8])

if (abs_int(127 - psx_buf[8]) > num)
{car_left1 = car_left1 + (0x7f - psx_buf[8]) * 2;car_right1 = car_right1 + (0x7f - psx_buf[8]) * 2;car_left2 = car_left2 + (0x7f - psx_buf[8]) * 2;car_right2 = car_right2 + (0x7f - psx_buf[8]) * 2;
}

右搖桿的水平值控制小車的左右平移。
(0x7f - psx_buf[8]):計算搖桿值與中立值 127 的差值。
如果搖桿向右推(psx_buf[8] > 127),差值為負,小車向右平移。
如果搖桿向左推(psx_buf[8] < 127),差值為正,小車向左平移。
將差值放大,增加電機轉速的靈敏度。

4.3 左搖桿水平值(psx_buf[5])

if (abs_int(127 - psx_buf[5]) > num)
{car_left1 = car_left1 - (0x7f - psx_buf[5]) * 2;car_right1 = car_right1 + (0x7f - psx_buf[5]) * 2;car_left2 = car_left2 + (0x7f - psx_buf[5]) * 2;car_right2 = car_right2 - (0x7f - psx_buf[5]) * 2;
}

左搖桿的水平值控制小車的旋轉。
(0x7f - psx_buf[5]):計算搖桿值與中立值 127 的差值。
如果搖桿向右推(psx_buf[5] > 127),差值為負,小車順時針旋轉。
如果搖桿向左推(psx_buf[5] < 127),差值為正,小車逆時針旋轉。
將差值放大,增加電機轉速的靈敏度。

4.4 左搖桿垂直值(psx_buf[6])

if (abs_int(127 - psx_buf[6]) > num)
{car_left1 = car_left1 + (0x7f - psx_buf[6]) * 2;car_right1 = car_right1 + (0x7f - psx_buf[6]) * 2;car_left2 = car_left2 + (0x7f - psx_buf[6]) * 2;car_right2 = car_right2 + (0x7f - psx_buf[6]) * 2;
}

左搖桿的垂直值控制小車的前后運動(與右搖桿垂直值類似)。
(0x7f - psx_buf[6]):計算搖桿值與中立值 127 的差值。
如果搖桿向上推(psx_buf[6] < 127),差值為正,小車向前運動。
如果搖桿向下拉(psx_buf[6] > 127),差值為負,小車向后運動。
將差值放大,增加電機轉速的靈敏度。

5. 電機轉速更新

if ((car_left1_bak != car_left1) || (car_right1_bak != car_right1) || (car_left2_bak != car_left2) || (car_right2_bak != car_right2))
{motor_speed_set(car_left1 / 1000, car_right1 / 1000, car_left2 / 1000, car_right2 / 1000);
}

如果當前計算的電機轉速與上一次保存的值不同,則調用 motor_speed_set 函數更新電機轉速。
car_left1 / 1000:將轉速值縮小,可能是為了適配電機控制器的輸入范圍。

6. 保存當前轉速值

car_left1_bak = car_left1;
car_right1_bak = car_right1;
car_left2_bak = car_left2;
car_right2_bak = car_right2;

保存當前計算的電機轉速值,用于下一次比較。

7. 原理總結

  1. PS2手柄的搖桿值通過計算與中立值 127 的差值,確定搖桿的偏移方向和幅度
  2. 根據搖桿的偏移方向和幅度,調整四個電機的轉速,實現小車的前后、左右、旋轉等運動。
  3. 通過設置死區(num),避免搖桿微小變化導致電機頻繁調整。
  4. 最終通過 motor_speed_set 函數將計算出的轉速值傳遞給電機控制器,實現小車的運動控制。

8. 參數轉化示例

假設

psx_buf[7] = 100(右搖桿向上推)。
psx_buf[8] = 150(右搖桿向右推)。
psx_buf[5] = 80(左搖桿向左推)。
psx_buf[6] = 127(左搖桿中立)。

計算

右搖桿垂直值:127 - 100 = 27,差值為正,小車向前運動。
右搖桿水平值:127 - 150 = -23,差值為負,小車向右平移。
左搖桿水平值:127 - 80 = 47,差值為正,小車逆時針旋轉。
左搖桿垂直值:127 - 127 = 0,無變化。

最終電機轉速

car_left1 = 0 - 272 + (-23)2 - 472 = -194
car_right1 = 0 + 27
2 + (-23)2 + 472 = 102
car_left2 = 0 - 272 + (-23)2 + 472 = -6
car_right2 = 0 + 27
2 + (-23)2 - 472 = -86

通過 motor_speed_set 函數將這些值傳遞給電機控制器,實現小車的運動。


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

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

相關文章

阿里千問大模型(Qwen2.5-VL-7B-Instruct)部署

參考鏈接 知乎帖子 B站視頻 huggingface 鏡像網站&#xff08;不太全&#xff0c;比如 Qwen/Qwen2.5-VL-7B-Instruct就沒有&#xff09; huggingface 5種下載方式匯總 通過huggingface-cli下載模型 不一樣的部分是預訓練權重的下載和demo 首先安裝huggingface_hub pip insta…

Jenkins在Windows上的使用(二):自動拉取、打包、部署

&#xff08;一&#xff09;Jenkins全局配置 訪問部署好的Jenkins服務器網址localhost:8080&#xff0c;完成默認插件的安裝后&#xff0c;接下來將使用SSH登錄遠程主機以實現自動化部署。 1. 配置插件 選擇dashboard->Manage Jenkins->plugins 安裝下面兩個插件  …

群暉DS 223 Docker:開啟私有云

群暉DS 223 Docker&#xff1a;開啟私有云的無限可能 引言 在數據存儲與管理的不斷演進中&#xff0c;群暉 DS 223 憑借其出色的性能和豐富的功能&#xff0c;成為眾多用戶搭建私有云的熱門選擇。而當它與 Docker 技術相遇&#xff0c;猶如為數據管理的舞臺添上了絢麗多彩的燈…

git切換版本

git brach 查看本地 剛從git上下載下來 的話 可以通過 git checkout xxxx進行切換 可能一段時間沒有用 而服務器上新建了某些版本 那么需要用 git fetch origin 同步本地與git服務器的分支 然后 創建本地分支xxx 并從服務器拉取xxx git checkout -b xxx origin/xxx…

Three.js 進階(燈光陰影關系和設置、平行光、陰影相機)

本篇主要學習內容 : 燈光與陰影聚光燈點光源平行光陰影相機和陰影計算投射陰影接受陰影 點贊 關注 收藏 學會了 1.燈光與陰影 1、材質要滿足能夠對光有反應 2、設置渲染器開啟陰影計算 renderer.shadowMap.enabledtrue 3、設置光照投射陰影 directionalLight.castShadow …

【 <一> 煉丹初探:JavaWeb 的起源與基礎】之 Tomcat 的工作原理:從啟動到請求處理的流程

<前文回顧> 點擊此處查看 合集 https://blog.csdn.net/foyodesigner/category_12907601.html?fromshareblogcolumn&sharetypeblogcolumn&sharerId12907601&sharereferPC&sharesourceFoyoDesigner&sharefromfrom_link <今日更新> 一、Tomcat…

【GPT入門】第11課 FunctionCall調用本地代碼入門

【GPT入門】第11課 FunctionCall調用代碼入門 1. 手撕FunctionCall2.代碼3.functionCall的結果 1. 手撕FunctionCall 為了了解&#xff0c;funcationCall底層&#xff0c;手寫一個functionCall多方法&#xff0c;并調用&#xff0c;體驗 思路&#xff1a; 任務&#xff1a;讓…

MySQL主從架構配合ShardingJdbc實現讀寫分離

文章目錄 目錄架構搭建讀寫分離pom.xmlfdy-live-user-provider 模塊application.ymlfdy-db-sharding.yamlShardingJdbcDatasourceAutoInitConnectionConfig.java 目錄 架構搭建 基于Docker去創建MySQL的主從架構 讀寫分離 pom.xml <dependency><groupId>mysql…

計網面試準備

正確理解網絡數據傳輸過程 同一路由器的不同接口屬于不同局域網&#xff0c;廣播只能在同一個局域網

NLP常見任務專題介紹(1)-關系抽取(Relation Extraction, RE)任務訓練模板

?? 關系抽取(Relation Extraction, RE)任務訓練示例 本示例展示如何訓練一個關系抽取模型,以識別兩個實體之間的關系。 1?? 任務描述 目標:從文本中提取兩個實體之間的語義關系,例如 “人物 - 組織”、“藥物 - 疾病”、“公司 - 創始人” 等。輸入:句子 + 標注的實…

【技術白皮書】內功心法 | 第二部分 | Telnet遠程登錄的工作原理

遠程登錄的工作原理 背景介紹遠程登錄遠程登錄的服務模式遠程登錄服務的實現基礎遠程登錄服務的運行模式Telnet服務為什么不被操作系統管理 Telnet協議的原理網絡虛終端&#xff08;NVT&#xff09;結束標示NVT的原理NVT屏蔽差異 背景介紹 絕大多數計算機都是運行多用戶操作系…

在 Spring Boot 中實現基于 TraceId 的日志鏈路追蹤

1 前言 1.1 什么是 TraceId? TraceId 是一個唯一的標識符,用于跟蹤分布式系統中的請求。每個請求從客戶端發起到服務端處理,再到可能的多個微服務調用,都會攜帶這個 TraceId,以便在整個請求鏈路中進行追蹤和調試。 1.2 日志鏈路追蹤的意義 日志鏈路追蹤可以幫助開發者…

游戲引擎學習第150天

回顧與當天計劃 我們在這里完全不使用任何庫&#xff0c;所以我們完全是引擎和庫免疫的, 正如大家所知道的&#xff0c;我們正在編寫自己的資源處理系統&#xff0c;準確來說&#xff0c;是一個資源加載系統。過去一周我們已經完成了很多工作&#xff0c;現在只剩下最后幾步&a…

Flutter中stream學習

Flutter中stream學習 概述Stream的基礎概念stream的常用方法Stream.fromFuture(Future<T> future)Stream.fromFutures(Iterable<Future<T>> futures)Stream.fromIterable(Iterable<T> elements)Stream.periodic(Duration period, [T computation(int c…

基于javaweb的SSM房屋租賃管理系統設計和實現(源碼+文檔+部署講解)

技術范圍&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬蟲、數據可視化、小程序、安卓app、大數據、物聯網、機器學習等設計與開發。 主要內容&#xff1a;免費功能設計、開題報告、任務書、中期檢查PPT、系統功能實現、代碼編寫、論文編寫和輔導、論…

物聯網商業模式

物聯網商業模式是一種戰略規劃&#xff0c;它融合了物聯網技術來創造價值并獲取收入。它與傳統商業模式的不同之處在于&#xff0c;它利用互聯設備來改善運營、提升客戶體驗以及優化服務項目。在當今由科技驅動的世界中&#xff0c;這種商業模式通過利用實時數據來提供創新服務…

從0開始的操作系統手搓教程45——實現exec

目錄 建立抽象 實現加載 實現sys_execv &#xff01;&#xff01;&#xff01;提示&#xff1a;因為實現問題沒有測試。所以更像是筆記&#xff01; exec 函數的作用是用新的可執行文件替換當前進程的程序體。具體來說&#xff0c;exec 會將當前正在運行的用戶進程的進程體&…

【python爬蟲】酷狗音樂爬取練習

注意&#xff1a;本次爬取的音樂僅有1分鐘試聽&#xff0c;僅作學習爬蟲的原理&#xff0c;完整音樂需要自行下載客戶端。 一、 初步分析 登陸酷狗音樂后隨機選取一首歌&#xff0c;在請求里發現一段mp3文件&#xff0c;復制網址&#xff0c;確實是我們需要的url。 復制音頻的…

Linux開發工具----vim

目錄 Linux編輯器-vim使用 1. vim的基本概念 正常/普通/命令模式(Normal mode) 插入模式(Insert mode) 底行模式(last line mode) 2. vim的基本操作 3. vim正常模式命令集 4. vim底行模式命令集 5. vim操作總結 (本篇文章相當于vim常用命令字典) Linux編輯器-vim使用 我們先來看…

基于云函數的自習室預約微信小程序+LW示例參考

全階段全種類學習資源&#xff0c;內涵少兒、小學、初中、高中、大學、專升本、考研、四六級、建造師、法考、網賺技巧、畢業設計等&#xff0c;持續更新~ 文章目錄 [TOC](文章目錄) 1.項目介紹2.項目部署3.項目部分截圖4.獲取方式 1.項目介紹 技術棧工具&#xff1a;云數據庫…