simplefoc / arduino-foc-reaction-wheel-inverted-pendulum Goto Github PK
View Code? Open in Web Editor NEWReaction wheel inverted pendulum project based on the Arduino Simple FOC library and SimpleFOC shied.
License: MIT License
Reaction wheel inverted pendulum project based on the Arduino Simple FOC library and SimpleFOC shied.
License: MIT License
hello
I got a foc board and was looking to try out an inverted pendulum.
As a first step I'm trying out the 2V motor rotation (beginning of your video), however I don't get the motor initialisation and there is no movement.
Trying to debug this there are a couple of things that seem odd to me:
thanks for your pointers
my hardware:
board: arduino mega 1280
motor: https://www.aliexpress.com/item/4001296350749.html
encoder: https://www.aliexpress.com/item/32990323362.html
(it's the first time i'm using this type of encoder, i didn't find any info on pull-up/down, so i didn't solder any of those on the board)
Dear Antun,
Thank you so much for this amazing project and it is very inspiring !!
I made a similar system that is almost working (please see https://youtube.com/shorts/L6I1zPEigmI?feature=share), but I don't know to tune the LQR parameters precisely so to make it completely stabilize. Could you please give me some advice? Thanks!
-- Wingman
HELLO SIR
I'm working on your perfect project.
So far, we have been able to successfully control the reaction wheel by lifting it up and standing it up by hand. However, it is not possible to raise the pendulum upward by swinging up. In your code, 40% of the voltage limit is used for swing-up, but even if I use more than 80%, the pendulum does not reach the top with swing-up.
Currently I am experimenting with the reaction wheel of the same weight and size as the pendulum of your project and a 12V POWER SUPPLY. Are there any expected problems?
Is it possible to achieve a similar result, but instead of using an encoder to get the position of the pendulum, use a gyro like the BNO055?
I'm trying to create a balancing RC vehicle that uses a reaction wheel to keep itself upright, but struggling to find a good motor/ESC pair, and came across the Arduino FOC project which seems promising. From what I can tell, it includes torque control, which is exactly what I would need.
The motor makes a mechanical sound at first and does not work.
I would appreciate any help in terms of hardware or software.
The Arduino code used is as follows
// software interrupt library
#include <PciManager.h>
#include <PciListenerImp.h>
// BLDC motor init
BLDCMotor motor = BLDCMotor(11);
// driver instance
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 10, 11, 8);
//Motor encoder init
Encoder encoder = Encoder(A1, A2, 500);
// interrupt routine
void doA(){encoder.handleA();}
void doB(){encoder.handleB();}
// pendulum encoder init
Encoder pendulum = Encoder(2, 3, 1000);
// interrupt routine
void doPA(){pendulum.handleA();}
void doPB(){pendulum.handleB();}
// PCI manager interrupt
PciListenerImp listenerPA(pendulum.pinA, doPA);
PciListenerImp listenerPB(pendulum.pinB, doPB);
void setup() {
// initialise motor encoder hardware
encoder.init();
encoder.enableInterrupts(doA,doB);
// init the pendulum encoder
pendulum.init();
PciManager.registerListener(&listenerPA);
PciManager.registerListener(&listenerPB);
// set control loop type to be used
motor.controller = MotionControlType::torque;
// link the motor to the encoder
motor.linkSensor(&encoder);
// driver
driver.voltage_power_supply = 12;
driver.init();
// link the driver and the motor
motor.linkDriver(&driver);
// initialize motor
motor.init();
// align encoder and start FOC
motor.initFOC();
}
// loop downsampling counter
long loop_count = 0;
void loop() {
// ~1ms
motor.loopFOC();
// control loop each ~25ms
if(loop_count++ > 25){
// updating the pendulum angle sensor
// NECESSARY for library versions > v2.2
pendulum.update();
// calculate the pendulum angle
float pendulum_angle = constrainAngle(pendulum.getAngle() + M_PI);
float target_voltage;
if( abs(pendulum_angle) < 0.5 ) // if angle small enough stabilize
target_voltage = controllerLQR(pendulum_angle, pendulum.getVelocity(), motor.shaftVelocity());
else // else do swing-up
// sets 40% of the maximal voltage to the motor in order to swing up
target_voltage = -_sign(pendulum.getVelocity())*motor.voltage_limit*0.4;
// set the target voltage to the motor
motor.move(target_voltage);
// restart the counter
loop_count=0;
}
}
// function constraining the angle in between -pi and pi, in degrees -180 and 180
float constrainAngle(float x){
x = fmod(x + M_PI, _2PI);
if (x < 0)
x += _2PI;
return x - M_PI;
}
// LQR stabilization controller functions
// calculating the voltage that needs to be set to the motor in order to stabilize the pendulum
float controllerLQR(float p_angle, float p_vel, float m_vel){
// if angle controllable
// calculate the control law
// LQR controller u = k*x
// - k = [40, 7, 0.3]
// - x = [pendulum angle, pendulum velocity, motor velocity]'
float u = 40*p_angle + 7*p_vel + 0.3*m_vel;
// limit the voltage set to the motor
if(abs(u) > motor.voltage_limit*0.7) u = _sign(u)*motor.voltage_limit*0.7;
return u;
}
And this is a real picture. Could it be a connection mistake?
hello
first off, thanks for the amazing documentation on your cool project!! - great work!
looking to build something similar...
there is 1 thing i don't understand in your setup: the foc-shield, as i understand it, does only allow 1 encoder to be connected to it. you obviously need 2. now i know the shields could be stackable, but you don't seem to stack them...
how did you solve that? - repurposing free pins? is that then still compatible with the foc library?
thanks!
Hi, I bought the iPower Motor GM4108H-120T and the encoder AMT103 CUI you used, I found there is no way to mount the encoder to the motor. Any advices?
Hi,
I'm using AMT103 encoder for my project as well. I'm here to ask if anyone has the same issue as mine.
I checked the DIP switch of the encoder, it should be the expected PPR number as I set it with the documentation. But still, I cannot get the correct angle value from the sensor.
Hardware: Arduino Uno
When I keep the motor running and get the angle value from the encoder, the value also keeps increasing. But the value is way less than the real angle value. For instance, when the motor rotated half circle, the value I got from the encoder was only around 1 instead of 3.14.
The codes:
#include <SimpleFOC.h>
// digital pins
int encoder_pin_a = 3;
int encoder_pin_b = 2;
Encoder encoder = Encoder(encoder_pin_a, encoder_pin_b, 500);
void doA(){encoder.handleA();}
void doB(){encoder.handleB();}
void setup() {
// initialize encoder hardware
encoder.init();
// hardware interrupt enable
encoder.enableInterrupts(doA, doB);
// monitoring port
Serial.begin(9600);
Serial.println("Setup ready");
delay(1000);
}
void loop() {
encoder.update();
Serial.println(encoder.getAngle());
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.