EFeru / hoverboard-firmware-hack-FOC

With Field Oriented Control (FOC)
GNU General Public License v3.0
1.13k stars 938 forks source link

RPM precision #254

Open landrisan opened 2 years ago

landrisan commented 2 years ago

Hello, I am using the system in an industrial machine, USART driven and motor controled FOC in SPD_MODE, the commands to the howerboard were send by ESP8266 wich is driven by a linux app using UDP protocol. My new problem is the precision of the RPM, is it possible with decimals? Because I have to do an electronic gear, so in some cases just integers are not enough. Also, I noticed that after setting up the speed at 50 let's say, the reported speed is variable at +-2RPM. With no load. Can thys be done more precise? I did some tuning at cf_nKp and cf_nKi but the same fluctuation, some response time is changed but fluctuation the same. Back to default. If you have any ideea, will be greatfull.

EFeru commented 2 years ago

Hi @landrisan ,

The RPM can be outputed with more precision directly in fixed point (exactly as it is used internally). Meaning at your side you have to something like this:

float rpm = rpm_fixed_point / 2^4;

Then you have a resolution of 0.0625 rpm Below is an image from the model showing the rpm is truncated to an int which make it loose some precision outside FOC control. image

However, I believe we won't get much more precision due to the fact the speed is estimated based on the Hall sensors which is not a very precise way to get an accurate speed measurement. Internally FOC uses the more precise rpm for control already. We can apply more filtering but then lag is introduced, then slow response, etc. In conclusion I am afraid there is not much we can do.

landrisan commented 2 years ago

Ok, I understand. But, if I use an optical encoder atached to the motor and TRQ_MODE and PWM as input method, and on the external controller, run a PID based control software, the response will be fast enough to get a real servo system? I am asking because you know better the hardware and the software. Of course, I can just try and see what is happening, but building the mechanical adaptor may take some time, is much easy to just ask.. :)

EFeru commented 2 years ago

That of course you can do and should give you a more accurate speed measurement. I don't see reasons why it wouldn't work. The comands are send fast enough for a speed loop. So i say give it a try.

landrisan commented 2 years ago

@EFeru Ok, I will try thys. I have read in a post that the firmware itself can read external encoder. Is not clear for me where thys encoder should be wired. I intend to use optical encoder, pulse output, with A and B outputs(can read the direction as well), and 480ppr resolution. Is it possible to help me with some informations about thys? I leave you my e-mail address(liviu21_sv@yahoo.com) just in case of some large files. I am ready to make a donation if you cand help me with thys specific task.

Candas1 commented 2 years ago

Hi,

I can reply and @EFeru can comment if I am wrong. Emanuel made an input available in the model for mechanical angle from an external encoder: https://github.com/EFeru/hoverboard-firmware-hack-FOC/blob/4770b13b2cfc3a952f17f6217ec254639d10a0f5/Src/bldc.c#L188

But there is no code for reading the angle from the encoder and feeding the model. This piece would be very specific to the encoder you use, and it's interface (SPI, I2C, ....)

What is the model of encoder you are using ?

landrisan commented 2 years ago

@Candas1 The encoder is this one: https://www.ebay.com/itm/202665032220 I did the modification indicated, at line 188 in bldc. c and something in main.c but of corse, with the encoder not connected, did't know where. The motors stalled, completly, absolutly freezed, not even the 4 degree angle oscilation when 0 speed is set in SPD_MODE. But after a few secconds, they where released, I think because of the current limit(or temp limit), because the whole system became warm.

Candas1 commented 2 years ago

I am saying there is no code to read encoder angle, of course it will not work. And the code to read encoder angle would be different depending on which encoder you are using.

EFeru commented 2 years ago

The thing is it won't work out of the box, because of initial position. The sensor needs to indicate the degrees such that the controllers fires the phases correctly. So it requires some calibration, either by mechanically position the sensor or software 0 point calibration (or both). Needs some thinking.

EFeru commented 2 years ago

Also, yes I totally agree with @Candas1

Candas1 commented 2 years ago

It seems those encoders output pulses in 2 phases when the wheel moves. https://howtomechatronics.com/tutorials/arduino/rotary-encoder-works-use-arduino/

It's incremental so an interrupt would have to capture the rising/falling edges, figure out the direction, and increase/decrease the angle/position.

Or an easier way would be to just check both phases with digital inputs in bldc.c and do the calculation, but I am wondering if you would be missing some pulses.

But @landrisan this you would have to code. Are you controlling 2 motors with one mainboard ?

landrisan commented 2 years ago

Yes, both motors, one mainboard. I don't think that the hall sensors should be replaced. They must stay and give informations for comutating phases. The optical encoder should be used just for more precise speed and for position control, on different IO pins. The ideea was not to get out of the hall sensors, just add some others more precise. Anyway, I noticed that, correct me if I do a mistake, the hall sensors give 4 degree resolution(90 pulses per rotation). When 0 speed, I can move the wheel 4 pulses back and forth with no feedback. The feedback just appear only after the 4-th pulse. If I can reduce this to one, will be better after all. I used a modified firmware, that can provide position, I reduced the time for serial feedback from 10ms to 5ms and I get a resonable position feedback. I will do a software in ESP8266 that will read the position provided via UART and control the mainboard via UART, with PID. Hope to get a better position/speed control. If still not good enough, will just replace the position feedback from the mainboard with an external encoder. Thank you for your answers, are verry helpfull, ideas can hide everywhere :)

tomekjaskiewicz commented 2 years ago

I've been following this discussion, because it very closely relates to my project where I'd like to control my vehicle from a coupled microcontroller with as much precision as possible, e.g. drive forward 1 meter, turn 90 degrees. Does rtU_Left.a_mechAngle allow control similar to a stepper motor? If so, I'd assume rtU_Left.r_inpTgt needs to be set to 0 then? Is there then also a way to control torque/speed for reaching the set angle? (i.e. through exposing another RT_model parameter?)

Candas1 commented 2 years ago

I've been following this discussion, because it very closely relates to my project where I'd like to control my vehicle from a coupled microcontroller with as much precision as possible, e.g. drive forward 1 meter, turn 90 degrees. Does rtU_Left.a_mechAngle allow control similar to a stepper motor? If so, I'd assume rtU_Left.r_inpTgt needs to be set to 0 then? Is there then also a way to control torque/speed for reaching the set angle? (i.e. through exposing another RT_model parameter?)

There is a fork meant to be used with ROS, it's linked in the page of the repository.

landrisan commented 2 years ago

@tomekjaskiewicz There is a variant of the firmware that returns via UART the motor position, 90 steps/rev and the maximum allowed distance is 9000steps. But, with an external microcontroller you can capture each step, count it internally and make a decision regarding the distance. On my project, to eliminate the need of an other encoder, I modified the firmware to give position feedback at evey 1ms. The position I used as input in to a PID software system running on ESP32, and can hold the position preaty good, at maximum speed I get 2 messages at every step. On my project is enough. But, for smooth movement, I used TRQ_MODE, not SPD_MODE. Also, speed can be holded from esp32 with PID, much flexible to have an external microcontroller. On the ESP32 I connected an PS3 remote controller so I can do many diffrent commands, knowing that the PS3 controller is giving analog output(converted to 8 bit digital) for almost all buttons and joystiks.

Candas1 commented 2 years ago

@landrisan, I am curious about your industrial use of the firmware, any video you can share ?

landrisan commented 2 years ago

I am using it in a slitting/rewinding machine with automatic tension control and constant web speed. All of this done using two mainboards, one for the brake control unit and one for the two rewinding units, controled via USART with esp32 microcontroller.