How to choose the SimpleFOC mode for the application of three-axis gimbal

Hey @Cc1924,

We’ll probably need a bit more details to help you more specifically with your setup.
Can you tell us if you have already tuned your PID parameters or are you using the default ones?
You should definitely spend some time on this and find the parameters that suite your application the best.

Now in terms of control architecture, I agree that the simplest one to start with would be simplefoc in angle mode and IMU setting the target values. Just make sure you tune your velocity and angle PIDs well.

The velocity control with simplefoc and angle PID using the IMU values is a good option as well and should give you a bit smoother operation. But this all depends how well did you tune your parameters. :smiley:

Now in terms of smoothness, I’m not sure if you’ll be able to get really smooth operation using the AS5600. Their resolution is not really good and even though the angle measurement is good enough to do FOC when you calculate the velocity from it it becomes very noisy and can introduce some osculations both because of the noise itself and due to the heavy filtering you need to put.

So what I would suggest you as a control structure would be:

  1. use the simplefoc in voltage mode.
  2. close the velocity loop using your gyro, which will give you a superbly smooth velocity measurement.
  3. close the angle/position loop using the fused IMU data

You would still have the same amount of PIDs to tune but at least you would be using the most out of your setup. :smiley:

Hi, @Antun_Skuric!

Thank you for your reply!

I have tried several sets of PID parameters. I input the target angle in the serial port, and SimpleFOC can quickly reach the target position. But when I joined the blue pill to control the gimbal, the rotation of the motor could not keep up with the movement speed of the gimbal. This makes it look very lagging.

In addition, in order to improve the accuracy, I tried to use the 14-bit AS5048A magnetic encoder. I run the example code of magnetic_sensor_spi_example. It uses

Serial.println(sensor.getVelocity())

to get the speed.But I found that the speed noise is relatively large, and I don’t know if this is normal. It looks like this:

I use AS5600 to run the same code, and its noise seems to be smaller than AS5048A. The resulting image looks like this:

Your suggestion of using the angular velocity data of the gyro as the speed feedback of the motor is great! But I have some problems. The gyro measures the angular velocity relative to its own coordinate system, not the speed of the motor. I don’t know if it is right that the gimbal is usually in a horizontal position, so the coordinate axis of the IMU and the axis of the gimbal are parallel at this time, so the angular velocity of the gyro can approximately replace the speed of the motor?

Thanks again for your help.

No it’s not. I am using 5047P which is relatively close to the 58. Perhaps I am saying the obvious, but your setup needs to be fully grounded and all cables shielded. All shields go to real ground (bury a metal bucket in your yard, draw a multi-stranded cable to your work-bench and connect to a grounding bar. Also use mu-metal to shield the magnetic sensor if you have a noisy environment or large motors or magnetically noisy motors. Mu-metal motor housing too. Ground everything, wear antistatic gloves. Avoid plastic. Keep signal cables short and avoid power supply for powering your setup (50Hz or 60Hz leaks from power network). Use batteries instead. Use ferrite rings. I am working from home due to covid and this is my clean sensor signal:

May I ask, how does the bluepill talk to the motor controllers? Have you checked the speed of this control loop? If this communication is taking too long it could be part of the reason why the reaction time is slow…
One way to check could be to plot IMU signals and motor board sensors at the same time (I guess some custom program would be needed for this, to combine the data from 2 serial ports) and see what the lag is.

Hi!

I have used shielded cables and connected the shields to the ground of my SimpleFOC. I am using battery power. But I have never got a signal as clean as yours.

Blue pill uses a serial port with 115200 baud rate to communicate with SimpleFOC. For example, simpleFOC works in position mode. This is my SimpleFOC command acceptance code:

void serialReceiveUserCommand() {
  static String received_chars;   
  while (Serial.available()) {
    char inChar = (char)Serial.read();
    if (inChar == ',') {
      target_angle = received_chars.toFloat();
      received_chars = "";
    }
    else if (inChar != Motor_No)   //check the target of this motor
    {
      received_chars += inChar;
    }
  }
}

Blue pill uses the serial port to send target commands according to the above protocol.

I have not checked the time taken for communication, I will try it later.

Thanks for your help!

Hi, @runger!

I use a simple way to test the time cost of serial communication. I added a part to change the IO level in the serial port receiving code in SimpleFOC. Then I use my mini oscilloscope to detect the high-level time to judge the time consumption of my serial port.

But something strange happened. The serial port time is basically stable at two values, they are about 200us and 2.5ms. I use a computer to send P10.1234, through the serial port. No matter if I send it every 5ms or every 2s, the serial port time of SimpleFOC is always jumping between these two values. I think 200us is normal. 2.5ms should be the cycle time including FOC. But I don’t understand why this happens.

In addition, this is the oscilloscope video I got when I used the computer to send data every 5ms:

This is the oscilloscope video I got when I used the computer to send data every 0.5s:

And this is my test code:

void loop() {
  motor.loopFOC();
  motor.move(target_angle);
  serialReceiveUserCommand();
}

void serialReceiveUserCommand() {
  static String received_chars;   
  while (Serial.available()) {
    char inChar = (char)Serial.read();
    if (inChar == ',') {    
      target_angle = received_chars.toFloat();
      received_chars = "";
      digitalWrite(TEST_PIN,LOW);   // Received the end of the frame, pull down the IO
    }
    else if (inChar == 'P')   
    {
      digitalWrite(TEST_PIN,HIGH);  // Received frame header, pull up IO
    }
    else if (inChar != 'P')
    {
      received_chars += inChar;
    }
  }
}

Hey,

I think this is ok. Judging by your code, sometimes the command sends within one call to serialReceiveUserCommand(), and sometimes the command takes 2 (or more?) calls to the serialReceiveUserCommand() to be received completely. But in between the FOC loop is executing, so that is ok.

So from the point of view of the serial communication on the motor board side, I think this is ok. 200us is acceptable, and 1 loop delay to receiving the command is also ok, I think.

I think the total loop time on the motor board of 2.5ms is quite high. This means FOC is executing at 400Hz - I think this is a little on the slow side. On the other hand, gimbal motors don’t need to spin fast.

On the sending side, on the bluepill, I guess you are sending to one motor after the other. So 2.5ms communication time per motor would mean 5ms between motor 1 and motor 3 receiving their commands.

At this point I have to say I don’t have the experience to judge it - it sounds like a slightly difficult setup to manage - AS5600 is slow and somewhat inaccurate, Bluepill has to read the IMU and then command one motor after another via serial, which does not have fixed timings.

There are some people on the forum who have made working balance bots - perhaps they can say something about these timings in relation to IMU control.

Hi, @Valentine !

Today I learned that the lower 3 bits of the AS5048A(AS5047P) magnetic sensor’s register data are not accurate. In other words, the data it reads from a stationary magnetic field may jump within the range of 2^3 =8. Then if the angle data is read every 1ms, the velocity error caused by this jitter is calculated like this:

CodeCogsEqn

The code I used to read the angle and speed of the encoder is here:

  Serial.print(sensor.getAngle());
  Serial.print("\t");
  Serial.println(sensor.getVelocity());

I learned that we can also use motor.shaft_angle and motor.shaft_velocity to get the angle and velocity, and shaft_velocity uses LPF.

So I want to know how you got the clean encoder signal that you responded to me earlier? Did velocity use LPF? Perhaps, can you show me your code?

@Cc1924

Could you provide the source for that information please?

I used the built-in example from the utils in simplefoc github.

Thanks,
Valentine

Hi, @Valentine!

I once heard two people talk about it. One of them was in this post in this community. They said it was the ADC sampling accuracy. I don’t have specific reference materials either. Sorry.
image
Unfortunately, I also run the examples in utils, but I can’t get the clean signal like your sensor.

That is untrue. There is no evidence of such claim. Unless you find out the exact ADC and CORDIC MCU silicon reference as well as the CORDIC ADC/DSP algorithm implementation microcode used in calculating the angle from the four hall sensor coordinates, and have the knowledge to take it apart and critique its merits, this blanket claim is baseless.

This is unfortunate however short of me walking into your place and examining the setup and waving an EMF meter, it’s impossible to offer suggestions. This 5048A/B sensor is designed for the robotic and automotive industry, it can withstand a pretty noisy environment, there’s got to be a pretty obvious source for the noise. Did you also use true ground (literally a buried bucked in the backyard)?

Something very important, I am using 5047P which is the extra-high speed version which uses a different CORDIC system and angle timing deviation error correction algorithm so by the time the signal hits the SPI bus it’s already corrected, and you are using the slow speed 5048A. However such high error you showed cannot be explained away by systemic noise.

Perhaps you acquire a 5047P and re-setup your system? I am not sure. Wish I could help.

Edit: Perhaps a stupid suggestion on my part but you could check the value of the error register of the sensor to see if your magnet is correctly set up? May be your magnet is right or not set up correctly?

> ...register address x3FFD (AS5048A) : •OCF (Offset Compensation Finished), logic high indicates the finished Offset Compensation Algorithm. After power up the flag remains always to logic high. •COF (CORDIC Overflow), logic high indicates an out of range error in the CORDIC part. When this bit is set, the angle and magnitude data is invalid. The absolute output maintains the last valid angular value. • COMP low, indicates a high magnetic field. It is recommended to monitor in addition the magnitude value. • COMP high, indicated a weak magnetic field. It is recommended to monitor the magnitude value.

Hi, @Valentine

You are right. I cannot say that until there are documents to prove it. And unfortunately, I searched for related documents today but couldn’t find it either.

image

This is the result I got when I used Keil MDK to program STM32 to read the angle data of AS5048A. It can be seen that the angle data has very little jitter. I don’t understand whether this is a normal phenomenon of the sensor or is caused by noise.

In addition, since my gimbal needs to be moved around, I cannot connect it to the real ground.

I’m working on a similar problem that requires precise and smooth control of slow motion.

In my experience, tuning PID for bigger changes (eg manually entering 1rad or 2 rads and watching it go to that angle), the same set of PIDs did not generate enough torque from small changes.

Now, when I tried to tune specifically for slow motion, I quickly realized that on a small scale torque of the motor is not linear, but has bumps often referred to as torque cogging or ripple.
So I went on to boost P gain to get over that torque bump, then increased D gain to compensate for oscillations caused by high P on the other side of the slope. I also increased I to compensate for high initial friction in my system, which may not be applicable to yours though.

Having high gain parameters has ended up amplifying the background noise from magnetic sensors, and applying heavy filtering to angle/velocity data just makes it sluggish again, while causing violent oscillations from larger disturbances.

Sounds familiar at all?

I’m also a bit disappointed to see that better position sensors haven’t helped you much.
I was about to try replacing my as5600 with 5048b hoping for help from 4x angular resolution, and your experience has lowered my expectations.

Working with sensors requires a lot of patience, and the results are very rewarding when you get it right. I have 5600 and it’s been fine as long as you take all the precautions. Don’t give up, keep experimenting and it also helps talking with someone with hard science lab experience, I mean, face to face, to examine your setup, especially if you live near a major university. I know many people work alone, in isolation, and get easily frustrated and abandon their projects. The fact that you can buy a complete 3-axis gimbal for less than $100 means all these sensors and hardware work just fine. Don’t give up, keep walking.

I’m used to frustration being a large part of any engineering or scientific project, but a little encouragement still helps, thank you :slight_smile:
I’ll report back when I make some progress.

If you’re thinking of changing your sensor, moving to SPI devices will be much faster. I like the simplicity of the I2C sensors, but in the end you want the speed of the SPI devices…

I’d recommend an AS5048A or AS5047 sensor, they work well.

In terms of the sensor accuracy, I think the thing to worry about is your magnet and your grounding.
Moving the sensor further/closer to the magnet can change the magnitude of the magnetic field registered, and change the accuracy. Using better magnets with clearly defined fields will also make a difference, I suppose.
And electrically, the sensor wants a nice stable supply and ground. The output is digital and has parity bits, so things would have to go quite badly wrong to get errors once the signal is digital. But when measuring the magnetic field, bad grounding/power supply can influence the accuracy.

1 Like

I’m in the exact same situation. Tuning my PIDs for large changes has been relatively easy, but I’ve failed to achieve good results (I mean fast and unbouncing corrections) for small disruptions. I’ve tried more aggressive current PIDs tuning, but then the motor vibrates and gets hot. I’m using a SimpleFOCShield and a AS5048A.

No news is bad news?

Hello!

I was actually looking to accomplish something very similar but, with OEM cheap micro gimbals such as what you can usually buy off of AliExpress as a replacement for a DJI Mavic1 or 2, Mavic Mini or Mavic Air…

I was heavily involved with the development testing of project called OpenHD… One of the goals was to create an open source solution to have the same functionality and greater range on an open source platform using readily available components…

One of the biggest disadvantages of DIY drones is the extreme miniaturization and camera stability of consumer drones like DJI…

I spent a lot of time researching and tearing down some of the inner workings of DJI gimbals and, engaged on another simpleFOC thread below with regards to the integrated DUAL linear HALL sensors the gimbals have…

Because they have mechanical stops limiting the rotation to 45°-90° or so, it sounds like they use a RATIOMETRIC difference between two Hall sensors to determine angle…

Someone on this thread said that the setup should be fairly simple to implement and use…

:diamonds:The primary objective would be to retrofit something like a GoPro sensor or Raspberry pi MIPI CSI-2 image sensor utilizing the stock micro coaxial signal and power wires…

:information_source:I have a ton of links pictures and information to anyone who might be interested…
*Unfortunately I don’t know how to program and still learning about simple FOC as well as the Storm32 open source gimbal project but, I’m really good with hardware and, thorough testing… :grinning:

I I would love to hear any thoughts or feedback related to this idea and application
Cheers…

Also, Here is a YouTube video I put together of some of the components and, a video of another person in China who was able to get a mavic mini gimbal operational but without the integrated Hall sensors…