I posted a question / prompt for discussion on the discord but it was pointed out that this would be better as it would be easier / more permanent for people to find.
In short the question was around what was missing from the current SimpleFOC library to enable regenerative braking and therefore what actions would need to be taken / are being taken to work on the implementation.
I had a reply to kick things off which I will put below. Hopefully this thread will prompt some positive discussion to help bring it forward and get around some of the hurdles mentioned:
“In terms of how to implement it, there are some building blocks missing - although we have been progressing on these:
you need good, reliable current sensing - we have been working on this, and it works for several MCUs, but I would say we aren’t quite happy yet with the stability, and on some MCU types it is not yet supported.
You would need to be able to add additional channels of current sensing to measure voltage, or bus current.
We currently don’t support this well, but we are working on it. When you run the current sensing in low-side configurations, the PWM and ADC need to be closely linked, and the code for this gets complex (and is very MCU dependent). So at the moment it usually does not work to use the ADC for other purposes than the phase currents.
You would need the ability to control additional FETs (at least if you have to dump the energy, perhaps not if you can charge a battery).
In this regard we have recently introduced 1-PWM code in some of the PWM drivers… but not all of them are supported at the moment.”
As I understand it, there are really three separate jobs:
The motor controller naturally does regenerative braking any time torque is applied in opposition to the direction of rotation (e.g. target velocity set to 0 or position control decelerating toward target). Bus voltage rises above power supply voltage, and if the power supply is a battery, current flows into it until the voltage drops back down. If not, the power supply dies.
If you want to boost/buck the voltage to match the ideal battery charging voltage and/or balance charge individual cells, that should be done by a battery management system (BMS) rather than the motor controller.
And if you want to waste the generated energy to protect a non-rechargeable power supply, you can have a separate device switch on a resistor if the bus voltage rises above a threshold Protect power supply against BEMF
ODrive integrates two motor controllers and one energy waster into a single device (although the brake resistor itself is connected separately), but that’s only good for non-rechargeable power supplies. The only time a battery needs to waste energy is if it’s already at full charge, and the BMS is what will make that decision. It seems awkward for the BMS to tell the motor controller to switch on its integrated energy waster, so it would be better to integrate the energy waster into the BMS, or have the BMS switch on a standalone energy waster.
So it may make more sense to create a separate library for energy wasters. If you have hardware like ODrive and a non-rechargeable power supply, use SimpleFOC and SimpleEnergyWaster in the same program. And if you’re making a BMS with integrated energy waster, use SimpleBMS and SimpleEnergyWaster in the same program Unless the energy waster takes so little code that it’s easier to just implement it in both SimpleFOC and the hypothetical BMS library.
@runger what is your intention for the strategy to initiate regeneration? Would it be to target a negative torque / current target?
What would happen with the current implementation if you were to set the target to a negative current when in torque control with current sense? Would it currently set the duty cycle to 0 on all phases (I.e negative values aren’t valid?)
Thanks for the link! I’ve been looking for an article like this for a long time. Also nice to hear that my idea of estimating the true rotor angle by interpolating between hall states by the motor speed has been done successfully
I would hope that the current limit is enforced on negative current the same as on positive current. If not, then make it so and we can use it to optimize regen.
First calculate the speed at which the current limit is the maximum regen power point. Above that speed, we’re capturing all the energy we can without overheating, so no change needed. Below that speed, it would be better to apply less brake so more energy is captured. But if maximum regen is enforced at very low speed, the PID won’t be able to get enough torque to hit its target. So we need to take some relatively low RPM and calculate the maximum regen current there, and if(RPM < lowRPM) currentLimit = lowLimit, else if(RPM > highRPM) currentLimit = highLimit, else currentLimit = interpolate
To answer on the control, I think it is application dependent. Consider a skateboard - if you automatically initiate braking, I think there will be situations where the rider will be unexpectedly thrown from the board… so I think actual braking would have to be under the control of the user in that application, i.e. related to the set-point rather than just the currents.
In other situations, you might want to limit the maximum speed, and initiate braking when exceeding it, e.g. when a vehicle is traveling downhill.
I think deku summarized it quite well. You’d need current and voltage sensing, and if you can’t “always charge the battery”, a way to dump excess energy (brake resistance).
There are also options to dump the energy into the motor (by setting D-axis current), but of course this will heat the motor which is usually not what you want, hence the external FET and brake resistor.
Generally speaking, I think you will usually want to avoid situations where the BEMF voltage rises above the bus voltage. If this happens you won’t be able to control the motor. So generally, the bus voltage should be above the motor’s “generator voltage” at the speeds you intend to work with.
But for regeneration this then means that the voltage generated by the motor is too low to charge the battery. So you have to boost it up.
You can use the high side FETs as the switching element for this “boost converter”, with the motor as the inductor. The paper you link to actually explains it quite nicely.
Deku’s suggestion of integrating a BMS also makes sense, to protect the battery and control the decision of whether to charge or to dump the energy…
I totally agree with all that has been said. Especially that the application level code should be “controlling” the regeneration / regenerative braking initiation and level.
I also agree there will be times where we need a way to dump excess energy.
I suppose my question is how will the lower level change to make this work and how with the application level interact with SimpleFOC
Really? I was under the impression that the bus voltage will always rise when applied in opposition to the motor rotation, and thus will be above the battery voltage and charge it. And the problem was the opposite, that if you apply too much opposition you’ll get excessively high voltage and current and heat and potentially explode capacitors.
Hmm, in that case it actually would make sense to integrate the BMS functionality into the motor controller and firmware… but can you simultaneously provide a controlled braking torque and boost the bus voltage to the specific optimal charging value? I’ll keep reading that paper.
My proposed implementation in post #6 could be as simple as calling an enable function and letting the low RPM cutoff default to some percent of max RPM. But I was thinking of position control mode since that’s what I need (flapping wing aircraft, so lots of energy to be recycled in the constant direction reversals). You could probably use it with wheeled vehicles too, because it provides a smooth decrease in braking power as the RPM drops, and the low RPM cutoff still has to provide enough braking power to decelerate usefully. But it may be better to make it entirely user controlled, with some feedback of where you are in relation to the maximum regen power so you can adjust your braking intensity to optimize it.
They just need a way to talk. Most batterie’s (Lithium based) already has BMS with balancing circuit. All that balancing stuff is not in the S_FOC domain.
Regarding charging voltage vs rpm vs windings etc. it all depends. IMO the ideal system does not go above battery voltage by BEMF, that would trigger the BMS safety, so charging would not take place, I guess it’s about finding the right balance…
Agree!! The application needs to know the full charge voltage and monitor / control to that.
I am not sure the circuit needs to be as complex as that above. In most cases just using the 6 FETs you should be able to control the braking torque and the power back to the battery.
I agree there needs to be a safety measure be it BMS or brake resistor and additional switch.
Braking torque would likely be a function of user input ( be it on/off or via a variable amount).
Power back to the battery would be a function of user input AND voltage level management.
And I am very sure you cannot achieve that with a simple circuit.
Unlike motor control, active braking with battery regen is a really complex topic, and a closely guarded commercial secret. The fact that you cannot find ANY online schematics and only high-level academic descriptions (and/or block schematics) is very obvious.
I challenge anyone here to make this work as simple as possible and demonstrate it. You don’t need to make it high power, just show that it works on a simple gimbal motor with any cheap driver.
To make matters even more complex, real-life braking also involves mechanical braking at the last stage to bring the vehicle to complete stop. So the complete solution must also include active/regen braking to mechanical braking switch/cut over.
I will hopefully be testing in a few weeks once my parts arrive.
This is the exact point of the thread, let’s see what we can come up with. I will keep you posted with what I find.
I want to point out that I am aware that the circuit without regenerative braking is not simple. I was merely saying that I don’t believe much more is needed to have a basic regen set up working.
I will be interested to see what we all find as we dig into this.
Well, obviously we are trying to make this work together. I’ll dig, too, as this is also of interest to me. The fact that no regen braking schematics in the wild exists, that is viable enough to commit to copper and test is extremely challenging and really piqued my curiosity. I feel like searching for that notorious unicorn.
The paper you link actually describes it quite well - and they’re doing it with just the motor FETs. So I think it should be possible.
But as Valentine indicates, it remains to be seen how “easy” it really is, and how well it really works with such a simple circuit.
For sure it will be an “area of research” as far as SimpleFOC is concerned for a little while, and if you want a quick solution that just works, you’re probably better off paying more for VESC or ODrive hardware…
But if you’re interested in making it work as part of our open source effort here, I am sure there will be many people who will be grateful for it, and it will certainly be interesting to see where we get…
I’d prefer to keep mechanical braking out of it - I don’t see a real connection to the SimpleFOC library for that. We will provide ways to set the braking torque, and you can always stop the motor by setting the set-point to 0 velocity, at which point the motor will oppose movement. If you want mechanical brakes then this can be accommodated in the outer control loops, I don’t think we need to consider it in the library.
I disagree with this - finding battery packs that do balancing, and indeed finding charging ICs that do balancing (although some exist) is actually rare. Maybe its different in the eBike and EV space, but in terms of hobbyist batteries like for RC cars or IoT devices, balancing is quite rare.
Where I agree with you is that balancing is out of scope for SimpleFOC.
Funny, I had the same misconception but this is not how it works. The motor has a natural BEMF voltage depending on its physical properties and the speed of rotation. This is the voltage it “generates” when you spin it using external force. If you also apply a bus voltage, the BEMF opposes this, and the motor effectively “sees the difference”.
Another question in my mind for implementing this, is what switching frequency you need to make the motor an effective boost converter. Our motor PWM is typically around 20-60kHz, but buck or boost converters usually switch much faster than this, more like 250kHz-2MHz.
I wonder if we will have to change the PWM frequency when in braking mode.
Question: Does SimpleFOC currenyl support “coasting” that is, let’s say, the motor spins at 10rps, then we slowly decrease torque until we “disconnect” the voltage however we keep following the sensor and then we “connect” back the voltage and slowly increase the torque but with the faster, say 15rps because downhill we accelerated due to gravity. Example would be climbing a hill, cresting, going downhill, then slowly increase the torque when we hit the flat.
My thinking is, when we get to “coasting” and go downhill, we can disconnect the power supply and redirect to a charging circuit, and then when we hit the throttle, we disconnect the charging circuit and connect back the voltage then the driver goes into “driving” mode.
That would be the simplest and easiest to implement “dumb” regen. The SimpleFOC will keep following the sensor to be able to go back into driving mode with the whatever rps is at that point. The switching to regen will be controlled by a switch, so when the user hits the brake, since SimpleFOC is in “disconnect” mode, wouldn’t even know the power supply is not connected anymore, and we can do whatever we want during disconnect as long as the algorithm keeps track of the sensor to jump back in.
A few months ago I was thinking about this too but I didn’t do anything with the thoughts I had because I had higher priorities. Now I can post them here and maybe there is something you can do with it.
I was thinking maybe it’s a good idea to not reinvent the wheel and take the things other people have learned but how can you do that? Well, you need a good source, but actually there is one, ODrive. Odrive is designed to handle regen braking and has opensource software and that’s not where the good news ends, ODrive is also compatible with SimpleFOC.
Conclusion: ODrive had the hardware, ODrive has the software, ODrive is already compatible with SimpleFOC.
If you ask me, that seems like a good place to start because there are less possible points of failure.
The boost converter is already invented. Thats PWM to the LOW side FETs while the HIGH side FETs are off. 6 pin PWM is mandatory for regen.
Basically we create lots of consecutive spikes to charge the capacitors to a desired voltage. When that voltage is charging voltage, current starts to run into the battery.
Ok, so in order to implement this to SimpleFoc we would need to know the cap / bus voltage. This we would need when turning the motor, without battery to the desired max rpm, in order to make sure ( calibration ) that we are boosting correctly. I believe for it to make sense for SimpleFoc, the best approach is to focus on a calibration method that will work for all future 6pwm controllers.