Turn P loop Help

I’ve been trying to make some nice turning with an inertial sensor, I’ve started off with a P loop, to see if it was consistent enough, and it appears to be. even with different amounts of cubes in my tray, it will always reach the same angle each time. But I’ve been having the strangest issues with my turning P loop.

/*----------------------------------------------------------------------------*/
/*                                                                            */
/*    Module:       main.cpp                                                  */
/*    Author:       VEX                                                       */
/*    Created:      Wed Dec 04 2019                                           */
/*    Description:  This program will turn right 90 degrees using the         */
/*                  Inertial Sensor.                                          */
/*                                                                            */
/*                                                                            */
/*                                                                            */
/*----------------------------------------------------------------------------*/

// ---- START VEXCODE CONFIGURED DEVICES ----
// Robot Configuration:
// [Name]               [Type]        [Port(s)]
// LFdrive              motor         1               
// LBdrive              motor         20              
// Inertial2            inertial      2               
// RFdrive              motor         12              
// RBdrive              motor         10              
// ---- END VEXCODE CONFIGURED DEVICES ----

#include "vex.h"

using namespace vex;

double P = 0.092;

double error = 0;

bool turnPactive = false;
int desiredAngle = 90;

int driveP (){
    while(turnPactive){
      error = desiredAngle - Inertial2.rotation(degrees);
      int turnPower = error * P;
      LFdrive.spin(forward, turnPower, voltageUnits:: volt);
      LBdrive.spin(forward, turnPower, voltageUnits:: volt);
      RFdrive.spin(reverse, turnPower, voltageUnits:: volt);
      RBdrive.spin(reverse, turnPower, voltageUnits:: volt);
    };
    return 1;
};

int main() {
  // Initializing Robot Configuration. DO NOT REMOVE!
  vexcodeInit();
  Inertial2.calibrate();
  // waits for the Inertial Sensor to calibrate
  while (Inertial2.isCalibrating()) {
    wait(100, msec);
  }
  vex::task turnip(driveP);

  wait(2,seconds);
  turnPactive = true;

  
  
}

This code works if you comment out the wait command before the turning. but if you have anything at all before the turning it won’t turn. This means that when I tried to code an auton, it would move forward as desired, but wouldn’t start the turn. I stripped it down to just this program trying to find the issue, to confirm it wasn’t an issue with my drive pid or anything in my competition program conflicting. It might be an issue with the way I’m multitasking or something, because it will only turn if I have no delay before I set turnPactive to true. no idea why, I’ve been troubleshooting for hours. I really appreciate the assistance.

The inertial sensor calibration is kinda weird. The calibration starts but doesn’t wait until it finishEs, it just moves on to the next line. Once you run the calibration command, you have to manually add a wait command so that the motors don’t start turning before calibration. You should move calibration to pre_auton so that you don’t waste time.

the calibration is not the issue, I’ve confirmed this.
I think it must be something with the way I’m using multitasking. It appears that the turnP task will just run once, and never again. even though I have that while loop inside.

add a print command to the end of your task, right before the return but outside of the while loop. Does it print that? If it does that means your while loop Is ending since the value of turnPactive is false and your task ends immediately. Usually people put while(true) in their tasks and have their logic inside of that loop.

yes, I’ve added a while loop that is always active while(true){} around my whole task. still nothing. I’ll test for the while loop exiting though, thanks.

If that doesn’t work try printing out the values of Inertial2.rotation(degrees); . Perhaps you might need to reset your rotation value before beginning rotation.

there is absolutely no issue related to the sensor itself. I tried completely ignoring the sensor and just blindly turning the motors, still no work. It has to be an issue with the way I’m multitasking, but I have no clue what it is.

Hm, could you try adding a print command after you set PTurn to true? Just so we know. And then also print something inside the task to know if the task ever starts?

ok I’ve solved the issue mostly. I just blindly moved some of the wait commands inside the tasks and now it works. no idea why, but it does. thanks for your help.

Could you send your fixed code so I can see what you did?

/*----------------------------------------------------------------------------*/
/*                                                                            */
/*    Module:       main.cpp                                                  */
/*    Author:       VEX                                                       */
/*    Created:      Wed Dec 04 2019                                           */
/*    Description:  This program will turn right 90 degrees using the         */
/*                  Inertial Sensor.                                          */
/*                                                                            */
/*                                                                            */
/*                                                                            */
/*----------------------------------------------------------------------------*/

// ---- START VEXCODE CONFIGURED DEVICES ----
// Robot Configuration:
// [Name]               [Type]        [Port(s)]
// LFdrive              motor         1               
// LBdrive              motor         20              
// Inertial2            inertial      2               
// RFdrive              motor         12              
// RBdrive              motor         10              
// ---- END VEXCODE CONFIGURED DEVICES ----

#include "vex.h"

using namespace vex;

double P = 0.092;

double error = 0;

bool turnPactive = false;
int desiredAngle = 90;

int driveP (){
  while(true){
    while(turnPactive){
      error = desiredAngle - Inertial2.rotation(degrees);
      int turnPower = error * P;
      LFdrive.spin(forward, turnPower, voltageUnits:: volt);
      LBdrive.spin(forward, turnPower, voltageUnits:: volt);
      RFdrive.spin(reverse, turnPower, voltageUnits:: volt);
      RBdrive.spin(reverse, turnPower, voltageUnits:: volt);
    };
    task::sleep(20);
  };
  return 1;
    
};

int main() {
  // Initializing Robot Configuration. DO NOT REMOVE!
  vexcodeInit();
  Inertial2.calibrate();
  // waits for the Inertial Sensor to calibrate
  while (Inertial2.isCalibrating()) {
    wait(100, msec);
  }
  vex::task turnip(driveP);

  wait(2,seconds);
  turnPactive = true;

  
  
}
1 Like

There is a reason why your addition of the wait() fixed your issue. Before, you were running an infinite loop with no delay - eating up CPU power and not allowing the brain to execute code in other threads.

Your addition of the wait() frees up CPU power, allowing the rest of your code in the other threads to execute.

3 Likes