Good vibrations

Post Reply
pihlerm
Posts: 23
Joined: Tue Dec 09, 2014 6:40 pm

Good vibrations

Post by pihlerm »

Hello all,
spring is coming and it is time for tweaking and flying.

Above all, I find getting rid of vibrations or minimizing them as much as possible the most difficult part of tweaking.
I balance the props, in both axes, by using a static prop balancer. I use tape for the long axis and epoxy near the shaft (sometimes throwing in a nut or a bolt in severe cases).
I then balance the motors using dynbalancing build of MWII. Down to 2x2 millimeter patches of tape.

And I'm still getting the damn good vibrations.

There are lots of methods for measuring vibrations:
- By listening to the props
- Using a smart phone taped near the motors
- Watching the sensor outputs in Multiwiiconf
- ...
Perhaps a lot has been said on this topic; what I'm missing is a way of communicating the OBJECTIVE measurements of vibrations.
Thinking of RMS values. The graphics of sensor output are nice; but hard to compare. A single value here is best.

I am experimenting with modified code in MWI that measures RMS values of GYRO and ACC raw sensor outputs. I find after good vibration dampening, gyro is almost at zero, but ACC is still showing values.

If people are interested, I can post my RMS calc code (it outputs gyro and acc RMS values measured over 500 samples through DEBUG values in multiwii gui.
Since the values are what the MWII code sees, they should be of objective value to MWII users and directly comparable. I wonder how much vibrations you people get?

Of course the frame vibrations could differ; depending on FC board(sensor) vibration isolation.
But I think vibrations as acc sensor sees them are what counts.

If there is interest on this topic, I will post my code here and we can measure and compare.


The method:

RMSgyro = SQRT(SUM ( gyro(x)^2 + gyro(y)^2 + gyro(z)^2) [over 500 samples])
RMSacc = SQRT(SUM ( acc(x)^2 + acc(y)^2) [over 500 samples]) *** ignoring Z component of acc

Copter must be levelled and acc calibrated prior to running the test. I am not normalizing the values, so this is important.
Use soft pads under copter to decouple it from the table below.
The throttle for measurements is to be set at perhaps hover power.

What do you think?

FengShuiDrone
Posts: 234
Joined: Wed Dec 24, 2014 1:20 am
Location: ......

Re: Good vibrations

Post by FengShuiDrone »

.
Last edited by FengShuiDrone on Fri Aug 07, 2015 5:05 pm, edited 1 time in total.

pihlerm
Posts: 23
Joined: Tue Dec 09, 2014 6:40 pm

Re: Good vibrations

Post by pihlerm »

ok, here is the code (for multiwii 2.4, but it will also work in 2.3)
Usage instructions below.



after - find the code block and add code below it

insteadof - find the code block and replace it with code

config.h

Code: Select all

 after #define DYNBALANCE   // (**) Dynamic balancing controlled from Gui
  #define RMS_SAMPLING 600  // compute RMS values of gyro&acc, use number of samples defined


imu.cpp

Code: Select all

after  #if GYRO
after    Gyro_getADC();
after  #endif

  // compute RMS
  #ifdef RMS_SAMPLING
    imu.accRMSsum += (int32_t)imu.accADC[0]*(int32_t)imu.accADC[0] + (int32_t)imu.accADC[1]*(int32_t)imu.accADC[1];
    imu.gyroRMSsum += (int32_t)imu.gyroADC[0]*(int32_t)imu.gyroADC[0] + (int32_t)imu.gyroADC[1]*(int32_t)imu.gyroADC[1]+ (int32_t)imu.gyroADC[2]*(int32_t)imu.gyroADC[2];
    imu.numRMS++;
 
    if(imu.numRMS >= RMS_SAMPLING) {
      if(imu.accRMSsum==0) {
        imu.accRMS = 0;
      } else {
         imu.accRMS =  sqrt((int32_t)imu.accRMSsum / (imu.numRMS));
      }
      if(imu.gyroRMSsum==0) {
        imu.gyroRMS = 0;
      } else {
         imu.gyroRMS =  sqrt((int32_t)imu.gyroRMSsum / (imu.numRMS));
      }
      imu.numRMS=0;
      imu.accRMSsum=imu.gyroRMSsum=0;
      debug[0]=imu.accRMS;
      debug[1]=imu.gyroRMS;     
    }
  #endif


multiwii.cpp

Code: Select all

around 760
after    plog.armed_time = 0;   // lifetime in seconds
after    //plog.running = 0;       // toggle on arm & disarm to monitor for clean shutdown vs. powercut
after  #endif


  #ifdef DYNBALANCE
   motor_num=0;
  #endif

  #ifdef RMS_SAMPLING
   imu.accRMS=0;
   imu.accRMSsum=0;    // current RMS sum of acc (x,y) values
   imu.gyroRMS=0;    // current RMS of gyro (x,y,z) values
   imu.gyroRMSsum=0;    // current RMS sum of gyro (x,y,z) values
   imu.numRMS=0; // num samples
  #endif
 



around 916


after      if (conf.activate[BOXARM] > 0) {             // Arming/Disarming via ARM BOX
after        if ( rcOptions[BOXARM] && f.OK_TO_ARM ) go_arm(); else if (f.ARMED) go_disarm();
after      }
after    }


    #ifdef DYNBALANCE
      if(rcDelayCommand == 20) {
        if (rcSticks == THR_LO + YAW_CE + PIT_CE + ROL_HI) motor_num++;    // next motor
        if (rcSticks == THR_LO + YAW_CE + PIT_CE + ROL_LO) motor_num--;    // prev motor
        else if (conf.activate[BOXARM] == 0 && rcSticks == THR_LO + YAW_HI + PIT_CE + ROL_CE) go_arm();      // Arm via YAW
        else if (conf.activate[BOXARM] == 0 && rcSticks == THR_LO + YAW_LO + PIT_CE + ROL_CE) go_disarm();    // Disarm via YAW
    
        if(motor_num==NUMBER_MOTOR) motor_num=0;
        if(motor_num==255) motor_num=NUMBER_MOTOR-1;
        rcDelayCommand=0;
        debug[3]=motor_num;
      }
    #endif



multiwii.h

Code: Select all

after extern int16_t motor[8];
after extern int16_t servo[8];


#ifdef DYNBALANCE
  extern uint8_t motor_num;
#endif



output.cpp

Code: Select all

around 1129

insteadof #if defined(DYNBALANCE)
insteadof     return;
insteadof #endif

  #if defined(DYNBALANCE)
     for(int i=0;i<8;i++) motor[i]=0;
     if (!f.ARMED)  return;  // Kill throttle when disarmed
     if(rcCommand[THROTTLE] > MINTHROTTLE+50)
       motor[motor_num] = rcCommand[THROTTLE];
     return;
  #endif




types.h

Code: Select all

after typedef struct {
after   int16_t  accSmooth[3];
after   int16_t  gyroData[3];
after   int16_t  magADC[3];
after   int16_t  gyroADC[3];
after   int16_t  accADC[3];


  #ifdef RMS_SAMPLING
  int32_t  accRMS;    // current RMS of acc (x,y) values
  int32_t  accRMSsum;    // current RMS sum of acc (x,y) values
  int32_t  gyroRMS;    // current RMS of gyro (x,y,z) values
  int32_t  gyroRMSsum;    // current RMS sum of gyro (x,y,z) values
  int16_t  numRMS; // num samples
  #endif

Last edited by pihlerm on Fri May 22, 2015 8:20 am, edited 1 time in total.

pihlerm
Posts: 23
Joined: Tue Dec 09, 2014 6:40 pm

Re: Good vibrations

Post by pihlerm »

The code in previous post does two things.

Make sure

Code: Select all

#define DYNBALANCE 
#define RMS_SAMPLING 600 

are uncommented in config.h.

1. It computes RMS values for accelerometer/gyro and sends them to GUI via DEBUG1 - accelerometer and DEBUG2 - gyro fields.

2. It allows you to use remote control and sticks to operate motors one at a time.
Power up, then use stick combo to arm (throttle low, yaw max).
Use throttle low, yaw center with roll max / roll min to change motor number that you are calibrating.
The motor number is displayed via DEBUG4.

Then use throttle to spin the selected motor.


I use wingui to show graphs for acc while i'm calibrating. RMS values are refreshed every second or so.

Note that RMS vill vary with throttle, I try to find position with max vibrations, then remember the RMS and try to lower it as much as possible via balancing.


Now for some data. My quad is a 550 class, 2kg, with 11x4.7 props on it.
I have AIO from HK.

Motor without props : I try to get lower than 6 RMS.
Motor with props : I try to get lower than 12 RMS.


If somebody is willing to test the code and post their RMS values, I would be very happy.

Post Reply