MecanumDrive wont initialize

I am looking for some help. I am trying to use the MecanumDrive with WPI_VictorSPX as the arguments and am having an error in the compiler of "no matching function for call to 'frc::MecanumDrive::MecanumDrive(ctre::phoenix::motorcontrol::can::WPI_VictorSPX*&, …

I am certain is has something to do with my shoddy programming or my lack of understanding, but I am a little overwhelmed by trying to figure out why its not working… I had everything happily working last year with eclipse and this change to vscode has brought me nothing but pain.

My code is at https://github.com/cca5448/2019TestRobot.Mk1, specifically, includes/subsystems/Drivetrain.h and cpp/subsystems/Drivetrain.cpp.

I also tried making a new robot using the robotbuilder which made a bunch of spaghetti code which doesn’t seem to compile at all, so that is mostly unhelpful.

Never used C++, but try this.

The MecanumDrive constructors take references, not pointers.

Oh, let me see if I can fix this to handle that… I haven’t gotten a firm grasp on ptr vs ref, so a lot of my code was figured out by trial and error (adding * or & to get it working)

I am clearly missing some syntax and can’t figure it out. This seems to produce similar issues…

C:\Storage\FRC\2019\Code\TestRobot.Mk1\src\main\cpp\subsystems\Drivetrain.cpp: In constructor 'Drivetrain::Drivetrain()':
C:\Storage\FRC\2019\Code\TestRobot.Mk1\src\main\cpp\subsystems\Drivetrain.cpp:12:74: error: no matching function for call to 'frc::MecanumDrive::MecanumDrive(ctre::phoenix::motorcontrol::can::WPI_VictorSPX*, ctre::phoenix::motorcontrol::can::WPI_VictorSPX*, ctre::phoenix::motorcontrol::can::WPI_VictorSPX*, ctre::phoenix::motorcontrol::can::WPI_VictorSPX*)'
  robotDrive.reset(new MecanumDrive(lf.get(), lr.get(), rf.get(), rr.get()));
                                                                          ^
In file included from C:\Storage\FRC\2019\Code\TestRobot.Mk1\build\tmp\expandedArchives\wpilibc-cpp-2019.1.1-headers.zip_bbc5901b0e22ac527e7d642f2ec68009/frc/WPILib.h:94:0,
                 from C:\Storage\FRC\2019\Code\TestRobot.Mk1\src\main\include/subsystems/Drivetrain.h:3,
                 from C:\Storage\FRC\2019\Code\TestRobot.Mk1\src\main\cpp\subsystems\Drivetrain.cpp:2:
C:\Storage\FRC\2019\Code\TestRobot.Mk1\build\tmp\expandedArchives\wpilibc-cpp-2019.1.1-headers.zip_bbc5901b0e22ac527e7d642f2ec68009/frc/drive/MecanumDrive.h:78:3: note: candidate: frc::MecanumDrive::MecanumDrive(frc::MecanumDrive&&)
   MecanumDrive(MecanumDrive&&) = default;
   ^~~~~~~~~~~~
C:\Storage\FRC\2019\Code\TestRobot.Mk1\build\tmp\expandedArchives\wpilibc-cpp-2019.1.1-headers.zip_bbc5901b0e22ac527e7d642f2ec68009/frc/drive/MecanumDrive.h:78:3: note:   candidate expects 1 argument, 4 provided
C:\Storage\FRC\2019\Code\TestRobot.Mk1\build\tmp\expandedArchives\wpilibc-cpp-2019.1.1-headers.zip_bbc5901b0e22ac527e7d642f2ec68009/frc/drive/MecanumDrive.h:72:3: note: candidate: frc::MecanumDrive::MecanumDrive(frc::SpeedController&, frc::SpeedController&, frc::SpeedController&, frc::SpeedController&)
   MecanumDrive(SpeedController& frontLeftMotor, SpeedController& rearLeftMotor,
   ^~~~~~~~~~~~
C:\Storage\FRC\2019\Code\TestRobot.Mk1\build\tmp\expandedArchives\wpilibc-cpp-2019.1.1-headers.zip_bbc5901b0e22ac527e7d642f2ec68009/frc/drive/MecanumDrive.h:72:3: note:   no known conversion for argument 1 from 'ctre::phoenix::motorcontrol::can::WPI_VictorSPX*' to 'frc::SpeedController&'

Drivetrain.h

#pragma once

#include <frc/WPILib.h>
#include <frc/commands/Subsystem.h>
#include <ctre/Phoenix.h>
#include <AHRS.h>
#include <frc/drive/MecanumDrive.h>

class Drivetrain : public frc::Subsystem
{
	private:
		static std::shared_ptr<WPI_VictorSPX> lf;
		static std::shared_ptr<WPI_VictorSPX> rf;
		static std::shared_ptr<WPI_VictorSPX> lr;
		static std::shared_ptr<WPI_VictorSPX> rr;
		static std::shared_ptr<MecanumDrive> robotDrive;
		AHRS* gyro;

	public:
		Drivetrain();
		void InitDefaultCommand() override;
		void DriveMecanum(double throttle, double strafe, double turn, bool useGyro = 0);
		double GetGyroAngle();
};

Drivetrain.cpp

#include "RobotMap.h"
#include "subsystems/Drivetrain.h"

Drivetrain::Drivetrain() : frc::Subsystem("Drivetrain"){
	lf.reset(new WPI_VictorSPX(DRIVE_MOT_LF));
	lr.reset(new WPI_VictorSPX(DRIVE_MOT_LR));
	rf.reset(new WPI_VictorSPX(DRIVE_MOT_RF));
	rr.reset(new WPI_VictorSPX(DRIVE_MOT_RR));

	robotDrive.reset(new MecanumDrive(lf.get(), lr.get(), rf.get(), rr.get()));

	//invert right side
	//rf.SetInverted(true);
	//rr.SetInverted(true);
	//rf->SetInverted(true);
	//rr->SetInverted(true);

	try {
		/***********************************************************************
		 * navX-MXP:
		 * - Communication via RoboRIO MXP (SPI, I2C, TTL UART) and USB.
		 * - See http://navx-mxp.kauailabs.com/guidance/selecting-an-interface.
		 *
		 * Multiple navX-model devices on a single robot are supported.
		 ************************************************************************/
		gyro = new AHRS(SPI::Port::kMXP);
	} catch (std::exception& ex ) {
		std::string err_string = "Error instantiating navX MXP:  ";
		err_string += ex.what();
		DriverStation::ReportError(err_string.c_str());
	}

}

void Drivetrain::InitDefaultCommand(){
	SetDefaultCommand(new TeleopMecanumDrive());
}

void Drivetrain::DriveMecanum(double throttle, double strafe, double turn, bool fieldCentric){
	if (fieldCentric){
		//field centric drive
		//robotDrive.MecanumDrive_Cartesian(throttle, strafe, turn, Drivetrain->GetGyroAngle());
		//robotDrive.driveCartesian(throttle, strafe, turn, Drivetrain->GetGyroAngle());
	} else {
		//not field centric
		//robotDrive.driveCartesian(throttle, strafe, turn);
	}
}

double Drivetrain::GetGyroAngle(){
	return gyro->GetAngle();
}

get() still returns a pointer. You need to dereference all 4 motors to get the reference.

robotDrive.reset(new MecanumDrive(*lf, *lr, *rf, *rr));

Note, if using shared_ptr you should be using make_shared rather then reset(new). So the motors would be

lf = std::make_shared<WPI_VictorSPX>(DRIVE_MOT_LF);

and similar for the robot drive.

This clears up the issues with MecanumDrive, but introduces an undefined reference.
Is there a better way I should be doing this?

Drivetrain.h

class Drivetrain : public frc::Subsystem
{
	private:
		static std::shared_ptr<WPI_VictorSPX> lf;
		static std::shared_ptr<WPI_VictorSPX> rf;
		static std::shared_ptr<WPI_VictorSPX> lr;
		static std::shared_ptr<WPI_VictorSPX> rr;
		static std::shared_ptr<MecanumDrive> robotDrive;
		AHRS* gyro;
//...

Drivetrain.cpp

Drivetrain::Drivetrain() : frc::Subsystem("Drivetrain"){
	lf = std::make_shared<WPI_VictorSPX>(DRIVE_MOT_LF);
	lr = std::make_shared<WPI_VictorSPX>(DRIVE_MOT_LR);
	rf = std::make_shared<WPI_VictorSPX>(DRIVE_MOT_RF);
	rr = std::make_shared<WPI_VictorSPX>(DRIVE_MOT_RR);

	//robotDrive.reset(new MecanumDrive(*lf, *lr, *rf, *rr));
	robotDrive = std::make_shared<MecanumDrive>(*lf, *lr, *rf, *rr);
//...
> Task :linkFrcUserProgramDebugExecutable FAILED
C:\Storage\FRC\2019\Code\TestRobot.Mk1\build\objs\frcUserProgram\debug\frcUserProgramCpp\cmfnvlnn9m0xvv4ma69bud8q9\Drivetrain.o: In function `Drivetrain::Drivetrain()':
C:\Storage\FRC\2019\Code\TestRobot.Mk1\src\main\cpp\subsystems/Drivetrain.cpp:31: undefined reference to `Drivetrain::lf'
C:\Storage\FRC\2019\Code\TestRobot.Mk1\src\main\cpp\subsystems/Drivetrain.cpp:31: undefined reference to `Drivetrain::lr'
C:\Storage\FRC\2019\Code\TestRobot.Mk1\src\main\cpp\subsystems/Drivetrain.cpp:31: undefined reference to `Drivetrain::rf'
C:\Storage\FRC\2019\Code\TestRobot.Mk1\src\main\cpp\subsystems/Drivetrain.cpp:31: undefined reference to `Drivetrain::rr'
C:\Storage\FRC\2019\Code\TestRobot.Mk1\src\main\cpp\subsystems/Drivetrain.cpp:31: undefined reference to `Drivetrain::robotDrive'
collect2.exe: error: ld returned 1 exit status

Because the motor controllers are static you have to define them in the cpp file

drivetrain.cpp

std::shared_ptr<WPI_VictorSPX> Drivetrain::lf;
std::shared_ptr<WPI_VictorSPX> Drivetrain::lr;
...

I would recommend to make them not static though

That was the ticket!

Thanks @Thad_House and @Kaboomboom3
I am past my immediate hurdle and I can go back to bashing my head against the desk some more.