esp32-car/src/motor.cpp

203 lines
4.4 KiB
C++
Raw Normal View History

2024-12-27 09:47:56 +08:00
#include "motor.h"
// 静态成员初始化
MotorStatus MotorController::motorA = {{0, 0, 0}, false, false, 0};
MotorStatus MotorController::motorB = {{0, 0, 0}, false, false, 0};
MotorStatus MotorController::motorC = {{0, 0, 0}, false, false, 0};
MotorStatus MotorController::motorD = {{0, 0, 0}, false, false, 0};
void MotorController::init(
MotorPin aPin,
MotorPin bPin,
MotorPin cPin,
MotorPin dPin)
{
2024-12-27 15:56:14 +08:00
Serial.println("Motor Init");
2024-12-27 09:47:56 +08:00
motorA.pin = aPin;
motorB.pin = bPin;
motorC.pin = cPin;
motorD.pin = dPin;
pinMode(aPin.pwm, OUTPUT);
pinMode(aPin.in1, OUTPUT);
pinMode(aPin.in2, OUTPUT);
pinMode(bPin.pwm, OUTPUT);
pinMode(bPin.in1, OUTPUT);
pinMode(bPin.in2, OUTPUT);
pinMode(cPin.pwm, OUTPUT);
pinMode(cPin.in1, OUTPUT);
pinMode(cPin.in2, OUTPUT);
pinMode(dPin.pwm, OUTPUT);
pinMode(dPin.in1, OUTPUT);
pinMode(dPin.in2, OUTPUT);
}
void MotorController::pwmControl(char motor, unsigned char pwm)
{
int pwmPin;
switch (motor)
{
case 'A':
pwmPin = motorA.pin.pwm;
motorA.pwm = pwm;
break;
case 'B':
pwmPin = motorB.pin.pwm;
motorB.pwm = pwm;
break;
case 'C':
pwmPin = motorC.pin.pwm;
motorC.pwm = pwm;
break;
case 'D':
pwmPin = motorD.pin.pwm;
motorD.pwm = pwm;
break;
}
analogWrite(pwmPin, pwm);
}
// 电机控制函数
void MotorController::motorControl(char motor, int speed)
{
int in1Pin, in2Pin;
MotorStatus *status;
switch (motor)
{
case 'A':
in1Pin = motorA.pin.in1;
in2Pin = motorA.pin.in2;
status = &motorA;
break;
case 'B':
in1Pin = motorB.pin.in2;
in2Pin = motorB.pin.in1;
status = &motorB;
break;
case 'C':
in1Pin = motorC.pin.in2;
in2Pin = motorC.pin.in1;
status = &motorC;
break;
case 'D':
in1Pin = motorD.pin.in1;
in2Pin = motorD.pin.in2;
status = &motorD;
break;
}
if (speed > 0)
{
digitalWrite(in1Pin, HIGH);
digitalWrite(in2Pin, LOW);
if (motor == 'A' || motor == 'D')
{
status->in1 = true;
status->in2 = false;
}
else
{
status->in1 = false;
status->in2 = true;
}
}
else if (speed < 0)
{
digitalWrite(in1Pin, LOW);
digitalWrite(in2Pin, HIGH);
if (motor == 'A' || motor == 'D')
{
status->in1 = false;
status->in2 = true;
}
else
{
status->in1 = true;
status->in2 = false;
}
speed = -speed;
}
else
{
digitalWrite(in1Pin, LOW);
digitalWrite(in2Pin, LOW);
status->in1 = false;
status->in2 = false;
}
pwmControl(motor, speed);
}
void MotorController::motorXYRControl(int8_t x, int8_t y, int8_t r)
{
// 将输入范围限制在 -100 到 100
x = constrain(x, -100, 100);
y = constrain(y, -100, 100);
r = constrain(r, -100, 100);
// 将 -100~100 映射到 -255~255
int16_t mappedX = map(x, -100, 100, -255, 255);
int16_t mappedY = map(y, -100, 100, -255, 255);
int16_t mappedR = map(r, -100, 100, -255, 255);
// 麦克纳姆轮运动学方程
2024-12-27 23:20:56 +08:00
// 左前轮(A) = Y - X - R
// 右前轮(D) = Y + X - R
// 右后轮(C) = Y - X + R
// 左后轮(B) = Y + X + R
int16_t speedA = mappedY - mappedX - mappedR; // 左前轮
int16_t speedB = mappedY + mappedX + mappedR; // 左后轮
int16_t speedC = mappedY - mappedX + mappedR; // 右后轮
int16_t speedD = mappedY + mappedX - mappedR; // 右前轮
2024-12-27 09:47:56 +08:00
// 找出最大速度的绝对值
int16_t maxSpeed = max(max(abs(speedA), abs(speedB)),
max(abs(speedC), abs(speedD)));
// 如果最大速度超过255等比例缩放所有速度
if (maxSpeed > 255)
{
float scale = 255.0f / maxSpeed;
speedA *= scale;
speedB *= scale;
speedC *= scale;
speedD *= scale;
}
// 控制各个电机
motorControl('A', speedA);
motorControl('B', speedB);
motorControl('C', speedC);
motorControl('D', speedD);
}
2025-01-01 17:53:59 +08:00
void MotorController::rotate(RotateDirection direction, uint8_t speed)
{
motorControl('A', direction == ROTATE_CLOCKWISE ? speed : -speed);
motorControl('B', direction == ROTATE_CLOCKWISE ? speed : -speed);
motorControl('C', direction == ROTATE_CLOCKWISE ? -speed : speed);
motorControl('D', direction == ROTATE_CLOCKWISE ? -speed : speed);
}
2024-12-27 09:47:56 +08:00
MotorStatus MotorController::getMotorStatus(char motor)
{
switch (motor)
{
case 'A':
2025-01-01 17:53:59 +08:00
return motorA;
2024-12-27 09:47:56 +08:00
case 'B':
2025-01-01 17:53:59 +08:00
return motorB;
2024-12-27 09:47:56 +08:00
case 'C':
2025-01-01 17:53:59 +08:00
return motorC;
2024-12-27 09:47:56 +08:00
case 'D':
2025-01-01 17:53:59 +08:00
return motorD;
2024-12-27 09:47:56 +08:00
default:
return {false, false, 0};
}
}