Inertial Sensor malfunction

Hi all!

I’m trying to code turning for my auton using the V5 inertial sensor
currently, I’m using

Inertial10.rotation(rotationUnits::deg);

to get the rotation value of the sensor
But whenever I run my program, the sensor’s value (printed to the brain) starts at zero and gradually goes up to -143, then stays put and works like it normally should.
Anyone have any ideas why this might be happening?

Do you have it mounted upside down, below the bot? IIRC the sensor does not like reading negative z acceleration.

yes, it is upside down, I didn’t think it would be an issue. Thanks for letting me know! ill try mounting it rightside up

It should not be an issue.
are you fully updated to vexos 1.0.9, that’s mandatory to use the inertial sensor.

1 Like

I just updated everything. The sensor works perfect now when standing still, but it just hovers between -1 and 1 while moving.

+/- 1 what ? test the sensor using the dashboard.

1 Like

this is inside a loop:

sensorValue = Inertial10.rotation(rotationUnits::deg);
    
Brain.Screen.clearLine(4, black);
Brain.Screen.setCursor(4, 1);
Brain.Screen.print(sensorValue);

I’m assuming ± 1 degree, but maybe .rotation() doesn’t work how I thought?

Is there sensor working in the dashboard ? does it show 0-360 degrees for heading as you rotate the robot ?
Is sensorValue a double ? Did you give the sensor time to finish calibration before entering the while loop ?

1 Like

yes * 4

The only time it doesn’t work is when I spin the wheels to turn towards the target rotation
Even when I lift the robot up and let the wheels spin free, the value of the rotation changes. Could the Inertial10.rotation(); value be linked to the spinning of a motor?

Edit: I heard something about some ports being linked (like 1 & 2). Is that a thing?

post all the code or attach the project as a zip file.

1 Like
void inertialTurnForPID(int degrees, double maxVoltage) {
  
  double target = Inertial10.rotation(rotationUnits::deg) + degrees;
  Brain.Screen.newLine();
  Brain.Screen.print("Target:");
  Brain.Screen.print(target);
  Brain.Screen.newLine();

  double iSensorValue = Inertial10.rotation(rotationUnits::deg);

  int allowedRange = 5;

  //the error (Proportional)
  double error = 0;
  double kP = 0.03;

  //Integral
  double integral = 0;
  double kI = 0.00;

  //Derivative
  double derivative = 0;
  double kD = 0.00;
  double previousError = 0;

  //the power to the motor
  double power = 0;

  while(iSensorValue < (target - allowedRange) || iSensorValue > (target + allowedRange)) {
    iSensorValue = Inertial10.rotation(rotationUnits::deg);
    
    Brain.Screen.clearLine(4, black);
    Brain.Screen.setCursor(4, 1);
    Brain.Screen.print(iSensorValue);

    error = target - iSensorValue;

    integral += error;
    //if you reach the goal or cross it, set integral to zero
    if(error == 0 || error * previousError < 0) {
      integral = 0;
    }
    //only use integral at the end
    if(abs(error) > 40) {
      integral = 0;
    }

    derivative = error - previousError;
    previousError = error;

    power = (error * kP) + (integral * kI) + (derivative * kD);

    if(power > maxVoltage) {
      power = maxVoltage;
    }
    if(power < -maxVoltage) {
      power = -maxVoltage;
    }

    LDrive.spin(directionType::fwd, power, voltageUnits::volt);
    LDrive2.spin(directionType::fwd, power, voltageUnits::volt);

    RDrive.spin(directionType::rev, power, voltageUnits::volt);
    RDrive2.spin(directionType::rev, power, voltageUnits::volt);

    task::sleep(20);
  }
  
  LDrive.stop(brakeType::brake);
  LDrive2.stop(brakeType::brake);

  RDrive.stop(brakeType::brake);
  RDrive2.stop(brakeType::brake);

}

in the auton section, I’m calling the function with the values (180, 5)

Ok, I got it working by adding an extra calibration section before the auton ran. This shouldn’t be necessary though, right?