isabellesimova / HoverboardFirmware

50 stars 24 forks source link

PID control #4

Open isabellesimova opened 6 years ago

isabellesimova commented 6 years ago

<Asked via a youtube comment on this video> I need some answer about that wheels, if you wanna turn 100 times for both whee lvia command "L20,R20" they are not turning same times.. ( one wheel turning 100 times other turning 101 or 99 ) your code does not have PID control for error(spin) correction . how you did solve that problem ? do you think add pid controller code to your project?

isabellesimova commented 6 years ago

I currently do have one in the works but don't have a timeline for getting it finished. If you'd like, you're welcome to make a PR and I'd be happy to look at it!

EmerickH commented 6 years ago

Hello, I'm trying to achieve the same thing here (changes) to get a position control instead of speed, my actual code is almost working but too slow because of this: https://github.com/EmerickH/HoverboardFirmware/blob/position/src/motor.c#L716 and because I use actual speed control functions, it would be better to use directly pwm control but I don't know exactly how to do it. A little help would be very nice... (absolute position feedback is working well)

EDIT: @isabellesimova Have you already started something? Can you share it?

Thank you

btsimonh commented 6 years ago

So glad I found this repo.... was working hard on NiklasFauth/Hoverboard-Board-Hack, yet yearning for sinusoidal control and position control. One question I need to think about is how to control the position and speed; i.e. it's not just a matter of demanding a position, you need to demand a position, and a timescale over which you want to achieve it, along with possibly a requested acceleration profile? - e.g. you may want to move the wheel by 50cm,, get there in 2s, and with a terminal speed of 0.3m/s (because you are going to ask it to go somewhere else, and don't want to stop). How would we specify this? I'm now torn between starting over here, and porting in the extras I've done (mainly software serial, protocol, and platform.io), or backporting your motor.c to there :). @isabellesimova - How are you with pull requests?

isabellesimova commented 6 years ago

Hi @EmerickH! Sorry it's taken a while for me to respond - I just got the chance to look through your code. I'm not too sure about a few things you're asking 1) Are you saying the Speed_ISR callback function takes too long so it doesn't work? 2) And it looks like you're using PWM like this:

motor_pwm(motor, ComputePID(motor, motor->absposition));

which basically directly controls the pwm? Do you mean setting it outside of the callback loop? If you can clarify, I think I'll have a better chance of helping you :)

I do have a branch and I'll push it when I get the chance - hopefully tomorrow!

isabellesimova commented 6 years ago

Hi @btsimonh! That's a good question -- definitely something to think about - and I think a problem that can be solved incrementally - first start with specifying distance and getting it to work, than adding a time constraint, etc. What are your thoughts? And I'm very happy to look at pull requests and merge them in :)

EmerickH commented 6 years ago

Hi @isabellesimova,

  1. I think my ComputePID function is slowing the Speed_ISR callback (also my absolute position code but it is acceptable), high speeds are not going to work...
  2. Computing of the PID must be done at regular intervals and not at an interval determined by speed.

So I think the best would be to compute PID in a separate and regular timer but I don't know how to do it...

Also, why can't we go at a speed under 11rpm ? (turning faster)

@btsimonh Yes of course, I'll keep speed so you will have to specify "go at this position with this speed" (wich is the same as giving a timestamp theorically)

EDIT: my last code's PID is working! Need to put PID on independent timer, actually Serial is not working well (randomly stopping), I think it is because of that.

btsimonh commented 6 years ago

I've now got positional control in my fork of the other repo working passably well. I'd just love to get rid of the grind, but my sinusoidal hack (stolen from here) just made the grind worse. But it's nice to be able to tell the board to stay at a position, and then when you push it a bit, it fights and returns :). want to achieve this, but actually not sure it's possible - I think you need some offset mass for that. and my hoverboard is very well balanced around the axles.might try it with an old HP printer on board :).

isabellesimova commented 6 years ago

@EmerickH One thing you can do to do something every so often is to call something from the main function, like how the TX / RX is working in the main for loop, and set some variable based off your calculation. The 11rpm is currently set to be the lowest speed right now because of the timer limitations, based on the maximum value it can count up to.

@btsimonh I've also had problems without a weight on my bot, especially transitioning from my trapezoidal to sinusoidal control.

isabellesimova commented 6 years ago

@EmerickH pushed my PID control code -- I think it had some problems though - it's differential pid control to keep the wheels at the desired ratio though, and not quite singular pid wheel control.

@btsimonh (just tagging you so you're aware) I also reimplemented the sinusoidal to do something closer to the original firmware - using the ST timer complementary pwm function (less likely to blow fets because ST handles toggling the two fets at the same time + deadtime). When I wrote it a few months back, it worked fantastically and was very quiet, but my current version seems to be a little bit less cooperative and is quite noisy, so I'll see if I can figure out what's up. I've also been working to rewrite it again to just do sinusoidal the whole way through, including startup (I think I can start more smoothly this way without any weird jerks) but I blew my board, so waiting for another one to come in.

Neither of the branches are in a state that's reliable for me to feel comfortable merging in -- if you have the chance to improve and make it reliable, that'd be wonderful - otherwise, it may be a while before I get to it.

btsimonh commented 6 years ago

If you end up with the YST board, lookout for three pads on the edge, marked AO40 AO44 and AO28 :) very conveniently easy to solder to. Just ran down the dog at uncontrolled speed with a heavy weight on board!

btsimonh commented 6 years ago

I've been thinking on this for some time; The 'original' NiklasFauth firmware sets all of it's pwms in a seemingly disconnected tight timer (a DMA result from ADC?). Seems wrong, but works fairly well over a certain speed. But the 'drive' into it is not 'Speed' as the firmware calls it, but is actually 'voltage' (which equates to 'power' in it's most simplistic concept?). We can get absolute position (and speed) from the HALL changes; this works well, as long as you are going fast enough to have a hall change. And for speed control, using this as the feedback for a PID loop works; as long as you are over a certain speed. Note also that direct feed to pwm from the original sensor angles gives an almost perfect reproduction of 'hoverboard' functionality. In many places, it states that positional control requires a switch of algorithm as the speed goes below a certain value. So; basically, when we're going REALLY slow, we need to run a timer which controls where we WANT the wheel to be, and use sinusoidal output with enough current to make sure the wheel IS where we want it to be. When we are going faster, the hall sensors reveal our position, and we need to control BOTH the phase and power (voltage) of the sinusoidal output to adjust our speed/position. Seems neither firmware currently uses the current feedback that we have available.... what can these value tell us? p.s. i'm going to play with this as generic PID code.

btsimonh commented 6 years ago

p.s. https://github.com/btsimonh/hoverboard-firmware-hack/tree/pidcontrol NiklasFauth based firmware which implements PID control for speed and position. Not working for speeds < 40mm/s, and PID parameters are only very loosely tuned (big dead zone in position), but it works quite sweetly.

isabellesimova commented 6 years ago

Nice! My new board came in today so when I get the chance I'm going to get the new sinusoidal version working (with fewer timers used and smoother startup), and then once that's good, I'll look into PID.

btsimonh commented 6 years ago

what board did you end up with?

EmerickH commented 6 years ago

Just to help: https://github.com/pekkaroi/bldc-drive/tree/master/firmware/src is a good project to help

btsimonh commented 6 years ago

have either of you played with steady state drive of the wheels; i.e. putting a static PWM into the two or three phases to control wheel position? at very low speed or stopped?

EmerickH commented 5 years ago

It seems that the example I found is not doing phase commutation in sinusoïdal mode, maybe we need to do the same thing in our code? https://github.com/pekkaroi/bldc-drive/blob/master/firmware/src/pwm.c#L212

ivliev123 commented 5 years ago

tell me in which file and where I can get the speed from the encoders?

btsimonh commented 5 years ago

hi @ivliev123, in my repo: https://github.com/btsimonh/hoverboard-firmware-hack/tree/pidcontrol I read the position by enabling interrupts from all the HALL lines. (see bldc.c) In @isabellesimova repo, in the 'pid' branch, she does a similar thing, populating motor->this_hall_count - but I've not tried this branch yet, so can't comment further :).

ivliev123 commented 5 years ago

how can i send this speed to uart?