Log in

View Full Version : Limit Swtich Help


curtis0gj
04-02-2015, 17:16
Hi guys, our team is trying to use a limit switch to stop the lifting mech powered by 2 victor motor controllers from bottoming out or flying off the top. But I can't get the switch to work properly.


public class Robot extends SampleRobot {

RobotDrive robot;
Joystick stick;
Joystick xbox;

Victor victor1;
Victor victor2;
DigitalInput limit;


boolean limitPressed = false;

boolean buttonPressedForwardVictor = false;

public Robot() {

robot = new RobotDrive(0, 1);
stick = new Joystick(1);
xbox = new Joystick(0);

limit = new DigitalInput(4);

victor1 = new Victor(4);
victor2 = new Victor(5);

}

public void operatorControl() {

while (isOperatorControl() && isEnabled()) {

stick.getThrottle();
robot.arcadeDrive(stick.getY(), stick.getX());
Timer.delay(0.1);

if(limit.get()) {

limitPressed = true;

}

if(limitPressed = true) {

victor1.set(0);
victor2.set(0);

}

if (xbox.getRawButton(4)) {

victor1.set(1);
victor2.set(1);
buttonPressedForwardVictor = true;

} else if (buttonPressedForwardVictor = true) {

victor1.set(0);
victor2.set(0);
buttonPressedForwardVictor = false;
}

if (xbox.getRawButton(1)) {

victor1.set(-1);
victor2.set(-1);
}


}

}

Jon Stratis
04-02-2015, 17:21
You need to use "==" inside of an if statement to get a Boolean. A single "=" is an assignment operation and won't do what you want it to do.

curtis0gj
04-02-2015, 17:38
You need to use "==" inside of an if statement to get a Boolean. A single "=" is an assignment operation and won't do what you want it to do.

No luck with that but I did make those changes.

Ether
04-02-2015, 17:39
A single "=" is an assignment operation and won't do what you want it to do.

True. (Hey, a little Boolean humor there).

You need to use "==" inside of an if statement to get a Boolean.

You don't need "==" to return a Boolean: a single "=" inside an if() statement will indeed return a Boolean. But as you said above, not what the OP was expecting.

If you already have an appropriately-named Boolean variable, you can cleanly code it by simply testing the variable:

if (limitPressed) {...}

curtis0gj
04-02-2015, 18:12
True. (Hey, a little Boolean humor there).



You don't need "==" to return a Boolean: a single "=" inside an if() statement will indeed return a Boolean. But as you said above, not what the OP was expecting.

If you already have an appropriately-named Boolean variable, you can cleanly code it by simply testing the variable:

if (limitPressed) {...}




So I will keep my if statements to one =. The limit switch is still not working here is a link for a picture of it. http://imgur.com/nRB3VqN. We used ground and signal from our pwm and it goes to DIO 4.

Ether
04-02-2015, 18:15
So I will keep my if statements to one =.

You did not read my post very carefully.

curtis0gj
04-02-2015, 18:19
You did not read my post very carefully.



Oh sorry I miss read that reply I understand now, my bad

Jon Stratis
04-02-2015, 18:50
Ok, some analysis of the logic.

First, the only place you set limitPressed to false is at the very beginning. by having
if(limit.get()) {

limitPressed = true;

}
in operatorControl, this means that once the limit switch is pressed, limitPressed will ALWAYS be true - there is nothing to set it to false later.

Also, there is an interesting case where you hit the limit switch, so you set them to 0, but if you're still holding button 4 you then immediately set them to 1. What happens is you start to quickly oscillate between setting the motors to 0 and 1 as long as both button 4 and the limit switch is pressed.

Now, a note about how limit switches work (I'm afraid I can't view the picture from where I am... it's blocked by the school's connection). There are two ways to wire them, and they act exactly opposite in code. If you wire signal and ground to the common/normally open connectors, the switch will be TRUE when not touched, and FALSE when pressed. Connect between the common/normally closed connectors, and it operates the other way.

So, here's some code that should help:


//ensure that limitPressed is true only when the limit switch is pressed
limitPressed = limit.get();

//output the value of limitPressed so we can verify proper functionality of the limit switch
System.out.println(“limitPressed=“ + limitPressed);


//if we hit the limit switch, stop all motion
if (limitPressed)
{
victor1.set(0);
victor2.set(0);
}
//otherwise, if we hit button 4 move forward
else if (xbox.getRawButton(4))
{
victor1.set(1);
victor2.set(1);
}
//otherwise, if we aren’t pressing anything don’t move.
else
{
victor1.set(0);
victor2.set(0);
}


This code only works to power the motors in a single direction, with the assumption that moving in that direction will trigger the limit switch. Without knowing the exact setup, I can't be sure about powering in both directions and stopping at both limits... I'll leave the other direction up to you.

Note a couple of things in the code:

First, I'm writing the value of the limitPressed variable to the console. This will let you look in the RIOLog to see what it is at all times - before moving anything, try manually pressing it and see how the value changes. You want to make sure this works before doing anything else!

Next, ALL of the controls for the motors are contained in a single if/else-if block. This means that only one of them will be active at a time. The default state (the final else) is to stop the motors - if you aren't touching anything, they'll stop. The limit switch control comes first to ensure that, if the limit switch is pressed, it absolutely doesn't move.

Give that a try, see if it helps, and see if you can figure out the other direction from there!

mmaunu
04-02-2015, 19:03
Edit: ninja'd by Jon Stratis. I think that we are saying the same basic things. I'll leave it in case...



You don't need "==" to return a Boolean: a single "=" inside an if() statement will indeed return a Boolean. But as you said above, not what the OP was expecting.



Actually, in Java, a single "=" does not return a boolean value. If you are assigning to a boolean value, then you will get the newly assigned value (which would actually be a boolean of course), but if you are assigning to an int or some other type, then the result is actually the value assigned.

For example:

boolean b = < something >

if( b = true )


The boolean expression evaluates to true in Java because you assigned true to the variable.

A different example:

int x = < something >

if( x = 8 )


The above will not compile because the value of the expression "x = 8" is actually the integer 8. This is what also allows you to do things like:


int a = < something >

int b = a = 9;


This gives a the value of 9 and then uses that assigned value to assign 9 to b. (Replace "a = 9" with 9.)

As for the original question/concern, have you tested that the get() method on the limit switch returns true when the limit switch is pushed? Depending on how you wire it (at least the ones that we have used in the past), you can get either true when the switch is triggered and false when it is not OR you can get false when the switch is triggered and true when it is not.

You also never set the limitPressed variable back to false; once set to true, limitPressed seems to remain true until you restart the robot.

Finally, if the limit switch is supposed to cancel the action that the joystick's button is performing, then you might want to change:

if (xbox.getRawButton(4)) {

victor1.set(1);
victor2.set(1);
buttonPressedForwardVictor = true;

}

so that it includes a test for the limit switch. Assuming that limitPressed is only true when the limit switch is activated, you could try a condition like:

if (xbox.getRawButton(4) && limitPressed == false) {

Without that extra condition, your logic is setting the motors to stop (above this line, where you check for the limitPressed value) and then you re-check the button...which re-sets the motors to run at full speed if the button is still engaged. The condition for running the motors needs to check the state of the button and the state of the limit switch. Another option is to use an else-if on the button condition so that you either set the victors to a value of 0 or set them to a value of 1 but not both.


if(limitPressed = true) {

victor1.set(0);
victor2.set(0);

}

else if (xbox.getRawButton(4)) {

victor1.set(1);
victor2.set(1);
buttonPressedForwardVictor = true;

}


I apologize if that was a bit scattered. Good luck and ask if anything/everything is unclear.

Ether
04-02-2015, 19:15
If you are assigning to a boolean value, then you will get the newly assigned value (which would actually be a boolean of course)

That was the context for the discussion.

if (limitPressed = true)

will return a boolean: it will always return "true" regardless of the value of limitPressed prior to the test.

curtis0gj
04-02-2015, 21:27
Ok, some analysis of the logic.

First, the only place you set limitPressed to false is at the very beginning. by having
if(limit.get()) {

limitPressed = true;

}
in operatorControl, this means that once the limit switch is pressed, limitPressed will ALWAYS be true - there is nothing to set it to false later.

Also, there is an interesting case where you hit the limit switch, so you set them to 0, but if you're still holding button 4 you then immediately set them to 1. What happens is you start to quickly oscillate between setting the motors to 0 and 1 as long as both button 4 and the limit switch is pressed.

Now, a note about how limit switches work (I'm afraid I can't view the picture from where I am... it's blocked by the school's connection). There are two ways to wire them, and they act exactly opposite in code. If you wire signal and ground to the common/normally open connectors, the switch will be TRUE when not touched, and FALSE when pressed. Connect between the common/normally closed connectors, and it operates the other way.

So, here's some code that should help:


//ensure that limitPressed is true only when the limit switch is pressed
limitPressed = limit.get();

//output the value of limitPressed so we can verify proper functionality of the limit switch
System.out.println(“limitPressed=“ + limitPressed);


//if we hit the limit switch, stop all motion
if (limitPressed)
{
victor1.set(0);
victor2.set(0);
}
//otherwise, if we hit button 4 move forward
else if (xbox.getRawButton(4))
{
victor1.set(1);
victor2.set(1);
}
//otherwise, if we aren’t pressing anything don’t move.
else
{
victor1.set(0);
victor2.set(0);
}


This code only works to power the motors in a single direction, with the assumption that moving in that direction will trigger the limit switch. Without knowing the exact setup, I can't be sure about powering in both directions and stopping at both limits... I'll leave the other direction up to you.

Note a couple of things in the code:

First, I'm writing the value of the limitPressed variable to the console. This will let you look in the RIOLog to see what it is at all times - before moving anything, try manually pressing it and see how the value changes. You want to make sure this works before doing anything else!

Next, ALL of the controls for the motors are contained in a single if/else-if block. This means that only one of them will be active at a time. The default state (the final else) is to stop the motors - if you aren't touching anything, they'll stop. The limit switch control comes first to ensure that, if the limit switch is pressed, it absolutely doesn't move.

Give that a try, see if it helps, and see if you can figure out the other direction from there!

Thank you so much, our team has been struggling along in the programming department this year mostly because I am the only programmer and it is my first year programming in java. But this is a great help and I think I will be far more confident when using booleans in the future. I will post an update tomorrow afternoon regarding the limit switch status, thanks! :]

curtis0gj
04-02-2015, 22:15
I have setup the limit switch program with the suggestions but I am attempting to setup reverse for the victors. Also I am trying to setup the same if statement layout for my relays does this look okay?

public class Robot extends SampleRobot {
RobotDrive robot;
Joystick stick;
Joystick xbox;
Relay spike1;
Relay spike2;
Victor victor1;
Victor victor2;
DigitalInput limit;
boolean limitPressed = false;

public Robot() {
robot = new RobotDrive(0, 1);
stick = new Joystick(1);
xbox = new Joystick(0);
spike1 = new Relay(0);
spike2 = new Relay(1);
limit = new DigitalInput(4);
victor1 = new Victor(4);
victor2 = new Victor(5);
}
public void operatorControl() {

while (isOperatorControl() && isEnabled()) {
stick.getThrottle();
robot.arcadeDrive(stick.getY(), stick.getX());
limitPressed = limit.get(); //Do I want this out side of my while operator control loop?
System.out.println("limitPressed=" + limitPressed); //Read the RoboRIO log for some values before you go all out on your motors.

if(limitPressed) {
victor1.set(0);
victor2.set(0);
} else if (xbox.getRawButton(4)) {
victor1.set(1);
victor2.set(1);
} else {
victor1.set(0);
victor1.set(0);
}
if(xbox.getRawButton(1)) {
victor1.set(-1);
victor1.set(-1);
} else {
victor1.set(0);
victor2.set(0);
}
if(xbox.getRawButton(3)) {
spike1.set(Relay.Value.kForward);
spike2.set(Relay.Value.kForward);
} else {
spike1.set(Relay.Value.kOff);
spike2.set(Relay.Value.kOff);
}
if(xbox.getRawButton(2)) {
spike1.set(Relay.Value.kReverse);
spike2.set(Relay.Value.kReverse);
} else {
spike1.set(Relay.Value.kOff);
spike2.set(Relay.Value.kOff);
}
}
}

mmaunu
04-02-2015, 22:21
I have setup...

public class Robot extends SampleRobot {

if(limitPressed) {
victor1.set(0);
victor2.set(0);
} else if (xbox.getRawButton(4)) {
victor1.set(1);
victor2.set(1);
} else {
victor1.set(0);
victor1.set(0);
}
if(xbox.getRawButton(1)) {
victor1.set(-1);
victor1.set(-1);
} else {




A quick glance (I'll look longer later) shows that you have set victor1 twice in several places when you should be setting victor1 and victor2.

Ether: I have learned so much from reading your posts and papers over the years. I didn't intend to sound like I was correcting your post but merely adding explicit context for other readers.

curtis0gj
04-02-2015, 22:26
A quick glance (I'll look longer later) shows that you have set victor1 twice in several places when you should be setting victor1 and victor2.

Woops I will fix that up thanks.

cstelter
04-02-2015, 22:42
Ether: I have learned so much from reading your posts and papers over the years. I didn't intend to sound like I was correcting your post but merely adding explicit context for other readers.

I for one appreciated the post. As a C/C++ guy who only recently has been using java (and only WRT FRC), I would have expected


int x=0;
if(x=8)
{
}


to compile fine. I didn't realize the if statement was strongly typed to boolean in java (kind of would have expected it to be overloaded to many types or that there may be some sort of implicit conversion of int to boolean that would happen transparently.)

Of course had I tried to code it, eclipse/netbeans/whatever would have let me know I was wrong long before I tried compile.

Reminds me of the most 'duh' moment I ever had that IDE's don't tend to flag for us yet. I had coded something along the lines of

int x=0;
...
if(x==4 && something_else==2 && something_else==some_other_thing);
{
//some stuff to do
}

It took me the longest time to figure out why I kept entering the if clause even though I was nearly 100% certain that x was *not* 4 and thus the hypothesis should evaluate to false. Finally I put in a sanity check to print x and confirmed that I was right (x was not 4 and the full expression for the if evaluated to false). Only then was I able to see the error of my ways...

sorry to send this slightly off topic.... I did appreciate the points made thoug.

Ether
04-02-2015, 22:49
Ether: I have learned so much from reading your posts and papers over the years. I didn't intend to sound like I was correcting your post but merely adding explicit context for other readers.

Understood. The additional explanation you provided was appropriate and useful. Reps :-)

Jon Stratis
04-02-2015, 22:58
I have setup the limit switch program with the suggestions but I am attempting to setup reverse for the victors. Also I am trying to setup the same if statement layout for my relays does this look okay?

public class Robot extends SampleRobot {
RobotDrive robot;
Joystick stick;
Joystick xbox;
Relay spike1;
Relay spike2;
Victor victor1;
Victor victor2;
DigitalInput limit;
boolean limitPressed = false;

public Robot() {
robot = new RobotDrive(0, 1);
stick = new Joystick(1);
xbox = new Joystick(0);
spike1 = new Relay(0);
spike2 = new Relay(1);
limit = new DigitalInput(4);
victor1 = new Victor(4);
victor2 = new Victor(5);
}
public void operatorControl() {

while (isOperatorControl() && isEnabled()) {
stick.getThrottle();
robot.arcadeDrive(stick.getY(), stick.getX());
limitPressed = limit.get(); //Do I want this out side of my while operator control loop?
System.out.println("limitPressed=" + limitPressed); //Read the RoboRIO log for some values before you go all out on your motors.

if(limitPressed) {
victor1.set(0);
victor2.set(0);
} else if (xbox.getRawButton(4)) {
victor1.set(1);
victor2.set(1);
} else {
victor1.set(0);
victor1.set(0);
}
if(xbox.getRawButton(1)) {
victor1.set(-1);
victor1.set(-1);
} else {
victor1.set(0);
victor2.set(0);
}
if(xbox.getRawButton(3)) {
spike1.set(Relay.Value.kForward);
spike2.set(Relay.Value.kForward);
} else {
spike1.set(Relay.Value.kOff);
spike2.set(Relay.Value.kOff);
}
if(xbox.getRawButton(2)) {
spike1.set(Relay.Value.kReverse);
spike2.set(Relay.Value.kReverse);
} else {
spike1.set(Relay.Value.kOff);
spike2.set(Relay.Value.kOff);
}
}
}



The relays look good. In addition to double victor1's which have already been pointed out, consider the effect of pushing buttons 1 and 4 at the same time - you'll oscillate between full speed forward and full speed reverse. It's probably not a big deal, as your driver shouldn't be pushing them both at the same time anyways, but I personally like to prevent that sort of situation. Using some fairly simple logic, you can reduce everything dealing with the victors to a single if/else-if/else block. Something like:

if ()//the conditions you want it to go up
{
//go up
}
else if ()//the conditions you want it to go down
{
//go down
}
else
{
//stop
}


You can set up the conditionals using the AND (&&) operator, the OR (||) operator, and the not (!). For example, to say "when button 4 is pressed and the limit switch is not pressed", you would do "xbox.getRawButton(4) || !limitPressed". Figuring out how to use logic like this is a very powerful tool while programming!

mmaunu
04-02-2015, 23:37
For example, to say "when button 4 is pressed and the limit switch is not pressed", you would do "xbox.getRawButton(4) || !limitPressed". Figuring out how to use logic like this is a very powerful tool while programming!

Just to clarify for others, the condition would have && instead of ||:

xbox.getRawButton(4) && !limitPressed



which is what you said very clearly but we all get noise in our signal sometimes between the brain and the fingers :)

Reps from Ether! I am showing my students that one!!! You might have a little bit of a fan club here at Team 2485...we seriously owe a lot to you and it is a shame if I haven't said that and "thank you" before (which is probably the case as I am mainly a lurker...but I am working on it).

curtis0gj
05-02-2015, 06:32
The relays look good. In addition to double victor1's which have already been pointed out, consider the effect of pushing buttons 1 and 4 at the same time - you'll oscillate between full speed forward and full speed reverse. It's probably not a big deal, as your driver shouldn't be pushing them both at the same time anyways, but I personally like to prevent that sort of situation. Using some fairly simple logic, you can reduce everything dealing with the victors to a single if/else-if/else block. Something like:

if ()//the conditions you want it to go up
{
//go up
}
else if ()//the conditions you want it to go down
{
//go down
}
else
{
//stop
}


You can set up the conditionals using the AND (&&) operator, the OR (||) operator, and the not (!). For example, to say "when button 4 is pressed and the limit switch is not pressed", you would do "xbox.getRawButton(4) || !limitPressed". Figuring out how to use logic like this is a very powerful tool while programming!

So when I go to add my second limit switch for the top could I use if(limit || limit2) or do I need a new if statement? Also I have been trying to figure out how to covert my victor buttons to axis would this be the correct way,
if(xbox.getRawAxis(I need to check mapping)) {
victor 1.set(1);
victor2.set(1);
}

Jon Stratis
05-02-2015, 07:52
Good catch mmaunu... I can only blame Sleep deprivation from the build season :P

Curtis, that looks correct for dealing with two limit switches, good job!

If you want to control the victors with axis instead of buttons, you need to pay attention to what the return types are. A button returns a Boolean, true or false, as it only has two states (pressed or not pressed). An axis from a joystick, however, returns a number between -1 and 1, indicating how far it is moved from the center. Treating that number like a Boolean in an if statement won't do what you want. Instead, you have three options:

Option 1 - turn the number into a Boolean value by using a comparison. You can say something like "if(axis > 0)" to indicate that you want to do something if the value of the axis is positive. Other handy comparisons are less than (<), equals (previously discussed, ==), and not equals (!=).

Option 2 - use the axis to give you variable speed control over the motor. By passing the axis directly into the motor, something like "victor1.set(axis)", the motor will go at a speed proportional to how far you move the joy stick, and it'll go both up and done with that one command! Also, if you let go of the joystick, it'll stop

Option 3 - this is kind of a combination of options 1 and 2 by using something called a ternary operator. A ternary operator is kind of like doing an if statement in a single line. An example would be "axis>0?1:0;". You can read this as " if the axis is greater than 0, then use the value 1, otherwise use the value 0". Everything before the question mark is your conditional. Everything between the question mark and the colon is what happens if true, and everything after the colon is what happens when false. So, if we always want the elevator moving at full speed, we could do something like "victor1.set(axis>0?1:axis<0?-1:0);". Here I strung two ternary operators together - if the axis is greater than 0, return 1, otherwise if the axis is less than 0 return -1, otherwise return 0. Many people find ternary operators confusing and non-intuitive, so don't feel bad about going with a more straightforward option!

Finally, a word of warning. Often when you let go of a joystick, it will return to something very close to 0, but not quite there. In all the examples above, I used an absolute 0 value for comparisons, which won't work unless the joystick returns to be perfectly centered! It's a lot better to use a "deadband" around 0 - go up if it's greater than 0.05, go down if less than -0.05, otherwise stop. That way if the joystick is close to center you'll stop.

curtis0gj
05-02-2015, 08:19
Good catch mmaunu... I can only blame Sleep deprivation from the build season :P

Curtis, that looks correct for dealing with two limit switches, good job!

If you want to control the victors with axis instead of buttons, you need to pay attention to what the return types are. A button returns a Boolean, true or false, as it only has two states (pressed or not pressed). An axis from a joystick, however, returns a number between -1 and 1, indicating how far it is moved from the center. Treating that number like a Boolean in an if statement won't do what you want. Instead, you have three options:

Option 1 - turn the number into a Boolean value by using a comparison. You can say something like "if(axis > 0)" to indicate that you want to do something if the value of the axis is positive. Other handy comparisons are less than (<), equals (previously discussed, ==), and not equals (!=).

Option 2 - use the axis to give you variable speed control over the motor. By passing the axis directly into the motor, something like "victor1.set(axis)", the motor will go at a speed proportional to how far you move the joy stick, and it'll go both up and done with that one command! Also, if you let go of the joystick, it'll stop

Option 3 - this is kind of a combination of options 1 and 2 by using something called a ternary operator. A ternary operator is kind of like doing an if statement in a single line. An example would be "axis>0?1:0;". You can read this as " if the axis is greater than 0, then use the value 1, otherwise use the value 0". Everything before the question mark is your conditional. Everything between the question mark and the colon is what happens if true, and everything after the colon is what happens when false. So, if we always want the elevator moving at full speed, we could do something like "victor1.set(axis>0?1:axis<0?-1:0);". Here I strung two ternary operators together - if the axis is greater than 0, return 1, otherwise if the axis is less than 0 return -1, otherwise return 0. Many people find ternary operators confusing and non-intuitive, so don't feel bad about going with a more straightforward option!

Finally, a word of warning. Often when you let go of a joystick, it will return to something very close to 0, but not quite there. In all the examples above, I used an absolute 0 value for comparisons, which won't work unless the joystick returns to be perfectly centered! It's a lot better to use a "deadband" around 0 - go up if it's greater than 0.05, go down if less than -0.05, otherwise stop. That way if the joystick is close to center you'll stop.

So could I do something like

axis = Xbox.getRawAxis(someaxis); // Do I need float or double?

if(axis == 1) {
victor1.set(1);
victor2.set(1);
}
Sorry if thats way off Im still a bit confused.

Jon Stratis
05-02-2015, 09:19
So could I do something like

axis = Xbox.getRawAxis(someaxis); // Do I need float or double?

if(axis == 1) {
victor1.set(1);
victor2.set(1);
}
Sorry if thats way off Im still a bit confused.

Your getting there! It can be hard to learn this stuff remotely without someone experienced there to help.

Your code is actually really close. Joystick axis values are returned as doubles, but that's a good question! There is often a lot of confusion between float and double, as they appear to be basically the same. In situations like thiszits useful to look at the javadoc For the object your using. A quick search turned up a copy here: http://team2168.org/javadoc/ go there and click on "Joystick" in the class listing on the left. You can then scroll through all of the methods in the joystick class, find the one you're using, get a short description of it, and see its return type. Pretty handy!

With the code you posted, the elevator will go up only if you have the joystick pushed full forward so the return value is 1. Pushing it halfway, so you get 0.5, wouldn't move it. Additionally, if you aren't pushing perfectly straight, you won't get a return value of 1! Take a piece of graph paper, draw a set of axis, and then draw a circle with a radius of 1, centered on the origin. Everything inside that circle is a value that can be returned by the joystick. If you push the joystick forward, you could get 0 for the x axis and 1 for the y axis... Or you could get something just a little less than 1 for the y axis and a little greater or less than 0 for the x axis, if you aren't perfectly straight.

So the only problem with your code is that it demands perfection from the driver to work. It would be much better to do something like "axis > 0.5" (pick an appropriate number) so you have a range on the joystick where pushing it forward makes it move. That way your driver doesn't have to be perfect!

curtis0gj
05-02-2015, 11:48
Your getting there! It can be hard to learn this stuff remotely without someone experienced there to help.

Your code is actually really close. Joystick axis values are returned as doubles, but that's a good question! There is often a lot of confusion between float and double, as they appear to be basically the same. In situations like thiszits useful to look at the javadoc For the object your using. A quick search turned up a copy here: http://team2168.org/javadoc/ go there and click on "Joystick" in the class listing on the left. You can then scroll through all of the methods in the joystick class, find the one you're using, get a short description of it, and see its return type. Pretty handy!

With the code you posted, the elevator will go up only if you have the joystick pushed full forward so the return value is 1. Pushing it halfway, so you get 0.5, wouldn't move it. Additionally, if you aren't pushing perfectly straight, you won't get a return value of 1! Take a piece of graph paper, draw a set of axis, and then draw a circle with a radius of 1, centered on the origin. Everything inside that circle is a value that can be returned by the joystick. If you push the joystick forward, you could get 0 for the x axis and 1 for the y axis... Or you could get something just a little less than 1 for the y axis and a little greater or less than 0 for the x axis, if you aren't perfectly straight.

So the only problem with your code is that it demands perfection from the driver to work. It would be much better to do something like "axis > 0.5" (pick an appropriate number) so you have a range on the joystick where pushing it forward makes it move. That way your driver doesn't have to be perfect!


Will this work?

double axis = Xbox.getRawAxis(*));

if(axis > 0.5) {
victor1.set(1);
victor2.set(1);

}

Jon Stratis
05-02-2015, 11:54
That looks good to me. Give a try, see if it does what your expecting!

curtis0gj
05-02-2015, 13:06
That looks good to me. Give a try, see if it does what your expecting!

Okay thanks for the help so far I will test it tonight.

curtis0gj
05-02-2015, 16:34
I am having a problem where my relay is stuck in forward (showing a green light) or off (showing no light) when I press a button. Here's the code.
if(xbox.getRawButton(4)) {
spike1.set(Relay.Value.kForward);
spike2.set(Relay.Value.kForward);
} else if(xbox.getRawButton(1)) {
spike1.set(Relay.Value.kReverse);
spike2.set(Relay.Value.kReverse);
} else {
spike1.set(Relay.Value.kOff);
spike2.set(Relay.Value.kOff);
}
}
}

Jon Stratis
05-02-2015, 17:14
When I read that, it looks like it says "while button 4 is pushed, go forward. While button 1 is pushed, go in reverse. If neither button is pushed, stop" is that not what's happening? Your description of the behavior isn't really complete to tell us what you want to have happen.

Take a look at the user manual for the spike, found here: http://content.vexrobotics.com/docs/spike-blue-guide-sep05.pdf

It describes the operation of the LED. It's been a while since my team has used one, but I believe it says kForward is green, kReverse is red, kOff is Orange, kOn is blank.

Double check the wiring and make sure it isn't shorting something when you push button 1, I've seen a short cause the LED to turn off before.

curtis0gj
05-02-2015, 17:36
When I read that, it looks like it says "while button 4 is pushed, go forward. While button 1 is pushed, go in reverse. If neither button is pushed, stop" is that not what's happening? Your description of the behavior isn't really complete to tell us what you want to have happen.

Take a look at the user manual for the spike, found here: http://content.vexrobotics.com/docs/spike-blue-guide-sep05.pdf

It describes the operation of the LED. It's been a while since my team has used one, but I believe it says kForward is green, kReverse is red, kOff is Orange, kOn is blank.

Double check the wiring and make sure it isn't shorting something when you push button 1, I've seen a short cause the LED to turn off before.

The issue is when I press button 1 one relay goes in reverse and the other goes to kOn (LED BLANK) and when I press button 4 it goes in kForward(GREEN). Also the spike is stuck in kForward because it's always green unlike the other which is yellow.

Jon Stratis
05-02-2015, 17:48
Double check the orientation of the PWM wire, both in the spikes and in the relay ports on the RoboRio. I have a suspicion that one is plugged in backwards or in the wrong location all together.

curtis0gj
05-02-2015, 18:02
Double check the orientation of the PWM wire, both in the spikes and in the relay ports on the RoboRio. I have a suspicion that one is plugged in backwards or in the wrong location all together.

No I just checked everything looks good the black cable is closest to the edge on the roboRIO and it is facing the correct way on the spike.

mmaunu
05-02-2015, 18:17
The issue is when I press button 1 one relay goes in reverse and the other goes to kOn (LED BLANK) and when I press button 4 it goes in kForward(GREEN). Also the spike is stuck in kForward because it's always green unlike the other which is yellow.

I'm trying to figure out exactly what the behavior is that you are describing. I think it would help to use the two variable names like spike1 and spike2.

When you press button 1, spike1 goes in reverse and spike2 goes to kOn?

When you press button 4, which spike goes to kForward: spike1 or spike2? What does the other do?

Whichever goes to kForward, are you saying that it is now stuck in the kForward state no matter which buttons you push?

When you say yellow, is that possibly orange? The manual says that the possible colors are red, green, and orange. Do you see all three of those colors and a yellow?

In addition to checking the orientation of the PWM cable, check the power leads (both into the spikes and then out of the spikes) so that you are correctly getting power to power and ground to ground.

curtis0gj
05-02-2015, 21:35
I'm trying to figure out exactly what the behavior is that you are describing. I think it would help to use the two variable names like spike1 and spike2.

When you press button 1, spike1 goes in reverse and spike2 goes to kOn?

When you press button 4, which spike goes to kForward: spike1 or spike2? What does the other do?

Whichever goes to kForward, are you saying that it is now stuck in the kForward state no matter which buttons you push?

When you say yellow, is that possibly orange? The manual says that the possible colors are red, green, and orange. Do you see all three of those colors and a yellow?

In addition to checking the orientation of the PWM cable, check the power leads (both into the spikes and then out of the spikes) so that you are correctly getting power to power and ground to ground.

Sorry for the confusion, basically when I press button 1 spike1 goes in kReverse and this is good, however, spike2 sets it self to kOn(No LED). When I release button 1 spike1 goes to the orange color but spike2 goes in kForward. When I press button 4 spike1 goes in kForward and this intended but spike2 also is in kForward but it was not activated by the button because it is always in kForward unless I press button 1 then it enters kOn until I release the button.

Jon Stratis
05-02-2015, 22:07
This is really sounding like a wiring issue, it's definitely not something in the code you posted. Can you post a pic of your wiring?

curtis0gj
05-02-2015, 22:21
This is really sounding like a wiring issue, it's definitely not something in the code you posted. Can you post a pic of your wiring?

Tomorrow afternoon I will post one.

mmaunu
06-02-2015, 00:42
I agree 100% with Jon...you construct the two objects in the same way (so they should default to the same settings) and you call the same methods on the objects under the same conditions. When you look at the wires, check all power inputs and outputs as well as the PWM wires. I hate to be a software guy that blames the hardware, but...

curtis0gj
06-02-2015, 14:52
I agree 100% with Jon...you construct the two objects in the same way (so they should default to the same settings) and you call the same methods on the objects under the same conditions. When you look at the wires, check all power inputs and outputs as well as the PWM wires. I hate to be a software guy that blames the hardware, but...
I just pulled a spike out of last years bot and it works.

mmaunu
06-02-2015, 15:00
I just pulled a spike out of last years bot and it works.

Sweet! Congrats on successfully troubleshooting the problem. I hope that you haven't torn too much hair out :)

curtis0gj
06-02-2015, 17:58
Sweet! Congrats on successfully troubleshooting the problem. I hope that you haven't torn too much hair out :)

lol yeah It's just a part of the process I guess... anyway thanks for all of the help.

curtis0gj
06-02-2015, 21:36
I have one final question, I noticed that when my victors are set in reverse and I press the limit switch the victors don't stop very well. Is there anyway to fix this or is it fine the way it is. Here's the code


public void operatorControl() {

while (isOperatorControl() && isEnabled()) {
double leftaxis = xbox.getRawAxis(1);
robot.arcadeDrive(stick.getY() * 0.5, stick.getX() * 0.5); //Change the 0.5 for sensitivity, I removed get throttle I may need it again.
limitPressed = limit.get();
limitPressed2 = limit2.get();
limitPressed3 = limit3.get();
limitPressed4 = limit4.get();

/*limitPressed will be the bottom of the lead screw.
* limitPressed2 will be the top of the lead screw.
* limitPressed3 will the for the left minimum arm distance.
* limitPressed4 will be for the max arm distance.
* The print lines are helpful for testing boolean states.
//System.out.println("limitPressed=" + limitPressed); //Read the RoboRIO log for some values.
//System.out.println("limitPressed2=" + limitPressed2);
//System.out.println("limitPressed3=" + limitPressed3);
//System.out.println("limitPressd4=" + limitPressed4);
*/

if(limitPressed || limitPressed2 == false || limitPressed3 == false || limitPressed4 == false) {
victor1.set(0);
victor2.set(0);
} else if (-leftaxis > 0.5) {
victor1.set(1);
victor2.set(1);
} else {
victor1.set(0);
victor2.set(0);
}
if(leftaxis > 0.5) {
victor1.set(-1);
victor2.set(-1);
} else {
victor1.set(0);
victor2.set(0);
}
if(xbox.getRawButton(4)) {
spike1.set(Relay.Value.kForward);
spike2.set(Relay.Value.kForward);
} else if(xbox.getRawButton(1)) {
spike1.set(Relay.Value.kReverse);
spike2.set(Relay.Value.kReverse);
} else {
spike1.set(Relay.Value.kOff);
spike2.set(Relay.Value.kOff);
}
}
}

Ether
06-02-2015, 21:37
I have one final question, I noticed that when my victors are set in reverse and I press the limit switch the victors don't stop very well.

Is the jumper set for coast or brake? If coast, try changing it to brake.

curtis0gj
06-02-2015, 21:46
Is the jumper set for coast or brake? If coast, try changing it to brake.




Sorry, I hate to sound like a complete rookie but how can I change the jumpers setting?

Ether
06-02-2015, 21:56
Sorry, I hate to sound like a complete rookie but how can I change the jumpers setting?

Go to the VEX web site.

Type "Victor" into the search box.

Click on the link for Victor888 (or SP).

Find the link for the user manual and click on it.

Search for "brake".

Follow the instructions you find there.

curtis0gj
06-02-2015, 22:52
Go to the VEX web site.

Type "Victor" into the search box.

Click on the link for Victor888 (or SP).

Find the link for the user manual and click on it.

Search for "brake".

Follow the instructions you find there.




Thank's I will try the break setting on Monday.

Ether
06-02-2015, 23:27
Thank's I will try the break setting on Monday.

Stay away from the break setting. Try the brake setting instead.

Jon Stratis
06-02-2015, 23:40
While the brake setting will help, it may not be your issue. It depends on what, exactly, the behavior is.

Take a look at this portion of the code:
if(limitPressed || limitPressed2 == false || limitPressed3 == false || limitPressed4 == false) {
victor1.set(0);
victor2.set(0);
} else if (-leftaxis > 0.5) {
victor1.set(1);
victor2.set(1);
} else {
victor1.set(0);
victor2.set(0);
}
if(leftaxis > 0.5) {
victor1.set(-1);
victor2.set(-1);
} else {
victor1.set(0);
victor2.set(0);
}


There are two if/else blocks here. The first one controls going up, the second going down, I assume. However, your limit switch at the bottom of the lead screw is being checked in the first if statement. What this may be doing is telling your motors to stop in the first if statement, then in the second telling them to go down. So you end up with a fast oscillation between stop and down.

When I'm working with a motor, I try to combine all control of the motor into a single if/else block, or in a single set command, just to make sure I don't get into a situation where I'm telling it two different things every loop through.

For this situation, I might do something like:

if (operator says to go up AND I haven't hit the top limit switch yet)
{
go up
}
else if (operator says to go down AND I haven't hit the bottom limit switch yet)
{
go down
}
else
{
stop
}


Obviously, that's pseudocode... its up to you to figure out how to translate that to real code :)

Also, check the third and fourth limit switches... your comments say they are for controlling left to right motion of the gripper, but in your code they're set up to work with the up/down motion of the elevator. Are you controlling the left/right motion with the relays? If so, you'll want to work those into the if/else block that deals with the relays!

curtis0gj
07-02-2015, 10:33
While the brake setting will help, it may not be your issue. It depends on what, exactly, the behavior is.

Take a look at this portion of the code:

if(limitPressed || limitPressed2 == false || limitPressed3 == false || limitPressed4 == false) {
victor1.set(0);
victor2.set(0);
} else if (-leftaxis > 0.5) {
victor1.set(1);
victor2.set(1);
} else {
victor1.set(0);
victor2.set(0);
}
if(leftaxis > 0.5) {
victor1.set(-1);
victor2.set(-1);
} else {
victor1.set(0);
victor2.set(0);
}


There are two if/else blocks here. The first one controls going up, the second going down, I assume. However, your limit switch at the bottom of the lead screw is being checked in the first if statement. What this may be doing is telling your motors to stop in the first if statement, then in the second telling them to go down. So you end up with a fast oscillation between stop and down.

When I'm working with a motor, I try to combine all control of the motor into a single if/else block, or in a single set command, just to make sure I don't get into a situation where I'm telling it two different things every loop through.

For this situation, I might do something like:

if (operator says to go up AND I haven't hit the top limit switch yet)
{
go up
}
else if (operator says to go down AND I haven't hit the bottom limit switch yet)
{
go down
}
else
{
stop
}


Obviously, that's pseudocode... its up to you to figure out how to translate that to real code :)

Also, check the third and fourth limit switches... your comments say they are for controlling left to right motion of the gripper, but in your code they're set up to work with the up/down motion of the elevator. Are you controlling the left/right motion with the relays? If so, you'll want to work those into the if/else block that deals with the relays!

Okay so if I remember correctly I can use && for and so could I do something like this?

if(-axis > 0.5 && limitPressed2 == true) { //I am using true because the limit switch is off when open and on when closed
victor1.set(1);
victor2.set(1);
} else if(axis > 0.5 && limitPressed == false) {
victor1.set(-1);
victor2.set(-1);
}else {
victor1.set(0);
victor2.set(0);
} if(xbox.getRawButton(4) && limitPressed3 == true) {
spike1.set(Relay.Value.kForward);
spike2.set(Relay.Value.kForward);
} else if(xbox.getRawButton(1) && limitPressed 4 == true) {
spike1.set(Relay.Value.kReverse);
spike2.set(Relay.Value.kReverse);
} else {
spike1.set(Relay.Value.kOff);
spike1.set(Relay.Value.kOff);
}

curtis0gj
08-02-2015, 16:21
Jon Stratis, does this look okay I feel as if I don't need to set my limit switches to true/false in the if statements also should I add any timer delays?


public void operatorControl() {

while (isOperatorControl() && isEnabled()) {
double leftaxis = xbox.getRawAxis(1);
double rightaxis = xbox.getRawAxis(4);
double rightyaxis = xbox.getRawAxis(5);
robot.arcadeDrive(stick.getY() * 0.5, stick.getX() * 0.5); //Change the 0.5 for sensitivity, I removed get throttle I may need it again.
limitPressed = limit.get();
limitPressed2 = limit2.get();
limitPressed3 = limit3.get();
limitPressed4 = limit4.get();

/* REMINDER limitPressed is an opposite type of limit switch!
* victor1 and victor2 will power the lead screw.
* victor3 will open and close arms.
* limitPressed will be the bottom of the lead screw.
* limitPressed2 will be the top of the lead screw.
* limitPressed3 will the for the left minimum arm distance.
* limitPressed4 will be for the max arm distance.
* The print lines are helpful for testing boolean states.
//System.out.println("limitPressed=" + limitPressed); //Read the RoboRIO log for some values.
//System.out.println("limitPressed2=" + limitPressed2);
//System.out.println("limitPressed3=" + limitPressed3);
//System.out.println("limitPressd4=" + limitPressed4);
*/

if(-leftaxis > 0.5 && limitPressed2 == true) {
victor1.set(1);
victor2.set(1);
} else if(leftaxis > 0.5 && limitPressed == false) {
victor1.set(-1);
victor2.set(-1);
} else {
victor1.set(0);
victor2.set(0);
}

if(-rightyaxis > 0.5 && limitPressed4 == true) {
victor3.set(1);
} else if(rightyaxis > 0.5 && limitPressed3 == true) {
victor3.set(-1);
} else {
victor3.set(0);
}

if(-rightaxis > 0.5) {
spike1.set(Relay.Value.kForward);
spike2.set(Relay.Value.kForward);
} else if(rightaxis > 0.5) {
spike1.set(Relay.Value.kReverse);
spike2.set(Relay.Value.kReverse);
} else {
spike1.set(Relay.Value.kOff);
spike2.set(Relay.Value.kOff);
}
}
}

Jon Stratis
08-02-2015, 17:38
That looks great to me. I think it'll work great for you!

curtis0gj
08-02-2015, 17:41
That looks great to me. I think it'll work great for you!

Alright awesome thanks for all the help I will try it out tomorrow.