For our previous tournament, we had a very accurate and precise turn function using the inertial sensor. However, the function no longer works and we have not changed anything. The issue is that the inertial sensor outputs a value of 0 for “iSensor.getRotation(rotationUnits::deg)”
We have tried multiple things to fix this:
Change the inertial sensor ports
Update to the latest firmware
Change wires
Connect laptop directly to brain
No matter what the inertial sensor outputs a value of 0 for heading, rotation, pitch, yaw, etc. even when we move it manually. When we check the value of heading on the brain however, its correct. Why is the inertial sensor not outputting any value? This is causing the motors to be rotating forever as they never approach the target angle. @jpearman
void rotateright(double angleTurn) {
/*
Get initial values and begin rotation
*/
iSensor.resetRotation();
rightdt.spin(directionType::fwd, -60, velocityUnits::pct);
leftdt.spin(directionType::fwd, 60, velocityUnits::pct);
/*
This ratio will be used to gradually slow down the robot as it approaches the target angle
*/
double ratio = iSensor.rotation(rotationUnits::deg) / -(angleTurn);
/*
Loops the turn as long as the angle is not met
Record the ratio adjust speed based on ratio
*/
while(iSensor.rotation(rotationUnits::deg) < angleTurn) {
cout << "right: " << -60 + ratio*50 << endl;
cout << "left: " << 60 - ratio*50 << endl;
rightdt.spin(directionType::fwd, -60 + ratio*50, velocityUnits::pct);
leftdt.spin(directionType::fwd, 60 - ratio*50, velocityUnits::pct);
ratio = iSensor.rotation(rotationUnits::deg) / angleTurn;
cout << "ratio: " << iSensor.rotation(rotationUnits::deg) / angleTurn << endl;
}
/*
Completely stops motors and holds them at angle
*/
rightdt.stop(hold);
leftdt.stop(hold);
vex::task::sleep(100);
}
The ratio variable stays at 0 since the sensor.rotation() stays at 0 and this causes the motors to spin at 60% forever.
same issue, you need to slow down the while loop, you cannot send data to std::cout that fast. Add a 20-50mS delay and you should be able to debug correctly.
Just tested with adding a 100ms delay in the while loop of rotateRight. Same result, cout prints 60 & -60 for the motor speeds and 0 for the ratio. Motors spin forever since ratio doesn’t ever increase due to iSensor.rotation(rotationUnits::deg) not changing.
/*
Rotates robot right using Inertial Sensor
*/
void rotateright(double angleTurn) {
/*
Get initial values and begin rotation
*/
iSensor.resetRotation();
rightdt.spin(directionType::fwd, -60, velocityUnits::pct);
leftdt.spin(directionType::fwd, 60, velocityUnits::pct);
/*
This ratio will be used to gradually slow down the robot as it approaches the target angle
*/
double ratio = iSensor.rotation(rotationUnits::deg) / -(angleTurn);
/*
Loops the turn as long as the angle is not met
Record the ratio adjust speed based on ratio
*/
while(iSensor.rotation(rotationUnits::deg) < angleTurn) {
cout << "right: " << -60 + ratio*50 << endl;
cout << "left: " << 60 - ratio*50 << endl;
rightdt.spin(directionType::fwd, -60 + ratio*50, velocityUnits::pct);
leftdt.spin(directionType::fwd, 60 - ratio*50, velocityUnits::pct);
ratio = iSensor.rotation(rotationUnits::deg) / angleTurn;
cout << "ratio: " << iSensor.rotation(rotationUnits::deg) / angleTurn << endl;
vex::task::sleep(100);
}
/*
Completely stops motors and holds them at angle
*/
rightdt.stop(hold);
leftdt.stop(hold);
vex::task::sleep(100);
}
I pulled some of your code into a test program. Seems to work ok.
Make sure IMU is plugged into the correct port.
Make sure you wait for IMU to finish calibration.
Try this test code, it works here.
/*----------------------------------------------------------------------------*/
/* */
/* Module: main.cpp */
/* Author: james */
/* Created: Sun Feb 02 2020 */
/* Description: V5 project */
/* */
/*----------------------------------------------------------------------------*/
#include "vex.h"
#include <iostream>
using namespace vex;
// A global instance of vex::brain used for printing to the V5 brain screen
vex::brain Brain;
// define your global instances of motors and other devices here
vex::motor rightdtFront(vex::PORT20, vex::gearSetting::ratio18_1, true);
vex::motor rightdtBack(vex::PORT11, vex::gearSetting::ratio18_1, true);
vex::motor leftdtFront(vex::PORT10, vex::gearSetting::ratio18_1, false);
vex::motor leftdtBack(vex::PORT1, vex::gearSetting::ratio18_1, false);
vex::inertial iSensor(vex::PORT3);
motor_group rightdt(rightdtFront, rightdtBack);
motor_group leftdt(leftdtFront, leftdtBack);
/*
Rotates robot right using Inertial Sensor
*/
void rotateright(double angleTurn) {
/*
Get initial values and begin rotation
*/
iSensor.resetRotation();
rightdt.spin(directionType::fwd, -60, velocityUnits::pct);
leftdt.spin(directionType::fwd, 60, velocityUnits::pct);
/*
This ratio will be used to gradually slow down the robot as it approaches the target angle
*/
double ratio = iSensor.rotation(rotationUnits::deg) / -(angleTurn);
/*
Loops the turn as long as the angle is not met
Record the ratio adjust speed based on ratio
*/
while(iSensor.rotation(rotationUnits::deg) < angleTurn) {
std::cout << "right: " << -60 + ratio*50 << std::endl; // sign changed
std::cout << "left: " << 60 - ratio*50 << std::endl; // sign changed
rightdt.spin(directionType::fwd, -60 + ratio*50, velocityUnits::pct);
leftdt.spin(directionType::fwd, 60 - ratio*50, velocityUnits::pct);
ratio = iSensor.rotation(rotationUnits::deg) / angleTurn;
std::cout << "ratio: " << iSensor.rotation(rotationUnits::deg) / angleTurn << std::endl;
// delay so we don't saturate cout
this_thread::sleep_for(50);
}
/*
Completely stops motors and holds them at angle
*/
rightdt.stop(hold);
leftdt.stop(hold);
vex::task::sleep(100);
}
int main() {
while( iSensor.isCalibrating() )
this_thread::sleep_for(10);
rotateright( 90 );
while(1) {
// Allow other tasks to run
this_thread::sleep_for(10);
}
}