Which of these general curve styles is preferred for driving control (joystick on the x-axis, motor speed on the y-axis)?
Top and bottom is probably best because it gives you fine control toward the slower speeds and then a little bit of a buffer at the top so you can still be going basically full speed even if you aren’t perfectly at the maximum (just bottom doesn’t seem to have as much tolerance with that.)
However, as 24C reported, even just making your control linear is a huge improvement over what they have now.
Disclaimer: This is the first year we are experimenting with this and have not determined conclusively what we like best yet.
I think it is different depending on your drive and how fast it is.
Care to elaborate?
I would also think bottom top. Daniel mentioned the key points. Having smooth control over your robot is a critical thing. By having the curves on the bottom and top, you increase the driver tolerance in making accurate decisions and driver tolerance when driving fast.
Though you may think driving fast isn’t a big issue, only recently have I noticed that joystick values for holonomic drive are very precise. Due to the minimal tolerance, the robot can waste motor power each time the robot changes direction. With that, seconds add up and i’m guestimating that the robot would lose 15 seconds of effective driving time. About the length of the autonomous period
Just finished wiring and programming a basic drive code in today, and I have no idea what you’re talking about. We can accelerate in any direction nearly instantly with our X-Drive. Even going diagonally, which uses only two motors, it seems like we’re completely fine.
For reference, my robot is fairly light and at 2.26:1 speed.
Maybe I phrased it poorly. When I first grabbed the controllers, the robot would respond really well, Too well. Though I intended to go forward, in reality i pushed slightly diagonal. This in turn slows the drive when I intended to move the drivetrain at a high velocity in a specific drivetrain.
Yes there are other ways around it, but since he asked which control layout is preferred, I would prefer the bottom top.
As an afterthought however, I don’t know how curved values would affect omni directional drivetrains when the major directions aren’t targeted.
I would go with bottom because it gives you a lot of control at slow speeds. You don’t need top and bottom because you don’t need precise control between the speeds of 100 through 127. It is also easier to program bottom.
//Untested code...
float x = vexRT[Ch3]*abs(vexRT[Ch3])/127;
float y = vexRT[Ch4]*abs(vexRT[Ch4])/127;
motor[0] = x - y;
motor[1] = x + y;
Personal preference always wins here. No real right or wrong answer, it’s how you like to drive your robot and how you perform the best.
This works on omnis incredibly well. 81M had it last year on their Halo style omni contorl on a quick robot (field reference with manual turn vs field reference with auto correcting heading control). Half our club now uses this log drive but mostly on regular or mechanum drives.
Are the pictures supposed to be from 0 - 127 or the full range from -127 - 127? If full range, top and bottom, as backwards would act very weird. If half range bottom is what this is…
You just call your log drive function (code from the post linked below) when you read the joystick values. That will tune down the value and then go about your normal business for coding holonomic drive. It’s the control value you are looking to tune more so than mess around at the output value. Some people have gone 3-4 times as much for a deeper curve but be careful about big integer numbers (divide earlier or just call your function twice). Plot it out in Excel to see the curves.
Original post on log drive from Quasar back in the day:
https://vexforum.com/showpost.php?p=139660&postcount=3
Go hog wild and selectively call the log drive based upon button pushes/states to test out different ones on the fly. It’s a fairly easy set of tests.
public class BezierCalculation
{
public static void main(String args])
{
double x,y,xr,xrPrev=.5, xPrev=0, yPrev=0;
int dip=0;
final double PRECISION=.00000001;
final double c=.5;//curviness of the bezier curve, a higher value will make it farther from linear
final int x_0=10;//joystick threshold
final int y_0=11;//minimum motor speed that causes it to move
final double x_1=(127-x_0)*c+x_0;
final int y_1=y_0;
final double x_2=(127-x_0)*(1-c)+x_0;
final int x_3=127;//ending x value
final int y_3=127;//ending y value
final int y_2=y_3;
int n=y_0;
//print y for every integer x
for(int i=1; i<=y_0; i++)
{
System.out.print( " 0,");
if(i%10==0)
System.out.println();
}
for(double t=0; t<=1; t+=PRECISION)
{
x=(1-t)*((1-t)*((1-t)*x_0+t*x_1)+t*((1-t)*x_1+t*x_2))+t*((1-t)*((1-t)*x_1+t*x_2)+t*((1-t)*x_2+t*x_3));
y=(1-t)*((1-t)*((1-t)*y_0+t*y_1)+t*((1-t)*y_1+t*y_2))+t*((1-t)*((1-t)*y_1+t*y_2)+t*((1-t)*y_2+t*y_3));
xr=x%1;
if(xr>=.5)
xr=1-xr;//rounding
if(xr<xrPrev)
dip=0;//the dip in the graph of xr has not happened yet
if(xr>xrPrev&&dip==0)
{
System.out.printf("%3.0f", yPrev);
System.out.print(",");
n++;
if(n%10==0)//width is 10
System.out.println();
dip++;
}
xPrev=x;
xrPrev=xr;
yPrev=y;
}
}
}
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 11, 11, 11, 11, 11, 11, 11, 12, 12,
12, 12, 12, 13, 13, 13, 14, 14, 15, 15,
16, 16, 17, 18, 18, 19, 20, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29, 31, 32, 33,
35, 36, 37, 39, 41, 42, 44, 45, 47, 49,
51, 53, 54, 56, 58, 60, 62, 64, 66, 68,
70, 72, 74, 76, 78, 80, 82, 84, 85, 87,
89, 91, 93, 94, 96, 97, 99,101,102,103,
105,106,107,109,110,111,112,113,114,115,
116,117,118,118,119,120,120,121,122,122,
123,123,124,124,125,125,125,126,126,126,
126,126,127,127,127,127,127,127
}
public class BezierNormalizedTo256
{
public static void main(String args])
{
double x,y,xr,xrPrev=.5, xPrev=0, yPrev=0;
int xRound, dip=0;
final double PRECISION=.00000001;
final double c=.5;//curviness of the bezier curve, a higher value will make it farther from linear
final int x_0=10;//joystick threshold
final int y_0=11;//minimum motor speed that causes it to move
final double x_1=(127-x_0)*c+x_0;
final int y_1=y_0;
final double x_2=(127-x_0)*(1-c)+x_0;
final int x_3=127;//ending x value
final int y_3=127;//ending y value
final int y_2=y_3;
int n=y_0;
final int LUT] =//look up table to normalize the values to vex motors
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 21, 21, 21, 22, 22, 22, 23, 24, 24,
25, 25, 25, 25, 26, 27, 27, 28, 28, 28,
28, 29, 30, 30, 30, 31, 31, 32, 32, 32,
33, 33, 34, 34, 35, 35, 35, 36, 36, 37,
37, 37, 37, 38, 38, 39, 39, 39, 40, 40,
41, 41, 42, 42, 43, 44, 44, 45, 45, 46,
46, 47, 47, 48, 48, 49, 50, 50, 51, 52,
52, 53, 54, 55, 56, 57, 57, 58, 59, 60,
61, 62, 63, 64, 65, 66, 67, 67, 68, 70,
71, 72, 72, 73, 74, 76, 77, 78, 79, 79,
80, 81, 83, 84, 84, 86, 86, 87, 87, 88,
88, 89, 89, 90, 90,127,127,127
};
int] bezier;
bezier=new int[128];
int] normalized;
normalized=new int[128];
int] after;
after=new int[127];
//print y for every integer x
for(int i=0; i<y_0; i++)
bezier*=0;
for(double t=0; t<=1; t+=PRECISION)
{
x=(1-t)*((1-t)*((1-t)*x_0+t*x_1)+t*((1-t)*x_1+t*x_2))+t*((1-t)*((1-t)*x_1+t*x_2)+t*((1-t)*x_2+t*x_3));
y=(1-t)*((1-t)*((1-t)*y_0+t*y_1)+t*((1-t)*y_1+t*y_2))+t*((1-t)*((1-t)*y_1+t*y_2)+t*((1-t)*y_2+t*y_3));
xr=x%1;
if(xr>=.5)
xr=1-xr;//rounding
if(xr<xrPrev)
dip=0;//the dip in the graph of xr has not happened yet
if(xr>xrPrev&&dip==0)
{
bezier[n]=(int)Math.round(yPrev);
n++;
dip++;
}
xPrev=x;
xrPrev=xr;
yPrev=y;
}
for(int i=0; i<127; i++)
normalized*=LUT[bezier[i]];
for(int i=127; i>0; i--)//prints after
after*=-1*normalized[127-i];
for(int i=0; i<127; i++)
{
System.out.printf("%4d", after*);
System.out.print(",");
if((i+1)%10==0)
System.out.println();
}
System.out.println();
for(int i=0; i<=127; i++)//prints before
{
System.out.printf("%4d", normalized*);
System.out.print(",");
if((i+1)%10==0)
System.out.println();
}
}
}
{
-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,
-127,-127,-127,-127, -90, -90, -90, -90, -89, -89,
-89, -88, -88, -88, -87, -87, -87, -86, -86, -84,
-84, -83, -81, -80, -79, -78, -77, -76, -73, -72,
-72, -70, -67, -67, -65, -64, -62, -60, -58, -57,
-56, -54, -52, -51, -50, -48, -47, -46, -45, -44,
-43, -42, -41, -40, -39, -38, -38, -37, -37, -36,
-35, -35, -34, -33, -32, -32, -31, -31, -30, -30,
-29, -28, -28, -28, -27, -27, -26, -25, -25, -25,
-25, -25, -24, -24, -24, -23, -22, -22, -22, -22,
-22, -22, -21, -21, -21, -21, -21, -21, -21, -21,
-21, -21, -21, -21, -21, -21, -21, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
22, 22, 23, 24, 24, 24, 25, 25, 25, 25,
25, 26, 27, 27, 28, 28, 28, 29, 30, 30,
31, 31, 32, 32, 33, 34, 35, 35, 36, 37,
37, 38, 38, 39, 40, 41, 42, 43, 44, 45,
46, 47, 48, 50, 51, 52, 54, 56, 57, 58,
60, 62, 64, 65, 67, 67, 70, 72, 72, 73,
76, 77, 78, 79, 80, 81, 83, 84, 84, 86,
86, 87, 87, 87, 88, 88, 88, 89, 89, 89,
90, 90, 90, 90, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127
}
this is the code (in java) that I used for calculating the bezier curve (top and bottom), and then normalizing it to vex motors using a look up table*****