|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
|
|
Thread Tools |
Rating:
|
Display Modes |
|
|
|
#1
|
||||
|
||||
|
Re: Drivetrain Idea - "Box Drive"
I actually thought of making a drive system like this, but doing it with traction wheels and have one set actuate up and down to change directions, a bit like some of the octocanum and similar drives do, but with the entire drive module (the benefit being you'd have a sort of omnidirectional drive system with traction wheels).
Eventually I concluded that the system would weigh too much, use to many motors, and be too complex to be practical. That said, it would be cool to see someone make it work. |
|
#2
|
||||
|
||||
|
Re: Drivetrain Idea - "Box Drive"
Quote:
|
|
#3
|
||||
|
||||
|
Re: Drivetrain Idea - "Box Drive"
The reason H drive has more forward traction than mecanum or omni is because more of the robot's weight is supported on the wheels pointing forwards than the wheels pointing sideways. In this configuration having more sideways wheels cancels out that effect.
With some specific exceptions, simply increasing the number of wheels on the ground does not significantly increase traction. So this drive is going to perform exactly as well as a holonomic 4 omni drive in terms of traction or manuverability. In addition, once you put more than 4 wheels on the ground you run into problems with maintaining wheels contact. Unless your frame is perfectly rigid with every wheel at exactly the same height (and a perfectly rigid drive doesn't exist) you'll have some wheels supporting far more weight than others, this disproportionately influencing the direction of travel. |
|
#4
|
|||||
|
|||||
|
Re: Drivetrain Idea - "Box Drive"
See if you can locate any tech specs for the only "linkage drive" ever used in FRC--"Twitch" was the robot name.
4 omni wheels mounted in swerve module-type devices, rotated 90 degrees by a single pneumatic cylinder. It was used in 2008 for making turns at the ends of the field. That might be worth trying out in the offseason; the "swerve modules" could be just large pieces of C-channel or box tubing (or, if you have any around, the 2010 KitBot risers with some extra well-placed holes). |
|
#5
|
||||
|
||||
|
Re: Drivetrain Idea - "Box Drive"
Quote:
About the OP: Cool idea. How would you make sure all 8 wheels are touching the ground though? This would save a lot of space depending on motor configurations. Using a shifter to shift between wheels on each corner bevel gears would net you the ability to tank, slide, and drift. Weight would be a big issue though with the extra 4 wheels and shifters. |
|
#6
|
||||
|
||||
|
Quote:
|
|
#7
|
||||
|
||||
|
Re: Drivetrain Idea - "Box Drive"
Quote:
Quote:
As for something I've seen in a few posts in this thead: This would probably use four motors to avoid the weight issue with 8 motors. We'd have to check in offseason testing, though, since we don't have much to do to prepare for our offseason competition. Anyways, if I can't convince my team anyway, we'd probably end up testing a butterfly drive or the like. |
|
#8
|
||||
|
||||
|
Re: Drivetrain Idea - "Box Drive"
Quote:
Thanks for that link, it made my day. ![]() |
|
#9
|
||||
|
||||
|
Re: Drivetrain Idea - "Box Drive"
So if figured out the math/code for this using cjl2625's version of the drivetrain.
Here's a segment (Java, btw): Code:
final double DISTANCE_X = 1.0;
final double DISTANCE_Y = 1.0;
private double leftY;
private double rightY;
private double frontX;
private double backX;
//rotation is cw
private double rotationX;
private double rotationY;
private double pi = 3.1415926;
private double curr_gyro_angle_degrees = 0.0;
private double curr_gyro_angle_radians = 0.0;
private double temp;
public void TakeJoystickInputsAndDrive(Joystick left, Joystick right)
{
calculatedDrive(-0.5 * left.getY(), 0.5 * left.getX(), 0.5 * right.getX());
}
void calculatedDrive(double y, double x, double rotation)
{
//Field-centric adjustments. Comment out for robot-centric.
curr_gyro_angle_degrees = gyro1.getAngle();
curr_gyro_angle_radians = curr_gyro_angle_degrees * pi/180;
temp = y * Math.cos(curr_gyro_angle_radians) - x * Math.sin(curr_gyro_angle_radians);
x = y * Math.sin(curr_gyro_angle_radians) + x * Math.cos(curr_gyro_angle_radians);
y = temp;
rotationX = rotation * DISTANCE_X;
rotationY = rotation * DISTANCE_Y;
leftY = y - rotationY;
rightY = y + rotationY;
frontX = x - rotationX;
backX = x + rotationX;
drive(leftY, rightY, frontX, backX);
}
void drive(double y1, double y2, double x1, double x2)
{
//left, right
robotDrive2Y.drive(y1, y2);
//front, back
robotDrive2X.drive(x1, x2);
}
Any problems with the code/math that you can see at the moment? I want to make sure this is sound before I pitch this to my team. |
|
#10
|
|||
|
|||
|
Re: Drivetrain Idea - "Box Drive"
180 combined that with an airplane propeller in 2009.
|
|
#11
|
|||||
|
|||||
|
Re: Drivetrain Idea - "Box Drive"
Quote:
|
|
#12
|
||||
|
||||
|
Re: Drivetrain Idea - "Box Drive"
That design uses pneumatic wheels, not traction wheels, though. Traction wheels might not actuate properly.
Also that design doesn't do diagonals or moving while rotating, which are key to be able to do for a field-centric system. I don't know of a non omni/mecanum/swerve/h drive that can do this, though. That said, that drivetrain looks effective for Rebound Rumble, so it served its purpose well, and might serve another purpose later. It just won't serve my purpose currently. |
|
#13
|
||||
|
||||
|
Re: Drivetrain Idea - "Box Drive"
I redid the Drivetrain code to normalize the motor values. How is the code? (Just ctrl-A ctrl-V'd it)
Code:
// RobotBuilder Version: 1.0
//
// This file was generated by RobotBuilder. It contains sections of
// code that are automatically generated and assigned by robotbuilder.
// These sections will be updated in the future when you export to
// Java from RobotBuilder. Do not put any code or make any change in
// the blocks indicating autogenerated code or it will be lost on an
// update. Deleting the comments indicating the section will prevent
// it from being updated in the future.
package org.usfirst.frc1127.DevBot2014_2015.subsystems;
import org.usfirst.frc1127.DevBot2014_2015.RobotMap;
import org.usfirst.frc1127.DevBot2014_2015.commands.*;
import edu.wpi.first.wpilibj.*;
import edu.wpi.first.wpilibj.command.Subsystem;
/**
*
*/
public class Drivetrain extends Subsystem
{
//constants
final double DISTANCE_X = 1.0;
final double DISTANCE_Y = 1.0;
//only needed for field-centric
final double PI = 3.1415926;
//wheel velocity values | positive x values are right | positive y values are forwards
private double[] motorValues = {0.0, 0.0, 0.0, 0.0};
//rotation is cw
private double rotationX;
private double rotationY;
//field-centric stuff
private double curr_gyro_angle_degrees = 0.0;
private double curr_gyro_angle_radians = 0.0;
private double cos;
private double sin;
private double temp;
//for the for loop
private int i;
double maxValue = 1.0;
// BEGIN AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=DECLARATIONS
CANJaguar cANJaguar1 = RobotMap.drivetrainCANJaguar1;
CANJaguar cANJaguar2 = RobotMap.drivetrainCANJaguar2;
RobotDrive robotDrive2X = RobotMap.drivetrainRobotDrive2X;
CANJaguar cANJaguar3 = RobotMap.drivetrainCANJaguar3;
CANJaguar cANJaguar4 = RobotMap.drivetrainCANJaguar4;
RobotDrive robotDrive2Y = RobotMap.drivetrainRobotDrive2Y;
Gyro gyro1 = RobotMap.drivetrainGyro1;
// END AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=DECLARATIONS
// Put methods for controlling this subsystem
// here. Call these from Commands.
public void initDefaultCommand()
{
// BEGIN AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=DEFAULT_COMMAND
setDefaultCommand(new DriveWithJoysticks());
// END AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=DEFAULT_COMMAND
// Set the default command for a subsystem here.
//setDefaultCommand(new MySpecialCommand());
}
public void TakeJoystickInputsAndDrive(Joystick left, Joystick right)
{
calculatedDrive(left.getY(), left.getX(), right.getX());
}
void calculatedDrive(double y, double x, double rotation)
{
//Field-centric adjustments. Comment out for robot-centric.
curr_gyro_angle_degrees = gyro1.getAngle();
curr_gyro_angle_radians = curr_gyro_angle_degrees * (PI / 180);
cos = Math.cos(curr_gyro_angle_radians);
sin = Math.sin(curr_gyro_angle_radians);
temp = y * cos - x * sin;
x = y * sin + x * cos;
y = temp;
//This code is needed for both robot-centric and field-centric
rotationX = rotation * DISTANCE_X;
rotationY = rotation * DISTANCE_Y;
motorValues[0] = y - rotationY;
motorValues[1] = y + rotationY;
motorValues[2] = x - rotationX;
motorValues[3] = x + rotationX;
maxValue = 1.0;
for(i = 0; i < 4; i++)
{
if(motorValues[i] > maxValue)
maxValue = motorValues[i];
}
if(maxValue > 1.0)
for(i = 0; i < 4; i++)
motorValues[i] = motorValues[i] / maxValue;
drive(motorValues[0], motorValues[1], motorValues[2], motorValues[3]);
}
void drive(double y1, double y2, double x1, double x2)
{
//left, right
robotDrive2Y.drive(y1, y2);
//front, back
robotDrive2X.drive(x1, x2);
}
public void stop()
{
robotDrive2Y.drive(0, 0);
robotDrive2X.drive(0, 0);
}
}
|
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|