Getting stable measurements with the BNO055 IMU
Try a permanent calibration. From the Adafruit forums:


  You'd basically need to read and write data registers 55-6A. In both cases, you have to set the sensor in CONFIG_MODE. There's more information on page 48 of the datasheet.


The magnetometer is influenced by surrounding magnetic sources like motors. You might be able to tell the extent of the effect using the following method:


  The System Calibration Status will start out at 0 and will go to 3
  when the sensor is calibrated. For example, the mag calibration status
  will go to 3 if you do some figure 8s. If you put a piece of metal
  near the sensor, the calibration status will drop to 0. But when the
  metal is moved away, it will go back to 3. You may be able to use this
  value as an indicator that calibration is lost. I have found that once
  it's calibrated, it seems to hold calibration well.


For getting solid readings out of the gyroscope, this might be helpful advice:


  I don't worry about scaling the gyro output on a per-sample basis. I simply sum the output into a 32 bit (or larger) integer register. I do subtract-out a null value at each sample, which I will talk about later. But essentially, if you sample your gyro at 1kHz, and sum the output into an accumulator, you will see that the value of that accum at any time will be directly proportional the angle of rotation. If your rate is set for 250 deg/sec, then a rotation of 180 deg will result in approximately 23330000 in the accumulator. I call that the GYRO_CAL number. So, at any given time the angle, in degrees, is deg = accum / GYRO_CAL * 180. 
  
  Since the gyro output is linear, the accumulator is insensitive to
  whether the rotation is fast or slow (as long as the max deg/sec isn't
  exceeded).
  
  Here is my basic routine for each gyro reading:


void read_FIFO(){
       sample = read_value_from_FIFO();   //read the latest z-axis sample. I use the fifo, but that isn't necessary
       accum += sample - null;           //add the sample to the sum and subtract the null
       if((accum &gt; GYRO_CAL) -= GYRO_CAL*2;  //roll the accumulator at +180 deg.
       if((accum &lt; -GYRO_CAL) += GYRO_CAL*2; // roll the accumulator at -180 deg.
       angle = accum/GYRO_CAL * 180;   // convert to degrees
}


  I calculate the null at the beginning of each run. I sum 1000 readings
  and take the average. The gyro has to sit still for 3 or 4 seconds for
  this. The GYRO_CAL value can be calculated by summing the output while
  you rotate the gyro by 180 deg. Or you can sum over many turns, and
  divide by the number of 180 deg turns for a more accurate value.
  
  You could probably use a 64-bit FP for the accumulator, but since
  arduino only supports 32 bit FP, I found it absolutely necessary to
  use a 32 bit integer to avoid roundoff and other errors.
  
  If you follow that general outline, I promise you will get rock solid
  performance out of the gyro. There are a few other small optimizations
  that I make, which I can discuss later.