Only one drive motor running. Help needed

I started coding my teams asterisk drive and when I tested it only the front left wheel (A1 on port 11) was spinning. All of the cords are plugged into the correct ports and when I run the default drive program all of the wheels spin.

I tried a different brain, system reset on both brains, copy and pasted the code into a new program, and redownloaded vscode on my laptop.

I also was able to add a display section to the user control loop but when I commented out all uses of A1 the program still ran A1 (at the correct speed), I then tried to just delete it and it kept running A1 (Yes I did confirm the new program downloaded).

I have no idea what the issue is as our sister teams coder, chat GPT, and Copilot all see no problems with the code (AI is usually good at finding stupid mistakes I miss).

This is all of the code but hopefully all you need is above the motor struct and in the user control loop. My apologize for the lack of comments.

#include "vex.h"
using namespace vex;
competition Competition;
controller cont = controller(primary);
motor A1 = motor(11, true);
motor B1 = motor(15, true);
motor C1 = motor(20, true);
motor A2 = motor(10, false);
motor B2 = motor(5, false);
motor C2 = motor(1, false);
#define CX1 cont.Axis4.position(percent)
#define CX2 cont.Axis1.position(percent)
#define CY1 cont.Axis3.position(percent)
#define CY2 cont.Axis2.position(percent)
struct Motor
{
  int e = 0;
  int f = 0;
  int g = 0;
  int h = 0;
  int i = 0;
  int P = 0;
  int I = 0;
  int D = 0;
  int PID()
  {
    h = e;
    e = g - i;
    P = e * .1;
    if (abs(e) < 45)
    {
      I = (e + I) * .1;
    }
    else
    {
      I = 0;
    }
    D = (h - e) * .1;
    f = P + I + D;
    return f;
  };
};
Motor a1;
Motor a2;
Motor b1;
Motor b2;
Motor c1;
Motor c2;
void move(int x, int y, int z)
{
  A1.setPosition(0, degrees);
  A2.setPosition(0, degrees);
  B1.setPosition(0, degrees);
  B2.setPosition(0, degrees);
  C1.setPosition(0, degrees);
  C2.setPosition(0, degrees);
  a1.g = ((y + x) * (360 * sin(45))) + (z * 18.1 * 90);
  a2.g = ((y + x) * (360 * sin(45))) - (z * 18.1 * 90);
  b1.g = ((y * 360 * sin(45)) + (z * 13.8 * 90)) * (5 / 7);
  b2.g = ((y * 360 * sin(45)) - (z * 13.8 * 90)) * (5 / 7);
  c1.g = ((y - x) * (360 * sin(45))) + (z * 18.1 * 90);
  c2.g = ((y - x) * (360 * sin(45))) - (z * 18.1 * 90);
  do
  {
    a1.i = A1.position(degrees);
    a2.i = A2.position(degrees);
    b1.i = B1.position(degrees);
    b2.i = B2.position(degrees);
    c1.i = C1.position(degrees);
    c2.i = C2.position(degrees);
    A1.spin(forward, a1.PID(), percent);
    A2.spin(forward, a2.PID(), percent);
    B1.spin(forward, b1.PID(), percent);
    B2.spin(forward, b2.PID(), percent);
    C1.spin(forward, c1.PID(), percent);
    C2.spin(forward, c2.PID(), percent);
    wait(20, msec);
  } while (abs(a1.e) + abs(a2.e) + abs(b1.e) + abs(b2.e) + (abs(c1.e) + abs(c2.e)) > 20);
  A1.stop();
  A2.stop();
  B1.stop();
  B2.stop();
  C1.stop();
  C2.stop();
}
void pre_auton(void)
{
  A1.setPosition(0, degrees);
  A2.setPosition(0, degrees);
  B1.setPosition(0, degrees);
  B2.setPosition(0, degrees);
  C1.setPosition(0, degrees);
  C2.setPosition(0, degrees);
}
void autonomous(void)
{
  move(10, 20, 45);
  move(-20, -10, 90);
}
void usercontrol(void)
{
  A1.spin(forward, 0, percent);
  A2.spin(forward, 0, percent);
  B1.spin(forward, 0, percent);
  B2.spin(forward, 0, percent);
  C1.spin(forward, 0, percent);
  C2.spin(forward, 0, percent);
  while (1)
  {
    A1.setVelocity(CY1 + CX1 + CX2, percent);
    A2.setVelocity(CY1 + CX1 - CX2, percent);
    B1.setVelocity(CY1 + ((13.8 * 5) / (18.1 * 7)) * CX2, percent);
    B2.setVelocity(CY1 - ((13.8 * 5) / (18.1 * 7)) * CX2, percent);
    C1.setVelocity(CY1 - CX1 + CX2, percent);
    C2.setVelocity(CY1 - CX1 - CX2, percent);
    wait(20, msec);
  }
}
int main()
{
  Competition.autonomous(autonomous);
  Competition.drivercontrol(usercontrol);
  pre_auton();
  while (true)
  {
    wait(100, msec);
  }
}

Is this error happening in driver control, autonomous or both?
I’m not seeing anything immediately wrong with your logic, but I would recommend printing the speed that you are setting each motor to onto the brain screen so you can see how fast they are supposed to be spinning.

1 Like

Try to delete build foloder, and rebuild your project. Sometimes C++ compiler is that smart.
By the way, one little suggestion, you could improve standardization of your code. Well, you konw, it’s a little hard to understand some variables with the name of “A, B ,C…”. Try to use more detailed names, and this will actually help you mange your logic and maintain your code better.

3 Likes

Please please please get better variable names, right now it’s hard to tell what parts of your code do because I don’t know what the variables mean. The only reason I know what’s going on in your PID method is because I know how a PID works, otherwise I would have no clue what it was doing. Variable names should only be short when it’s a very common abbreviation, and the variable only lasts a couple lines (like i for “index” in a loop or tmp for a temporary variable). You should prioritize making code which is efficient to read, not efficient to write, especially with modern autocomplete making typing long variable names fast. Also, avoid unexplained “magic numbers” and use constant variables instead.

double speed_ips = // something...

double WHEEL_DIAMETER = 3.25;
double GEAR_RATIO = 60.0 / 36.0;

double degrees_per_inch = WHEEL_DIAMETER * PI * GEAR_RATIO / 360.0;
double speed_rpm = speed_ips * degrees_per_inch / 360.0 * 60.0;

is a lot more understandable then

double b = a * 0.00787821566;

even if it is longer


As for you actual problem, try switching your data type to be float or double on all of your numbers instead of int, because those support decimal places and int does not. You are also dividing integers when you do 5 / 7, which should be 0.714285714 but will actually be 0 because integers can’t have decimal places. Replace 5 / 7 with 5.0 / 7.0 to fix this. This will give your numbers more precision and will stop them from weirdly rounding and potentially ending up at 0 when they should just be a small number.

Try logging the speed values and deleting the build folder like NO1 and SunWater said too, and make sure you are saving the file before building/uploading.

4 Likes

looks like the link to the youtube video just turned into an image, here’s what it was supposed to be: https://www.youtube.com/watch?v=-J3wNP6u5YU

@NO1 I don’t have the robot right now but I know the issue exists in driver control, printing the speed of each motor gives the correct velocity.

@SunWater @iseau395 Here is the “correctly named” code. Theoretically the motor struct shouldn’t matter but I reformatted it anyway. I deleted the build folder but I don’t have the robot to test if that fixed it right now.

#include "vex.h"
using namespace vex;
competition Competition;
controller cont = controller(primary);
motor Front_Left = motor(11, true);
motor Middle_Left = motor(15, true);
motor Back_Left = motor(20, true);
motor Back_Right = motor(10, false);
motor Middle_Right = motor(5, false);
motor Front_Right = motor(1, false);
#define CX1 cont.Axis4.position(percent)
#define CX2 cont.Axis1.position(percent)
#define CY1 cont.Axis3.position(percent)
#define CY2 cont.Axis2.position(percent)
struct Motor
{
  int error = 0;
  int function_return = 0;
  int goal = 0;
  int historical_error = 0;
  int internal_position = 0;
  int Proportional = 0;
  int Itegral = 0;
  int Derivitive = 0;
  int PID()
  {
    historical_error = error;
    error = goal - internal_position;
    Proportional = error * .1;
    if (abs(error) < 45)
    {
      Itegral = (error + Itegral) * .1;
    }
    else
    {
      Itegral = 0;
    }
    Derivitive = (historical_error - error) * .1;
    function_return = Proportional + Itegral + Derivitive;
    return function_return;
  };
};
Motor front_left;
Motor back_right;
Motor middle_left;
Motor middle_right;
Motor front_right;
Motor back_left;
void move(int x, int y, int z)
{
  Front_Left.setPosition(0, degrees);
  Back_Right.setPosition(0, degrees);
  Middle_Left.setPosition(0, degrees);
  Middle_Right.setPosition(0, degrees);
  Back_Left.setPosition(0, degrees);
  Front_Right.setPosition(0, degrees);
  front_left.goal = ((y + x) * (360 * sin(45))) + (z * 18.1 * 90);
  back_right.goal = ((y + x) * (360 * sin(45))) - (z * 18.1 * 90);
  middle_left.goal = ((y * 360 * sin(45)) + (z * 13.8 * 90)) * (5 / 7);
  middle_right.goal = ((y * 360 * sin(45)) - (z * 13.8 * 90)) * (5 / 7);
  front_right.goal = ((y - x) * (360 * sin(45))) + (z * 18.1 * 90);
  back_left.goal = ((y - x) * (360 * sin(45))) - (z * 18.1 * 90);
  do
  {
    front_left.internal_position = Front_Left.position(degrees);
    back_right.internal_position = Back_Right.position(degrees);
    middle_left.internal_position = Middle_Left.position(degrees);
    middle_right.internal_position = Middle_Right.position(degrees);
    front_right.internal_position = Back_Left.position(degrees);
    back_left.internal_position = Front_Right.position(degrees);
    Front_Left.spin(forward, front_left.PID(), percent);
    Back_Right.spin(forward, back_right.PID(), percent);
    Middle_Left.spin(forward, middle_left.PID(), percent);
    Middle_Right.spin(forward, middle_right.PID(), percent);
    Back_Left.spin(forward, front_right.PID(), percent);
    Front_Right.spin(forward, back_left.PID(), percent);
    wait(20, msec);
  } while (abs(front_left.error) + abs(back_right.error) + abs(middle_left.error) + abs(middle_right.error) + (abs(front_right.error) + abs(back_left.error)) > 20);
  Front_Left.stop();
  Back_Right.stop();
  Middle_Left.stop();
  Middle_Right.stop();
  Back_Left.stop();
  Front_Right.stop();
}
void pre_auton(void)
{
  Front_Left.setPosition(0, degrees);
  Back_Right.setPosition(0, degrees);
  Middle_Left.setPosition(0, degrees);
  Middle_Right.setPosition(0, degrees);
  Back_Left.setPosition(0, degrees);
  Front_Right.setPosition(0, degrees);
}
void autonomous(void)
{
  move(10, 20, 45);
  move(-20, -10, 90);
}
void usercontrol(void)
{
  Front_Left.spin(forward, 0, percent);
  Back_Right.spin(forward, 0, percent);
  Middle_Left.spin(forward, 0, percent);
  Middle_Right.spin(forward, 0, percent);
  Back_Left.spin(forward, 0, percent);
  Front_Right.spin(forward, 0, percent);
  while (1)
  {
    Front_Left.setVelocity(CY1 + CX1 + CX2, percent);
    Back_Right.setVelocity(CY1 + CX1 - CX2, percent);
    Middle_Left.setVelocity(CY1 + ((13.8 * 5.0) / (18.1 * 7.0)) * CX2, percent);
    Middle_Right.setVelocity(CY1 - ((13.8 * 5.0) / (18.1 * 7.0)) * CX2, percent);
    Back_Left.setVelocity(CY1 - CX1 + CX2, percent);
    Front_Right.setVelocity(CY1 - CX1 - CX2, percent);
    wait(20, msec);
  }
}
int main()
{
  Competition.autonomous(autonomous);
  Competition.drivercontrol(usercontrol);
  pre_auton();
  while (true)
  {
    wait(100, msec);
  }
}

@iseau395 the 5/7 being an int doesn’t matter as they are both multiplied by doubles so the overall result is a double. (I changed it anyway).

When you do math in c++, it will automatically use the least precise unit of measurement. While programming, I have had that issue multiple times and it did need to be changed.

1 Like

I found the problem and its kind of stupid.

I checked the API for the motor initialization i used

motor name = motor(portnumber, reversed)

And the portnumber starts at zero like a list, so motor(11,true) isn’t going to the motor pluged into port 11 motor(10,false).

This explains why when I deleted A1 the motor still ran, and why A1 is the only motor that ran because port 10 and 11 are the only ports one away from each other.

Anyway it works now so thanks for all the help.

2 Likes