So I got the motors to use velocity mode (and braking works great) by creating a derived class with an extra function:
Code
#include "main.h"
#include <cmath>
#include <chrono>
#include <string>
using namespace okapi::literals;
class cXDriveModel : public okapi::XDriveModel {
public:
void xArcadeVel(const double ixSpeed,
const double iforwardSpeed,
const double iyaw,
const double ithreshold) {
double xSpeed = std::clamp(ixSpeed, -1.0, 1.0);
if (std::abs(xSpeed) < ithreshold) {
xSpeed = 0;
}
double forwardSpeed = std::clamp(iforwardSpeed, -1.0, 1.0);
if (std::abs(forwardSpeed) < ithreshold) {
forwardSpeed = 0;
}
double yaw = std::clamp(iyaw, -1.0, 1.0);
if (std::abs(yaw) < ithreshold) {
yaw = 0;
}
topLeftMotor->moveVelocity(
static_cast<int16_t>(std::clamp(forwardSpeed + xSpeed + yaw, -1.0, 1.0) * maxVelocity));
topRightMotor->moveVelocity(
static_cast<int16_t>(std::clamp(forwardSpeed - xSpeed - yaw, -1.0, 1.0) * maxVelocity));
bottomRightMotor->moveVelocity(
static_cast<int16_t>(std::clamp(forwardSpeed + xSpeed - yaw, -1.0, 1.0) * maxVelocity));
bottomLeftMotor->moveVelocity(
static_cast<int16_t>(std::clamp(forwardSpeed - xSpeed + yaw, -1.0, 1.0) * maxVelocity));
}
};
pros::Imu inertial(4);
// Construct the drivetrain
std::shared_ptr<okapi::ChassisController> drive =
okapi::ChassisControllerBuilder()
.withMotors(
2,
-10,
-11,
20
)
.withDimensions(okapi::AbstractMotor::gearset::green, {{4_in, 15.5_in}, okapi::imev5GreenTPR})
.build();
auto cXDriveTrain { std::static_pointer_cast<cXDriveModel>(drive->getModel()) };
void opcontrol() {
while(true) {
cXDriveTrain->xArcadeVel(
controller.getAnalog(okapi::ControllerAnalog::leftX),
controller.getAnalog(okapi::ControllerAnalog::leftY),
controller.getAnalog(okapi::ControllerAnalog::rightX),
0.05);
//Tilt Lock
static bool tilted { false };
int roll = std::abs(inertial.get_roll());
if (!tilted && roll >= 10 && roll < 1000) { // Going from flat to tilted enable hold
std::cout << "triggered tiltbrake\n";
cXDriveTrain->setBrakeMode(okapi::AbstractMotor::brakeMode::hold);
tilted = !tilted;
}
else if (tilted && roll < 10) { //going from tilted to flat disable hold
cXDriveTrain->setBrakeMode(okapi::AbstractMotor::brakeMode::coast);
tilted = !tilted;
}
pros::delay(10);
}
I don’t know why, but if instead of
auto cXDriveTrain { std::static_pointer_cast<cXDriveModel>(drive->getModel()) };
I say this:
auto cXDriveTrain { std::dynamic_pointer_cast<cXDriveModel>(drive->getModel()) };
The program will crash with this in console:
Error
DATA ABORT EXCEPTION
CURRENT TASK: User Operator Control (PROS)
REGISTERS AT ABORT
r0: 0x00000000 r1: 0x00000008 r2: 0x00000000 r3: 0x00000000 r4: 0x038000dc r5: 0x00000000 r6: 0x06060606 r7: 0x07070707
r8: 0x08080808 r9: 0x09090909 r10: 0x10101010 r11: 0x11111111 r12: 0x00000011 sp: 0x03ae3f88 lr: 0x07801134 pc: 0x07800300
BEGIN STACK TRACE
0x7800300
0x7801134
END OF TRACE
HEAP USED: 7448 bytes
STACK REMAINING AT ABORT: 4233247881 bytes
Maybe there is a c++ guru out there who will know why.
I think its weird because
auto XDriveTrain { std::dynamic_pointer_cast<okapi::XDriveModel>(drive->getModel()) };
has no problem.