Strange okapi xDriveModel setBrakeMode() behavior

I’m having an issue when okapilib with an x-drive and trying to set the brake mode.

Relevant code:

std::shared_ptr<okapi::OdomChassisController> drive =
        okapi::ChassisControllerBuilder()
                .withMotors(
                                1,
                                -3,
                                -4,
                                2
                           )
                .withDimensions(okapi::AbstractMotor::gearset::green, {{4_in, 15.25_in}, okapi::imev5GreenTPR})
                .withOdometry()
                .buildOdometry();

auto XDriveTrain { std::dynamic_pointer_cast<okapi::XDriveModel>(drive->getModel()) };
auto topLeft { XDriveTrain->getTopLeftMotor() };

okapi::Controller controller;
okapi::ControllerButton holdButton(okapi::ControllerDigital::B);

void opcontrol() {
        while (true) {

                /*


                Driving code


                */                    

                static bool toggle { false };
                if (holdButton.changedToPressed()) {
                        toggle = !toggle;
                        if (toggle) {
                                XDriveTrain->setBrakeMode(okapi::AbstractMotor::brakeMode::hold);
                        }
                        else {
                                XDriveTrain->setBrakeMode(okapi::AbstractMotor::brakeMode::coast);
                        }
                }

                switch (topLeft->getBrakeMode()) {
                case okapi::AbstractMotor::brakeMode::hold :
                        std::cout << "hold mode\n";
                        break;
                case okapi::AbstractMotor::brakeMode::coast :
                        std::cout << "coast mode\n";
                        break;
                }
                pros::delay(10);
        }

}

What should happen is when B is pressed, all chassis motors go to hold brake mode (and the terminal should be saying “hold mode” in a loop). When B is pressed again all chassis motors go to coast mode (terminal should go back to saying “coast mode”).

However, when B is pressed the motors do not actually hold, even though the terminal prints the expected correct output.

I noticed that if I place XDriveTrain->setBrakeMode(okapi::AbstractMotor::brakeMode::hold); inside opcontrol but outside of the loop, it also does not work, but if I place in within the opcontrol loop it does work.

Back when I was using only C++ PROS I set the brake mode per motor and it worked fine. I wonder if it has to do with okapilib using C PROS for setBrakeMode internally…

setBrakeMode only sets the brake mode, it does not actually activate braking. To cause the motors to brake (or hold) set their velocity to 0.

6 Likes

The XDriveModel’s xArcade function is constantly being called with values read from the controller analog sticks. Not pressing the sticks, so the inputs and all the motors velocity are sitting at 0, however the robot does not resist pushing from any direction. i.e. “hold” brake mode is not functioning.

Resisting to pushing is the intended purpose, not to stop the robot right away.

I noticed that in order to get the correct behavior, first I have to drive with the new brake mode set. Then it works. But this behavior is different than I had in pros.