OP control not working

I have an OP control program, it uses arcade control. Only two of my motors move when joysticks or any other digital buttons are pressed. The Joystick only senses Y on the right despite me making it X, for arcade control. Does anyone have a solution? No errors have been shown so far.

 #include "main.h"

/**
 * A callback function for LLEMU's center button.
 *
 * When this callback is fired, it will toggle line 2 of the LCD text between
 * "I was pressed!" and nothing.
 */
void on_center_button() {
	static bool pressed = false;
	pressed = !pressed;
	if (pressed) {
		pros::lcd::set_text(2, "I was pressed!");
	} else {
		pros::lcd::clear_line(2);
	}
}

/**
 * Runs initialization code. This occurs as soon as the program is started.
 *
 * All other competition modes are blocked by initialize; it is recommended
 * to keep execution time for this mode under a few seconds.
 */
void initialize() {
	pros::lcd::initialize();
	pros::lcd::set_text(1, "Hello PROS User!");

	pros::lcd::register_btn1_cb(on_center_button);
}

/**
 * Runs while the robot is in the disabled state of Field Management System or
 * the VEX Competition Switch, following either autonomous or opcontrol. When
 * the robot is enabled, this task will exit.
 */
void disabled() {}

/**
 * Runs after initialize(), and before autonomous when connected to the Field
 * Management System or the VEX Competition Switch. This is intended for
 * competition-specific initialization routines, such as an autonomous selector
 * on the LCD.
 *
 * This task will exit when the robot is enabled and autonomous or opcontrol
 * starts.
 */
void competition_initialize() {}

/**
 * Runs the user autonomous code. This function will be started in its own task
 * with the default priority and stack size whenever the robot is enabled via
 * the Field Management System or the VEX Competition Switch in the autonomous
 * mode. Alternatively, this function may be called in initialize or opcontrol
 * for non-competition testing purposes.
 *
 * If the robot is disabled or communications is lost, the autonomous task
 * will be stopped. Re-enabling the robot will restart the task, not re-start it
 * from where it left off.
 */
void autonomous() {}

/**
 * Runs the operator control code. This function will be started in its own task
 * with the default priority and stack size whenever the robot is enabled via
 * the Field Management System or the VEX Competition Switch in the operator
 * control mode.
 *
 * If no competition control is connected, this function will run immediately
 * following initialize().
 *
 * If the robot is disabled or communications is lost, the
 * operator control task will be stopped. Re-enabling the robot will restart the
 * task, not resume it from where it left off.
 */


 void opcontrol() {


  pros::Controller master(pros::E_CONTROLLER_MASTER);
  pros::Motor left_mtr(1);
  pros::Motor right_mtr(10);
  pros::Motor left_mtr2(9);
  pros::Motor right_mtr2(2);
  pros::Motor arm(5);
  pros::Motor intake_left(5);
  pros::Motor intake_right(3,1);
  pros::Motor tray(9);
  //left and right is viewed from back of robot
  arm.set_brake_mode(pros::E_MOTOR_BRAKE_HOLD);
   std::cout << "Brake Mode: " << arm.get_brake_mode();
  arm.set_brake_mode(pros::E_MOTOR_BRAKE_HOLD);
  while (true) {
 	 int left = master.get_analog(ANALOG_LEFT_Y);
 	 int right = master.get_analog(ANALOG_RIGHT_X);
	 left = (left) + (right);
	 left_mtr2 = (left) + (right);
 	 right_mtr = (left) - (right);
 	 right_mtr2 = (left) - (right);
int tray_speed=127;
 	 if(master.get_digital(DIGITAL_R2)) {
 		 tray.move_velocity(tray_speed);
 		tray_speed -= 1;
 		 pros::delay(50);

 		 //deploying tray system at proportional speed, speed will decrease every 50 MS
 	 }
 	 else if (master.get_digital(DIGITAL_R1)) {
 		 tray_speed = 127;
 		 tray.move_velocity(-127);
 	   pros::delay(50);
 		//moves tray back at 127 rpm

 	 }
 	 else if(master.get_digital(DIGITAL_Y))
 	 {
 		 tray.move_velocity(-60);
 		 pros::delay(50);
 		 //moving tray back at partial speed
 	 }
 	 else if(master.get_digital(DIGITAL_A))
 	 {
 		 tray.move_velocity(60);
 		 pros::delay(50);
 		 //deploying tray system at partial speed to prevent cubes from tipping
 	 }
 	 if (master.get_digital(DIGITAL_RIGHT)) {
  arm.move_velocity(127);
 		 while (!((arm.get_position() < 1855) && (arm.get_position() > 1845))) {
 		     // Continue running this loop as long as the motor is not within +-5 units of its goal
 		     pros::delay(500);
 				 //medium tower

 		   }
 		 }
 	 //code for medium tower
 	 else if (master.get_digital(DIGITAL_DOWN)) {
 		 while(!((arm.get_position() <0) &&(arm.get_position() >-5))) {
 		 arm.move_velocity(-127);
 pros::delay(500);
 //resets arm to bottom position
 }
 	 }
 	 else if (master.get_digital(DIGITAL_LEFT))
 	 {
 		 while (!((arm.get_position() < 1555) && (arm.get_position() > 1545))){}
 		 arm.move_velocity(127);
 		 pros::delay(500);
 		 //code for low tower
 	 }


 	 if (master.get_digital(DIGITAL_L1)) {
 		 intake_left.move_velocity(127);
 		 intake_right.move_velocity(127);
 		 //When L1 is pressed intake stops, or is revesed when L1 is held down
 	 }
 	 else if (master.get_digital(DIGITAL_L2)) {
 		 while(true)
 		 {
 		 intake_left.move_velocity(-127);
 		 intake_right.move_velocity(-127);
 		 //intake on/off switch
 	 }
 	 }

 }
 }

I would highly advise splitting your teleop code into multiple functions, and then putting those functions into separate CPP files. This is probably just due to the web formatting, but also make sure that with each nesting you indent, and as you exit that nesting you go back to the left a bit. These steps aren’t necessary for code to function, but it makes it way easier to read and debug.

At the start of your main while loop there is your arcade drive code. I see two main problems with this. First, I don’t think you are setting the motor speeds correctly. The function in PROS(V5) is motor.move(speed);, not motor = speed;. Second, you did left and not left_mtr. This means that you are setting the variable left to the value of left + right instead of the left_mtr motor. This offsets the rest of your motor speeds since they rely on the left variable.

There are multiple while() loops within your teleoperated period (ignoring the main while(true)). While loops prevent the code below it from running until the loop is finished. That means if you press the down button, everything will freeze until the arm is in position. I would advise putting it into a separate task or using something other than a loop to accomplish your goal.

For your arm it looks like you are using a concept called Bang-Bang. This is fine for many things. Your lift however, is probably not a good use case. For your tilter, you are relying on time, which is also not a best case senerio. I would advise instead using PID or just a Proportional loop. Basically you take the target position you want, and then subtract from that your current position. You then take that ‘error’, and then multiply it by a ‘proportional’ value (kP). So as your titler moves towards its target, it slows down without relying on time or delaying the program. For your arm, the built in PID function should be fine. It’s motor.move_absolute(position, speed); in PROS.

Also if you remove the 50MS delays throughout the program, make sure to add one single 20MS delay at the end of the loop. Without it it starves other tasks from the processor, and the program can’t do everything it needs to. The reason why we use 20MS delays instead of 50MS ones is that the brain updates the motors and sensors at 20MS intervals. So that’s the fastest time we can update anything.

5 Likes

Actually, PROS provides an assignment operator overload, so this syntax is correct. However, it still makes more sense to use the move function, which increases readability.

5 Likes

I will try that hopefully it works I will update you thanks for the help.