mirror of
https://github.com/m5stack/M5Stack.git
synced 2026-05-20 10:06:46 -07:00
78457b190e
* rename some example file * add Unit exmaple sketch comment * add module example comment
178 lines
3.5 KiB
C++
Executable File
178 lines
3.5 KiB
C++
Executable File
#include "M5Bala.h"
|
|
#include "M5Stack.h"
|
|
|
|
#define MPU9250_ID 0x71
|
|
#define MPU6050_ID 0x68
|
|
|
|
M5Bala::M5Bala() {
|
|
wire = &Wire;
|
|
}
|
|
|
|
M5Bala::M5Bala(TwoWire &w) {
|
|
wire = &w;
|
|
}
|
|
|
|
void M5Bala::begin() {
|
|
|
|
// IMU
|
|
imu_CalcInit();
|
|
|
|
// Motor
|
|
setMotor(0, 0);
|
|
|
|
// PID param
|
|
K1 = 60;
|
|
K2 = 24;
|
|
K5 = 0;
|
|
K3 = 8.5;
|
|
K4 = 5.2;
|
|
// K5 = 8;
|
|
|
|
loop_interval = 0;
|
|
left_offset = 0;
|
|
right_offset = 0;
|
|
forward_offset = 0;
|
|
|
|
for (int i = 0; i < 128; i++) {
|
|
imu_update();
|
|
}
|
|
pitch = imu_getAngleX();
|
|
}
|
|
|
|
uint8_t M5Bala::i2c_readByte(uint8_t address, uint8_t subAddress) {
|
|
uint8_t data;
|
|
M5.I2C.readByte(address, subAddress, &data);
|
|
return data; // Return data read from slave register
|
|
}
|
|
|
|
void M5Bala::setMotor(int16_t pwm0, int16_t pwm1) {
|
|
// Value range
|
|
int16_t m0 = constrain(pwm0, -255, 255);
|
|
int16_t m1 = constrain(pwm1, -255, 255);
|
|
|
|
// Dead zone
|
|
if (((m0 > 0) && (m0 < DEAD_ZONE)) || ((m0 < 0) && (m0 > -DEAD_ZONE))) m0 = 0;
|
|
if (((m1 > 0) && (m1 < DEAD_ZONE)) || ((m1 < 0) && (m1 > -DEAD_ZONE))) m1 = 0;
|
|
|
|
// Same value
|
|
static int16_t pre_m0, pre_m1;
|
|
if ((m0 == pre_m0) && (m1 == pre_m1))
|
|
return;
|
|
pre_m0 = m0;
|
|
pre_m1 = m1;
|
|
|
|
uint8_t i2c_out_buff[4];
|
|
i2c_out_buff[0] = m0 & 0xff;
|
|
i2c_out_buff[1] = (m0 >> 8) & 0xff;
|
|
i2c_out_buff[2] = (m1 >> 0) & 0xff;
|
|
i2c_out_buff[3] = (m1 >> 8) & 0xff;
|
|
M5.I2C.writeBytes(M5GO_WHEEL_ADDR, MOTOR_CTRL_ADDR, i2c_out_buff, 4);
|
|
}
|
|
|
|
void M5Bala::readEncder() {
|
|
static float _speed_input0 = 0, _speed_input1 = 0;
|
|
int16_t rx_buf[2];
|
|
M5.I2C.readBytes(M5GO_WHEEL_ADDR, ENCODER_ADDR, 4, (uint8_t *)rx_buf);
|
|
|
|
// filter
|
|
_speed_input0 *= 0.9;
|
|
_speed_input0 += 0.1 * rx_buf[0];
|
|
_speed_input1 *= 0.9;
|
|
_speed_input1 += 0.1 * rx_buf[1];
|
|
|
|
speed_input0 = constrain((int16_t)(-_speed_input0), -255, 255);
|
|
speed_input1 = constrain((int16_t)(_speed_input1), -255, 255);
|
|
}
|
|
|
|
void M5Bala::PIDCompute() {
|
|
static float last_angle;
|
|
static int16_t last_wheel;
|
|
float angle, angle_velocity;
|
|
int16_t wheel, wheel_velocity;
|
|
int16_t torque, speed_diff, speed_diff_adjust;
|
|
|
|
angle = pitch;
|
|
angle_velocity = angle - last_angle;
|
|
last_angle = angle;
|
|
|
|
wheel = (speed_input0 + speed_input1) / 2; /* wheel = read_encoder()-profiler() */
|
|
wheel_velocity = wheel - last_wheel;
|
|
last_wheel = wheel;
|
|
|
|
torque = (angle_velocity * K1) + (angle * K2)
|
|
+ (wheel_velocity * K3) + (wheel * K4);
|
|
|
|
speed_diff = (speed_input0 - speed_input1);
|
|
speed_diff_adjust = (K5 * speed_diff);
|
|
|
|
pwm_out0 = torque - speed_diff_adjust;
|
|
pwm_out1 = torque;
|
|
pwm_out0 = constrain(pwm_out0, -255, 255);
|
|
pwm_out1 = constrain(pwm_out1, -255, 255);
|
|
}
|
|
|
|
void M5Bala::run() {
|
|
if (micros() >= loop_interval) {
|
|
loop_interval = micros() + 10000;
|
|
|
|
// Attitude sample
|
|
imu_update();
|
|
pitch = imu_getAngleX() + angle_offset;
|
|
|
|
// Car down
|
|
if (abs(pitch) > 45) {
|
|
setMotor(0, 0);
|
|
return;
|
|
}
|
|
|
|
// Encoder sample
|
|
readEncder();
|
|
|
|
// PID Compute
|
|
PIDCompute();
|
|
|
|
// Motor out
|
|
setMotor(pwm_out0 + forward_offset + left_offset,
|
|
pwm_out1 + forward_offset + right_offset);
|
|
}
|
|
}
|
|
|
|
void M5Bala::stop() {
|
|
left_offset = 0;
|
|
right_offset = 0;
|
|
}
|
|
|
|
void M5Bala::move(int16_t speed, uint16_t duration) {
|
|
forward_offset = -speed;
|
|
if (duration != 0) {
|
|
delay(duration);
|
|
stop();
|
|
}
|
|
}
|
|
|
|
void M5Bala::turn(int16_t speed, uint16_t duration) {
|
|
if (speed > 0) {
|
|
left_offset = speed;
|
|
right_offset = 0;
|
|
|
|
} else if (speed < 0) {
|
|
left_offset = 0;
|
|
right_offset = -speed;
|
|
}
|
|
|
|
if (duration != 0) {
|
|
delay(duration);
|
|
stop();
|
|
}
|
|
}
|
|
|
|
void M5Bala::rotate(int16_t speed, uint16_t duration) {
|
|
left_offset = speed;
|
|
right_offset = -speed;
|
|
|
|
if (duration != 0) {
|
|
delay(duration);
|
|
stop();
|
|
}
|
|
}
|