Regenerative Braking

Not true. Oscar close-sourced O-Drive more than 5 years ago.

Have you tried running SimpleFOC on O-Drive?

I believe the point here is to use SimpleFOC, not O-Drive.

O-Drive is using closed-source TI driver hardware supported passive braking (dissipating power through a high-power resistor). You cannot capture this to re-charge a battery, just heat up the environment. This is achieved via two MOSFETs, bulk capacitance and an external power resistor.

As you can see from the image there is absolutely no connection and means to re-charge the power supply, you only dump the extra BEMF and heat up a passive load.

Also, and here I’m quoting from memory because I don’t have time to source-check my claim, O-Drive also uses the TI DRV830? proprietary braking mechanism (here I could be wrong).

In any event the end-game here and goal of the exercise is to create a generic regen braking that could be implemented with discrete components and then enhance SimpleFOC to use it.

Please correct me if I’m wrong.

Cheers,
Valentine

Hello

I was just trying to help by sharing my thought if you don’t agree, that’s okay.

If that’s what you want to do, go for it. I was just sharing my thoughts.

Correct, but as you can see in the following url’s, the firmware and schematics until 3.5 are available (there is almost no difference between 3.5 and 3.6)
ODriveHardware/v3/v3.5docs at master ¡ odriverobotics/ODriveHardware ¡ GitHub
ODrive/Firmware at master ¡ odriverobotics/ODrive ¡ GitHub
So that’s why I said it’s open source, I will now correct myself by saying it was opensource so everything we need is there.

No, but I will try it soon, in the SimpleFOC examples that there is an ODrive file so I assumed someone else had done it.

I mean that you can use the ODrive regen software as a source to create the SimpleFOC regen software.

Incorrect, there is indeed no connection between the aux port (brake resistor connections) and the input, but you can choose if you use regen or not and if you use a braking resistor or not and it can even use both at once (sort of).

Regenerative breaking question - General - ODrive Community (odriverobotics.com)
How to enable regenerative breaking? - General - ODrive Community (odriverobotics.com)

DRV8301
DRV8301 Three-Phase Gate Driver With Dual Current Shunt Amplifiers and Buck Regulator datasheet (Rev. F) (ti.com)

Again I was just sharing my thought not trying to correct anything, I’m not an electronics expert. In my experience, I’ve noticed that I have better results when I use the knowledge and results that other people have instead of starting from scratch but if you prefer to start from scratch, go for it and I will be happy to see it working, I want the SimpleFOC project to keep growing in every way possible.

There are a lot of things that have to work together and as I said before, maybe it’s a good thing to reduce the amount of possible points of failure to get this working and expand the idea afterwads.

Cheers

Carelsbergh Stijn

I do agree, I was just explaining the obvious. A 3phase motor used as a boost converter is not proprietary.

Yes, I’ve read these comments long time ago, since I’m also an o-drive subscriber and follow closely all developments (in fact Oscar is literally my neighbor if that even makes any difference or sense). In case you want me to post it here, there we go:

The only thing the resistor does is protects the circuit from blowing up. Everything else has nothing to do with regen. You are on your own if you need regen braking.

The only thing you will see in the source code is the opening of the mosfets when the bus voltage goes above a threshold to dump the BEMF into the resistor. As simple as that. There is nothing else.

This is the entire schematics, o-drive only opens and closes the energy dump mosfets when the voltage or temperature exceed a threshold and dissipates it as heat.

If you open the source code you will see very simple logic there with PWM on pins PB10 and PB11 controlling the exhaust gate driver. There is no regeneration circuit or anything. You are confusing a circuit protection scheme with a regen braking scheme.

There is nothing in o-drive to help you with regen braking. This is a passive braking scheme to prevent the board from smoking when you suddenly try to lower the RPM of the motor and the voltage shoots up.

Cheers,
Valentine

Hello

That seems very weird to me, I’ve made multiple projets with ODrive but I’ve not used regen. Why are there settings like odrv0.config.max_regen_current if there is no regen?

Cheers

Carelsbergh Stijn

This is a protection feature, I guess. I am not an o-drive expert or anything but whatever you see is to protect the circuit from overloading by setting control/threshold points and dumping the excess into the power resistor. That’s only a guess on my part. O-Drive has a discord and a pretty good community forum board, you can go there and ask them.

Cheers,
Valentine

Hello

Weird that I’ve misunderstood that for so long.

Cheers

Carelsbergh Stijn

Unfortunately we are back to square 0.

I’m open to others suggesting any schematics or input.

The field is open. Who’s going to score a goal?

Cheers,
Valentine

Yeah, I think what I had in mind was plugging mode, and I had it backward. The battery and BEMF are both trying to push current in the same direction, so while the motor sees the sum of the voltages, the battery is in a sort of short circuit condition rather than being charged.

Studying Fig13 in that first PDF more closely, the goal is always to have 100% negative q-axis current like I thought, but at high speed the current lags so far behind voltage that you have to apply some positive q voltage to do it. Although I don’t quite understand what load angle and phase angle refer to. I only understand the forward driving case where they are equal (time delay between applying voltage and current flowing, due to inductance of the windings). But I can see that the positive q voltage is what makes the difference between regen and plugging. You have to have some voltage opposing the BEMF, but the BEMF has to be greater magnitude for current to flow toward the battery. If you want more braking torque than the BEMF can provide, you have to spend some energy (though the BEMF does still assist).

I also see now that the voltage boost you’re talking about happens as a result of PWMing the FETs to apply less than full battery voltage to the motor. Voltage x current is equal on both sides of the bridge, so while we normally get lower voltage and higher current on the motor side, in this reverse case we get lower current and higher voltage on the battery side.

Long story short, we should already be getting some regeneration when braking from high speed. And my proposed implementation in post #6 is still a viable way to stretch the regeneration zone without losing PID stability.

I’d like to chime in on the ODrive discussion:

While I agree that it is always good to look at other sources, including existing open source implementations, I don’t believe we would ever directly “copy” ODrive’s solution, or directly use their software.
They can be a source of inspiration, but when we get it working in SimpleFOC, the implementation will be a uniquely SimpleFOC one, just like everything else we have. I think this is not only a “moral obligation”, but also just a necessity due to us not being the same as ODrive.

I think the path to getting it done in SimpleFOC will be a longish one, since we need to put some extra functionality into the core first, get ADC support and current control to be really stable, and then come up with the scheme(s) we want to support for regeneration braking.

Presumably, there will be some “hacked up” implementations first, which will eventually evolve into the officially supported one.

No, I think this would require external modification of the parameters, i.e. an “outer control loop” that switches between modes/limits/set-points to achieve what you describe.
In the SimpleFOC control loop, you have a mode, e.g. closed loop velocity, or closed loop torque-current, and I don’t believe any of the modes would behave exactly in the way you describe.

Unless we introduce coasting/freewheeling while tracking the speed without interrupting the control loop, practical real-world use case regenerative braking will not be feasible. If we disable the drivers and turn off the mosfets, this would effectively use the body diodes to turn the motor into a generator. we can redirect the power to a regenerative loop and also switch over to any physical braking, and when we are done, we turn back the control loop with the new speed/position/torque and the control loop takes over.

That’s my thinking at the moment. I might be wrong.

Cheers,
Valentine

I agree with you completely. I think we’re at the moment still missing the more low level functionality of being able to drive the high and low sides separately, so I would try to introduce that as the initial low level building block needed.
Then we should think about introducing the needed parameters to the core algorithm to enable regeneration - I’m not 100% clear on that yet, but I think it will become more clear as we proceed. It will be something along the lines of being able to set the braking torque, charging voltage and so on.

1 Like

I think this would just be a matter of adding a flag to never apply torque in opposition to rotation. So if commanded velocity is greater than current velocity, apply torque. Else zero torque and coast down to whatever velocity is commanded, or up to whatever speed you get to rolling down a hill. Of course that runs the risk of spinning the motors faster than they can drive themselves. But if you’re going to switch to a separate regen circuit when in this coasting state and apply reverse torque that way, then you won’t get going too fast.

Coasting should already be fine in torque control mode. If target torque is set equal to the position of a gas pedal type input, then letting off the pedal will apply zero torque and that is coasting. In this case perhaps you could apply regen if speed is increasing despite lack of applied torque. i.e. maintain constant speed via regen until you get to the bottom of the hill, and then speed will start decreasing without any regen so it will revert to normal coasting.

I apologise for the long note but I think this may be useful (if not / you already know this then sorry) for some searching for info on this topic.

I have been doing some more digging into this topic mainly to improve my understanding but also to make sure we aren’t missing a trick.

Firstly, there are multiple ways of achieving regenerative braking with a brushless motor. As has already been mentioned above, if you simply turn a brushless motor using an external source, provided the rotational speed is high enough you will produce enough BEMF to move charge back into the power source. We know this is nearly never the case and so, really, what we are trying to do is achieve this same effect at lower rotational speeds and use the common driver circuit as a boost converter.

The most discussed strategies online seem to be around the more simple brushless motor control, “6 step commutation” and even within this control algorithm, there are multiple examples of how to achieve it. First there is the “Three Switch Strategy” (which I think has possibly been mentioned above already) where you quite simply switch the low side transistors at a pwm duty cycle between 0 and 100% to control the level of regeneration and braking torque. (Note: this happens no matter the commutation step and all other switches (high side) are left floating)

A second alternative method is “Full Bridge” (FYI the names are just as they were called in the document I was reading, not necessarily to true / given name). In this method all switches are used at least once, but for each commutation step only 1 phase (and one switch within that phase) is active, the rest are floating. (This one warrants an example: Step1 = PhaseA Low, phase B and C floating, step 2 = Phase C high, phase A and B floating…)

In addition to the above there is another strategy “Two switch” whereby you are essentially commutating in the reverse direction. I.e. Lets use an example…you are on a bike and you are commutating clockwise to get up a hill and now you are going back down the hill. If you start to commutate the motor in the anti-clockwise direction, this too will provide a positive charge to the battery. The only warning with this method is that it very quickly moves from regenerative braking to plugging as you increase the duty cycle.
This paper covers the above and also shows some graphs showing how each perform which are interesting A new electric braking system with energy regeneration for a BLDC motor driven electric vehicle - ScienceDirect

It is this method that got me thinking about the SimpleFOC algorithm, I was watching one of the videos showcasing the SimpleFOC working and when in “voltage” mode you are able to drive the motor forward or backward using positive or negative inputs (voltages) as if it were a DC motor. Surely this means that to an extent the library is already capable! Now I am aware that there is no formal “control” of the regeneration or power source protection etc. however this could mean we could use a “user control loop” to switch to the “voltage” mode and start playing around with this.

Now as you will see when reviewing the paper I have linked above, the most simple to implement also seems to come up on top for capability as well, the “Three Switch Strategy”. I think @runger has already stated that the SimpleFOC library currently only seems to control 3 PWM outputs?? and thus it cannot leave a phase floating which is the main issue stopping the first 2 options being used.

Just to finish this off as I saw a note about coasting come in as I was writing this.
@dekutree64 I completely agree, surely there is a torque setting which would activate coasting already in the library. Again, referring back to the 6 step commutation scheme, to coast it seems you essentially commutate based on the step but the two active phases are both Low rather than one being high and one being low.

I am now the frustrated kid sitting at home waiting for my DRV8301 driver module and motor to turn up but perhaps someone here already has a test set up?

2 Likes

Probably shooting in the dark but here is my “coasting regen” scheme. I will make the analogy with a gas-powered car.

We put the motor in voltage/velocity mode. We push on the gas pedal. The car goes faster to V1.

We release the gas pedal to some degree. Releasing the gas pedal is same as braking but with a different deceleration profile. The car needs to slow from V1 to V2. We have a pre-determined deceleration profile and we need to decelerate the car.

  1. FOC goes into coasting mode, following the wheels but completely disconnecting the mosfets.
  2. A switch cuts over from battery power circuit to regen circuit. By a switch I mean we literally redirect the bus to a completely different regenerative circuit.
  3. The regenerative circuit will contain the battery management. We then redirect the voltage to this circuit which will use a mosfet chopper to skim some and move to a rectifier/DC regulator/buck/boost converter and produce the correct voltage to feed the battery management/charging. The chopper is controlled by the gas pedal and the regen stays open as long as there is a negative delta V and the deceleration profile has not reached the desired speed.
  4. The desired lower speed is reached. The circuit switches over to FOC control, we disconnect the regen circuit.

The same happens if the user moves the foot from gas to brake but we are using a more aggressive deceleration profile, may be combined with a power resistor for dissipation (we do not want to overcharge the battery) as well as switching over to conventional braking if needed, which will be decided by the larger outer logic ran on a second MCU which will also monitor things like traction, temperature, battery level, user pedal work, vehicle telemetry, etc. From implementation point of view in fact it doesn’t matter if we decelerate with the gas pedal or brake.

The more I think, the more I like the coast/disconnect/regen with an external MCU. It’s very generic, and there is no mucking with FOC, just put it in coasting mode, and we can design an external regen circuit as a separate module.

Also, since coasting must be able to be turned on/off momentarily, we probably will need do designate an optional “coasting pin”. If the pin is low, we just motor on. If the pin is high, we immediately switch to coasting. This will introduce absolutely minimal overheat to the FOC loop.

OK, now it’s everyone’s turn to smash on my design. Come on!

Cheers,
Valentine

1 Like

Would this switch be placed inbetween the normal 6 MOSFETs and the 3 motor wires? Or between the battery and the normal 6 MOSFETs? The latter case is what I had in mind, and I think I was wrong about using regular torque mode with zero setpoint. The MOSFETs will have to be commutated like usual so a DC voltage is presented to the regen circuit, else it would have nothing to work with.

Between the power supply and the mosfets. The driver won’t even know there is no power going into the mosfet rail. The external regenerative circuit will make sure the voltage is not exceeded to damage the mosfets.

This will keep the driver as generic as possible.

Right, we are on the same page then.

Does the regen circuit really need a separate MOSFET chopper? If my thinking is correct that the regular 6 MOSFETs will have to be commutated to provide a voltage to the regen circuit, then they might as well do the chopping while they’re at it. That would also allow using the regular current sense to control the braking torque. Basically the battery would be replaced by a boost converter which should hopefully appear as a 0V power supply (not fighting back against the BEMF at all so we can get regeneration at lower speed than what I described in post 29).

Hopefully the FOC current control loop will still function when it doesn’t have a proper power supply.

If all the mosfets are down, my understanding is that the motor and body diodes form a generator. You can then syphon off power to the regen which will make the motor work, and the work will slow the motor down. This way there is no real change to the SimpleFOC algorithm, no mosfets co commutate.

Correct, the current sense will still work, since it’s between the motor and mosfets. However, I’m thinking to place a high-side or low-side current sensing to the input itself to make the regen completely independent of the driver.

That’s my understanding too.

Oh, that’s easily solvable. There will be an auxiliary power connection to the driver board to keep the control running when the power is disconnected. I already solved this with a galvanic isolation power supply and optoisolated drivers and current sensor. It’s nasty and complicated and expensive but isolates completely the driver from the mosfets. Essentially you end up with two power supplies, one dirty from the battery being charged, and one clean from the isolated supply to the control MCU. You could probably get away with only one, and get clean auxiliary power from the regen circuit and have a switch on the driver to choose if you want to use the mosfet rail (for no regen cases) or the auxiliary power supply for regen / rail disconnect cases.

I don’t want to smash on your design especially as I cannot claim to be an expert in circuit design. However I don’t fully understand the need for the second MCU and second boost circuit. In terms of the boost circuit, there already is one so it seems this would just be doubling up for no reason. In terms of the MCU, surely at worst you would just disable the library to gain control over timers and pwm etc. and re-initiate it once we are done, but my solution I will share shortly potentially negates the need for this.

I agree with having a 7th mosfet to link to a break resistor, more than that I don’t think is necessary and here is why. Unless you are controlling something with a very large mass (a car for example) you are rarely going to have the torque and speed to produce huge amounts of regenerative power. (I have seen videos of people recovering ~5% of power used to get up to speed when then stopping with regen only). The only time I think you would ever even need to disperse power is if you happened to fully charge your battery and happened to be at the top of a massive hill and used no energy before heading down it. As anything is possible, a break resistor circuit needs to be there.

I want to try to steer this back to the library rather than the circuit design as that is what this forum is related to. Due to the number of applications and circuit designs that could be used I think it is important to distinguish that the control of regen be handles by the user application and the SimpleFOC library facilitate this.

From what @runger has stated, the main hurdles are:

  1. Additional ADC requirement to check the power supply voltage so we can make judgment on where to put the energy regenerated. Currently there is risk of the user application interfering with the library if we attempt to use one of the ADCs / channels.
    My proposal as you will see below is that the library would handle the gathering of the data so that it has control over timing to get round this. This data is then provided to the user application rather than used by the library in any control algorithm. (i.e. the user application acts based on the data gathered and provided by the library).

  2. The library currently does not control the 6 mosfets individually (although I haven’t quite got my head around exactly what is happening with the “BLDCDriver6PWM”.
    Currently from what I can see the library is always using the built in PWM functionality of the various MCUs. A potential for controlling the 6 mosfets is to use simple timers and switch the pin states manually within them to provide greater control over them.

  3. Control over a 7th mosfet for break resistor / separate circuit. This may be MCU dependant based on how many timers / pwm pins there are. May restrict to high cost MCUs.

Below shows a high level pseudo code implementation. The goal for me is to get some direction for the library in terms of regeneration so that I can help / contribute to it. So please let me know what you think. @Valentine I think this would work with your circuit design also. The code below will me shown within an Arduino sketch to keep it simple to understand. Just as a note to anyone scanning this in the future, don’t copy this code as it won’t work and is not an example of how the library currently works. Also this is obviously not a final implementation so no doubt will have holes in…it is the concept I am trying to portray.

//APPLICATION LEVEL CODE
void setup()
{
 //Usual SimpleFOC setup including sensors(hall/encoder), 
//current sensing, drivers and motor linking etc. 
//as well as control type (e.g. torque control or speed control)

//In addition to the above link power supply voltage reading
motor.linkPowerSupplyADC(adcNum);

//In addition link break resistor / alternate circuit mosfet
motor.linkAdditionalMosfet(pin);

//In addition select a regen strategy
motor.regenStrategy(REGEN_STRATEGY_3_SWITCH);

//Complete the initialisation
motor.init();
motor.initFOC();
}

void loop()
{

//Application level control
target = application.getUserTarget();
if(target = 0){
  motor.state = coasting;
}

//Application level regen control (just an example)
regen = application.getUserRegen();
if(regen){
  motor.state = regen;
  motor.regenDuty = application.getUserRegenDuty();
}else if (motor.state != coasting){
  motor.state = normal;
}

//Usual loop
motor.loopFOC();


//Usual control
motor.move(target);

}


//HIGH LEVEL LIBRARY CODE
Motor::loopFOC()
{
   switch(motorState){
   case normal:
     switch(controller){
     case torque:
        .....
        break;
     case speed:
        .....
        break;
      case ....
     }

  case coast:
    //control the relevant mosfets for coasting
    break;

  case regen:
     switch(regenStrategy){
        case REGEN_STRATEGY_3_SWITCH:
          //control the relevant mosfets for 3 switch regen
          break;

        case REGEN_FOC:
          //We discussed above this could work if you just switch to voltage
         // control and use a negative voltage
         controller = voltageControl;
         target = regenDuty;

       case ....
     }
  }
}

I hope what the above shows is that my take is that the library should be able to facilitate regeneration and coasting but not implement the control strategy. This should be handled by the application level.
If this is agreed and the above indicates a vague direction how can I help start contributing towards this. Alternatively, if there is another direction, what is it and I am willing to support that as well.