文章目錄
- 前言
- 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. 原理總結
- PS2手柄的搖桿值通過計算與中立值 127 的差值,確定搖桿的偏移方向和幅度。
- 根據搖桿的偏移方向和幅度,調整四個電機的轉速,實現小車的前后、左右、旋轉等運動。
- 通過設置死區(num),避免搖桿微小變化導致電機頻繁調整。
- 最終通過 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 + 272 + (-23)2 + 472 = 102
car_left2 = 0 - 272 + (-23)2 + 472 = -6
car_right2 = 0 + 272 + (-23)2 - 472 = -86
通過 motor_speed_set 函數將這些值傳遞給電機控制器,實現小車的運動。