<div dir="ltr"><div>Hi Murray,</div><div><br></div><div>The way I do it is that I have two PI loop (I only use integral and Proportional components) in the following cascade fashion. The Speed PI Loop receives the reference from the speed measurement engine. I do not have shaft encoders (SE), but since in 3 phase BLDC you need to commutate electronically, the speed is derived from this. With a SE it should be way easier. Anyway, the Speed PI gets this reference and then regulates against the command which is whatever speed you want to go to. I use Hz in electrical revolution, which is not the same as mechanical revolutions or RPM's. But it is just simple math, so at the end of the day it can be anything.</div><div><br></div><div>The trick is that the output of the Speed PI Loop is the Current PI reference. That is, the Speed PI drives the Current PI and the Current PI drives the motor. How so?</div><div><br></div><div>The Current PI regulates current. I measure current from the motor's tri phase inverter's SENSE resistor network. This current is "compared" against the current reference (which was generated by the Speed PI) and then the Current PI Loop's output is the duty cycle. The duty cycle is what drives the motor.<br><br></div><div>Seems like a good topic so I may write a blog posting with pictures to illustrate better all of these mechanisms. I am intrigued as to why you want to regulate power, as the only application where I have seen this technique employed is in vacuum cleaners. I mean, I have no argument for why you wouldn't want to use it on robots, but seems to me with robotics it may make more sense to do position loops.</div><div><br></div><div>Anyway, just wanted to share my thoughts as a means to hopefully steer the discussion in the right direction/directions ;-)</div><div><br></div><div>Best regards,</div><div><br></div><div>JIQ<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Apr 21, 2020 at 12:04 AM Murray Altheim via DPRGlist <<a href="mailto:dprglist@lists.dprg.org" target="_blank">dprglist@lists.dprg.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi all,<br>
<br>
Over the past week I've spent many an hour working on my Python-<br>
based PID controller, which is using a ThunderBorg motor controller<br>
under the hood to drive a quartet (left-right pairs) of OSEPP motors.<br>
<br>
I've kinda got something working, at least the PD part of it seems<br>
functional, but there's a big gaping hole where a certain part of<br>
the implementation is concerned: prior to PID I was "successfully"<br>
driving the robot based on an encoder-based velocity measurement,<br>
but there was no PID, and my recent attempts to create a PID<br>
controller using velocity have failed.<br>
<br>
I believe this is due to the fact that I was attempting to use the<br>
velocity measurement as the PID input to set the motor power. As I<br>
think David noted in his YouTube video, there isn't a direct relationship<br>
between motor power and velocity so this was bound to fail. I like<br>
fail as much as the next person, but success is nice too.<br>
<br>
So with that in mind I've gone back to a power-based PID controller,<br>
knowing I still have a certain mountain to climb.<br>
<br>
The question I now have is: how to add a velocity-based control to<br>
my robot? Do I come up with some mathematical relationship between<br>
velocity and motor power, or do I create a velocity-based PID<br>
controller **over top** of the power-based PID controller, i.e.,<br>
two layers of PID control?<br>
<br>
Much-simplified pseudo-code:<br>
<br>
   KP = some_constant<br>
   KI = some_constant<br>
   KD = some_constant<br>
<br>
   target_power = 0.5<br>
<br>
   while True:<br>
       current_power = motor.get_power()<br>
       error = target_power - current_power<br>
<br>
       k_diff = KP * error<br>
       i_diff = KI * sum_errors<br>
       d_diff = KD * last_error<br>
<br>
       output = k_diff + i_diff + d_diff<br>
       slewed_output = slew(output)<br>
       new_power = current_power + slewed_output<br>
       set_motor_power(new_power)<br>
<br>
       last_error = error<br>
       sum_errors += error<br>
<br>
So would I incorporate velocity into the above somehow, or build<br>
Yet Another PID controller for velocity (using roughly the same<br>
structure as above, but solely dealing with velocity) that calls<br>
the above power-based PID controller?<br>
<br>
I thought perhaps we could discuss this in tomorrow's Robot Builders<br>
Night Virtual get together... but an email discuss is also welcome,<br>
thanks!<br>
<br>
Cheers,<br>
<br>
Murray<br>
<br>
...........................................................................<br>
Murray Altheim <murray18 at altheim dot com>                       = =  ===<br>
<a href="http://www.altheim.com/murray/" rel="noreferrer" target="_blank">http://www.altheim.com/murray/</a>                                     ===  ===<br>
                                                                    = =  ===<br>
     In the evening<br>
     The rice leaves in the garden<br>
     Rustle in the autumn wind<br>
     That blows through my reed hut.<br>
            -- Minamoto no Tsunenobu<br>
<br>
_______________________________________________<br>
DPRGlist mailing list<br>
<a href="mailto:DPRGlist@lists.dprg.org" target="_blank">DPRGlist@lists.dprg.org</a><br>
<a href="http://lists.dprg.org/listinfo.cgi/dprglist-dprg.org" rel="noreferrer" target="_blank">http://lists.dprg.org/listinfo.cgi/dprglist-dprg.org</a><br>
</blockquote></div>