View Single Post
  #9   Spotlight this post!  
Unread 02-18-2015, 01:07 AM
kylelanman's Avatar
kylelanman kylelanman is offline
Programming Mentor
AKA: Kyle
FRC #2481 (Roboteers)
Team Role: Mentor
 
Join Date: Feb 2008
Rookie Year: 2007
Location: Tremont Il
Posts: 185
kylelanman is a name known to allkylelanman is a name known to allkylelanman is a name known to allkylelanman is a name known to allkylelanman is a name known to allkylelanman is a name known to all
Re: Keeping two motors in sync

We started out with 2 motors and 2 encoders on a lift with 2 PID loops and could not keep the 2 in sync close enough to prevent binding. We linked them with a criss-cross chain and 2 sprockets and then tied them together in software under the control of 1 PID controller and 1 encoder.

Here was the code we used to tie them together. We like to implement limit switches and inverting of motors if needed as close to the hardware as possible. This ensures the motors are never fighting each other.

Code:
/*
 * DualCANTalon.h
 *
 *  Created on: Jan 29, 2015
 *      Author: Team2481
 */

#ifndef SRC_COMPONENTS_DUALCANTALON_H_
#define SRC_COMPONENTS_DUALCANTALON_H_

#include "WPILib.h"

class DualCANTalon : public PIDOutput {
private:
	CANTalon* mAMotor;
	CANTalon* mBMotor;
	bool mAInverted;
	bool mBInverted;
public:
	DualCANTalon(int motorA, int motorB, bool AInvert, bool BInvert);
	virtual ~DualCANTalon();
	void PIDWrite(float output);
	void Set(float speed);
	float GetOutputCurrent();
	float GetOutputVoltage();
};

#endif /* SRC_COMPONENTS_DUALCANTALON_H_ */
Code:
/*
 * DualCANTalon.cpp
 *
 *  Created on: Jan 29, 2015
 *      Author: Team2481
 */

#include <Components/DualCANTalon.h>


DualCANTalon::DualCANTalon(int motorA, int motorB, bool AInvert, bool BInvert) {
	mAMotor = new CANTalon(motorA);
	mBMotor = new CANTalon(motorB);
	mAInverted = AInvert;
	mBInverted = BInvert;

	mAMotor->ConfigNeutralMode(CANTalon::kNeutralMode_Brake);
	mBMotor->ConfigNeutralMode(CANTalon::kNeutralMode_Brake);
}

DualCANTalon::~DualCANTalon() {
	delete mAMotor;
	delete mBMotor;
}

void DualCANTalon::PIDWrite(float output) {
	Set(output);
}

void DualCANTalon::Set(float speed) {
	mAMotor->Set(mAInverted ? speed * -1 : speed);
	mBMotor->Set(mBInverted ? speed * -1 : speed);
}

float DualCANTalon::GetOutputCurrent() {
	float outputCurrentA = mAMotor->GetOutputCurrent();
	float outputCurrentB = mBMotor->GetOutputCurrent();

	float averageCurrent = (outputCurrentA + outputCurrentB) / 2;

	return averageCurrent;
}

float DualCANTalon::GetOutputVoltage() {
	float outputVoltageA = mAMotor->GetOutputVoltage();
	float outputVoltageB = mBMotor->GetOutputVoltage();

	float averageVoltage = (outputVoltageA + outputVoltageB) / 2;

	return averageVoltage;
}
__________________
"May the coms be with you"

Is this a "programming error" or a "programmer error"?

Reply With Quote