Log in

View Full Version : CANJaguar


Kodiak
20-01-2012, 15:12
Hello,
I am not new to Java, but I am new to the code for the wpi, so I was looking at the API and was especially looking at CANJaguar. My question is that in order to use CAN, do I make an instance of CANJaguar for each jaguar used, or is it only one instance, and I make an instance of Jaguar for the amount used? Also would I need to use it within the drive train? In the end, I am pretty much asking how to set up CAN withing Java.

WizenedEE
20-01-2012, 15:17
The CANJaguar class represents a jaguar. So yes, you need one for each physical jaguar. To set up the drive train, you create all of the jaguars needed and then call the robotDrive constructor with each of the jaguars.

For programming, the only practical difference between CANJaguar and Jaguar is that CANJaguar has more methods (for things like setting PID constants), so if you find a tutorial on how to set things up with normal Jaguars, you just replace the class names with CANJaguar and you should be set.

Kodiak
20-01-2012, 15:22
Awesome, that makes it much simpler, also on the ID, its the id you issue the Jaguar when you update the firmware correct? or is in in order they are setup along the CAN

WizenedEE
20-01-2012, 15:52
It's the one where you set the number and then press the button on the jaguar (the ID). The order makes absolutely no difference (except for the whole "wire can't be too long" thing)

Kodiak
20-01-2012, 16:35
Ha, how can the wire be too long? on such a short distance with data flying at 1mbs and the Jaguars acting as switches. Also I would like your input on this, for Joystick input, would it be best on Periodic or Continuous?

Bryscus
20-01-2012, 17:37
Ha, how can the wire be too long? on such a short distance with data flying at 1mbs and the Jaguars acting as switches. Also I would like your input on this, for Joystick input, would it be best on Periodic or Continuous?

It possibly has to do with loading down the CAN cable driver. I think the total cable length is something like 20' if I remember right. One suggestion was to buy a 20' cable and use it. If you need more, you've used too much.

Read joystick should probably go in Periodic. Continuous will read the joystick as fast as possible. Periodic will read the joystick at precise intervals (200Hz I think). Honestly, in reference to the system response time of "Joystick moved -> Joystick value read -> Joystick value interpreted -> Motor value sent -> Motor starts moving", the moving of the motor is the longest part (by quite a bit).

Running in continuous only makes more requests and sends more control packets (unnecessarily) utilizing more system bandwidth.

- Bryce

Kodiak
20-01-2012, 17:49
It possibly has to do with loading down the CAN cable driver. I think the total cable length is something like 20' if I remember right. One suggestion was to buy a 20' cable and use it. If you need more, you've used too much.

Read joystick should probably go in Periodic. Continuous will read the joystick as fast as possible. Periodic will read the joystick at precise intervals (200Hz I think). Honestly, in reference to the system response time of "Joystick moved -> Joystick value read -> Joystick value interpreted -> Motor value sent -> Motor starts moving", the moving of the motor is the longest part (by quite a bit).

Running in continuous only makes more requests and sends more control packets (unnecessarily) utilizing more system bandwidth.

- Bryce

I agree, and I was looking at the code, and its at 50hz, just in case you where curious, and about the CAN, I guess it can be looked at it just like in Networking, but what I think they may mean about being too long is the distance of wire used between one Jaguar to the next and maybe not meant in total distance, which sounds the same but its not, lol.

dyanoshak
20-01-2012, 18:26
Ha, how can the wire be too long? on such a short distance with data flying at 1mbs and the Jaguars acting as switches. Also I would like your input on this, for Joystick input, would it be best on Periodic or Continuous?

I guess it can be looked at it just like in Networking, but what I think they may mean about being too long is the distance of wire used between one Jaguar to the next and maybe not meant in total distance, which sounds the same but its not, lol.

Bryscus is correct:

It possibly has to do with loading down the CAN cable driver. I think the total cable length is something like 20' if I remember right. One suggestion was to buy a 20' cable and use it. If you need more, you've used too much.

It is in fact 20' total, not the maximum between each Jaguar. The Jaguars aren't switches or repeaters, the left and right CAN ports are wired directly to each other on the Jaguar circuit board.

This 20' limitation does have to do with the CAN driver:

When all the Jaguars are responding at the same time to broadcast messages they drive the bus slightly higher than a single Jag would. It takes longer for the bus to return to 'zero' and therefor some Jaguars may not read the bit correctly if the bit hasn't had time to settle.

The time from high to low depends on the termination resistance as well. This is the reason why we also specify a 100 ohm termination resistor. It helps snap the bus back to zero quickly so there aren't any bit timing errors.

We found that 20' of cable, 100 ohm termination resistors, and ~16 Jags on a bus is a good limit for reliable operation. It may be possible to get more Jags, but the cable lengths will have to be shorter.

-David

Kodiak
20-01-2012, 18:30
Bryscus is correct:



It is in fact 20' total, not the maximum between each Jaguar. The Jaguars aren't switches or repeaters, the left and right CAN ports are wired directly to each other on the Jaguar circuit board.

This 20' limitation does have to do with the CAN driver:

When all the Jaguars are responding at the same time to broadcast messages they drive the bus slightly higher than a single Jag would. It takes longer for the bus to return to 'zero' and therefor some Jaguars may not read the bit correctly if the bit hasn't had time to settle.

The time from high to low depends on the termination resistance as well. This is the reason why we also specify a 100 ohm termination resistor. It helps snap the bus back to zero quickly so there aren't any bit timing errors.

We found that 20' of cable, 100 ohm termination resistors, and ~16 Jags on a bus is a good limit for reliable operation. It may be possible to get more Jags, but the cable lengths will have to be shorter.

-David

Awesome, great information! thanks for the clarification.

kingkurry
20-01-2012, 18:59
How do we know if we have regular jaguars or CAN jaguars? Also, if we use jaguars does this mean we actually need to declare 4 jaguar instances to drive the robot? Can we do something like


public void robotInit() {
RobotDrive robot = new RobotDrive(1,2,3,4);
Joystick left = new Joystick(1);
Joystick right = new Joystick(2);

}
public void teleopPeriodic() {
robot.tankDrive(left.getThrottle(),(-1*right.getThrottle()));

}


or do we need to actually need to create jaguar instances and use them to drive the robot. If so, how would we do this?

Kodiak
20-01-2012, 19:08
How do we know if we have regular jaguars or CAN jaguars? Also, if we use jaguars does this mean we actually need to declare 4 jaguar instances to drive the robot? Can we do something like


public void robotInit() {
RobotDrive robot = new RobotDrive(1,2,3,4);
Joystick left = new Joystick(1);
Joystick right = new Joystick(2);

}
public void teleopPeriodic() {
robot.tankDrive(left.getThrottle(),(-1*right.getThrottle()));

}


or do we need to actually need to create jaguar instances and use them to drive the robot. If so, how would we do this?

All jaguars both gray and black can use CAN, it is a diffrent way of sending information to them, instead of using the PWM cables you use a phone like cable. Both get the job done, just more accuracy and additional information about the controller while its running comes with the CAN.

And what I did with the jaguar is create an instance for each jaguar outside of any of the Init's. Then on the RobotInit(), I initialized them along with the drive train.


public class Team3325 extends IterativeRobot {

CANJaguar leftCANJaguarTop;
CANJaguar leftCANJaguarBottom;
CANJaguar rightCANJaguarTop;
CANJaguar rightCANJaguarBottom;
Joystick inputJoystick;
int leftCanTop = 1;
int leftCanBot = 2;
int rightCanTop = 3;
int rightCanBot = 4;
RobotDrive mechanumDrive;

public void robotInit() {

try {

leftCANJaguarTop = new CANJaguar(leftCanTop);
leftCANJaguarBottom = new CANJaguar(leftCanBot);
rightCANJaguarBottom = new CANJaguar(rightCanBot);
rightCANJaguarTop = new CANJaguar(rightCanTop);

inputJoystick = new Joystick(1);

mechanumDrive = new RobotDrive(leftCANJaguarTop, leftCANJaguarBottom, rightCANJaguarTop, rightCANJaguarBottom);

} catch (Exception e) {

System.out.println(e);
}
}

public void teleopPeriodic() {

try {

mechanumDrive.mecanumDrive_Cartesian(inputJoystick .getX(), inputJoystick.getY(), inputJoystick.getThrottle(), 0.0); //TODO <-- Fix Gyro to proper Param.


} catch (Exception e) {

System.out.println(e);
}
}
}



The code is a little dirty, but it works for testing purposes and can hopefully help you. In your case, if you didn't use CAN, you would have to replace CANJaguar with Jaguar and fix a few of the params respectively.

CodeYeti
20-01-2012, 19:08
Besides variables going out of scope, the code you have posed there would do ok. To answer your question about creating Jaguar instances, you can create a RobotDrive both ways

RobotDrive(int frontLeftMotor, int rearLeftMotor, int frontRightMotor, int rearRightMotor);

/* OR */

RobotDrive(SpeedController frontLeftMotor, SpeedController rearLeftMotor, SpeedController frontRightMotor, SpeedController rearRightMotor);


And whether you have CANJaguars or regular Jaguars all depends on how you have them hooked up. chances are, you have normal Jaguars. If you are using a PWM cable to hook the Jaguars to the digital module/sidecar, then you have regular Jaguars for sure.

EDIT: Also, its more common to use the y axis of each joystick to control motor speeds than it is the throttle, but obviously you can do whatever you wish.

Kodiak
20-01-2012, 19:16
Besides variables going out of scope, the code you have posed there would do ok. To answer your question about creating Jaguar instances, you can create a RobotDrive both ways

RobotDrive(int frontLeftMotor, int rearLeftMotor, int frontRightMotor, int rearRightMotor);

/* OR */

RobotDrive(SpeedController frontLeftMotor, SpeedController rearLeftMotor, SpeedController frontRightMotor, SpeedController rearRightMotor);


And whether you have CANJaguars or regular Jaguars all depends on how you have them hooked up. chances are, you have normal Jaguars. If you are using a PWM cable to hook the Jaguars to the digital module/sidecar, then you have regular Jaguars for sure.

EDIT: Also, its more common to use the y axis of each joystick to control motor speeds than it is the throttle, but obviously you can do whatever you wish.

I agree, just threw this code together to please the Electrical crew, I planed to correctly do it being that I have more time :P

kingkurry
20-01-2012, 19:49
Thank you for your replies. No matter what we try we cannot seem to get our robot to move. This is the code I have been trying:

package edu.wpi.first.wpilibj.templates;


import edu.wpi.first.wpilibj.IterativeRobot;
import edu.wpi.first.wpilibj.Joystick;
import edu.wpi.first.wpilibj.RobotDrive;
import edu.wpi.first.wpilibj.Solenoid;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.Watchdog;
import edu.wpi.first.wpilibj.SpeedController;
import edu.wpi.first.wpilibj.Jaguar;

public class RobotTemplate extends IterativeRobot {
RobotDrive robot;
Joystick left;
Joystick right;

public void robotInit() {


robot = new RobotDrive(1,2,3,4);
left = new Joystick(1);
right = new Joystick(2);
System.out.println("RobotInit() completed.");
}

public void autonomousPeriodic() {

}

public void teleopPeriodic() {
//robot.tankDrive(left.getThrottle(),(-1*right.getThrottle()));
//robot.tankDrive(left, right);

robot.tankDrive(2,2);

//System.out.println("left:"+left.getThrottle());
//System.out.println("right:"+right.getThrottle());
//System.out.println("LMAG:"+ left.getMagnitude());
//System.out.println("RMAG:"+ right.getMagnitude());

}

}


the getThrottle() method always returns a 0 regardless of what we do to the joystick. The getMagnitude() method show change as we move the joystick. However, what worries me is that the robot doesn't seem to move even if i input doubles into the tankDrive() method. The jaguars lights should stop blinking and become solid when they are receiving a signal right? They never seem to do this and stay blinking no matter what.

Kodiak
20-01-2012, 20:24
The jaguars lights should stop blinking and become solid when they are receiving a signal right?

Yes that is correct. What if you where to make an instance of the Jaguars with their Channel and the location of the module, and place that inside of the drive train, is it the same result?

kingkurry
20-01-2012, 21:06
Yes I tried that as well. I declared 4 of them. Something along the lines of

SpeedController frontLeft = new Jaguar(1,1);
SpeedController rearLeft = new Jaguar(1,2);
SpeedController frontRight = new Jaguar(1,3);
SpeedController rearRight = new Jaguar(1,4);

To be honest, I am not entirely sure what the slot number on the chassis is supposed to signify, so i just used 1 because that seems to be what everyone used in the examples i have seen. For the channel number, I used the PWM slot number i connected each jaguar to on the digital side car.

Then I used the set method, passing in the throttle value from a joystick, to set the speeds. Then I passed the speed controllers into the tankDrive() method.

One more thing that i have noticed is that the the green diagnostic light in the driver station diagnostic console doesnt change color to blue when i move the sticks. It does, however, change color when i press buttons on the stick. Does this have any significance?

nickpeq
20-01-2012, 21:17
Yes I tried that as well. I declared 4 of them. Something along the lines of

SpeedController frontLeft = new Jaguar(1,1);
SpeedController rearLeft = new Jaguar(1,2);
SpeedController frontRight = new Jaguar(1,3);
SpeedController rearRight = new Jaguar(1,4);

To be honest, I am not entirely sure what the slot number on the chassis is supposed to signify, so i just used 1 because that seems to be what everyone used in the examples i have seen. For the channel number, I used the PWM slot number i connected each jaguar to on the digital side car.

Then I used the set method, passing in the throttle value from a joystick, to set the speeds. Then I passed the speed controllers into the tankDrive() method.

One more thing that i have noticed is that the the green diagnostic light in the driver station diagnostic console doesnt change color to blue when i move the sticks. It does, however, change color when i press buttons on the stick. Does this have any significance?
If the code isn't working, try removing the slot number. Instantiate your Jaguars with only the PWM number. Also, I've never used "SpeedController x = new Jaguar(etc)". I believe I always use "Jaguar x = new Jaguar(blah)"... If that makes any difference.
And the dashboard is just like that. No real significance. It changes color only for button-presses.

Kodiak
20-01-2012, 21:22
If the code isn't working, try removing the slot number. Instantiate your Jaguars with only the PWM number. Also, I've never used "SpeedController x = new Jaguar(etc)". I believe I always use "Jaguar x = new Jaguar(blah)"... If that makes any difference.
And the dashboard is just like that. No real significance. It changes color only for button-presses.

I do what nick does, works just fine for me, and for Java I think the Digital Side car module is on the second slot and for Labview the 4th one, maybe you have one of the modules wrong?

CodeYeti
21-01-2012, 00:31
We had some problems with things getting initiated at the beginning of the year because some standards have changed with regards to the numbering of the modules. Your digital module should be in slot 2, and then you should just remove the slot number from the lines that instantiate the motors. Also, how to OTHER things connected to the sidecar work? I saw a person earlier today that had a faulty ribbon cable.

Mike Copioli
21-01-2012, 10:14
Bryscus is correct:

We found that 20' of cable, 100 ohm termination resistors, and ~16 Jags on a bus is a good limit for reliable operation. It may be possible to get more Jags, but the cable lengths will have to be shorter.

-David

David,

I have to disagree with you on this. According to CAN spec IS0 11898:1993(E) Table 15, the maximum cable distance for 1Mbit/second is 40 Meters not 20 feet.

We have also tested at distances much greater than 20 feet without issue using 120 Ohm's of termination on each end of the BUS.

FYI a termination resistor of 100 ohms is outside of the spec. Teams using 120 ohms resistors should have no issues related to signal reflection.

Bryscus
21-01-2012, 21:52
David,

I have to disagree with you on this. According to CAN spec IS0 11898:1993(E) Table 15, the maximum cable distance for 1Mbit/second is 40 Meters not 20 feet.

We have also tested at distances much greater than 20 feet without issue using 120 Ohm's of termination on each end of the BUS.

FYI a termination resistor of 100 ohms is outside of the spec. Teams using 120 ohms resistors should have no issues related to signal reflection.

From the getting started guide:

Total Cable Length
(maximum)
20 ft / 6.1m Tip: Start with this length of bulk cable and cut all
segments from it to ensure compliance.

Termination Resistance 100 At each end of the network.

Just quoting specs.

- Bryce

Kodiak
22-01-2012, 01:22
Total Cable Length
(maximum)
20 ft / 6.1m Tip: Start with this length of bulk cable and cut all
segments from it to ensure compliance.

Termination Resistance 100 At each end of the network.

Just quoting specs.

Hmm, it may be that 20 feet is the best length for the best outcome, but if you need more it may not be THE limit.

otherguy
22-01-2012, 13:15
To be honest, I am not entirely sure what the slot number on the chassis is supposed to signify, so i just used 1 because that seems to be what everyone used in the examples i have seen. For the channel number, I used the PWM slot number i connected each jaguar to on the digital side car.


For 2012 I believe the Java methods referring to "Slot" numbers essentially mean the instance of the particular card you are trying to access. I think the same is true for how LabVIEW is identifying the modules. For example: in the 8 or 4 slot cRIO chassis the DIO module in slot position two would be identified to the program as "Slot" 1. A second DIO module in slot position 4 (on the cRIO II) or slot position 6 (on the cRIO) would be identified to the program as "Slot" 2.

I think this deviates from what "Slot" meant in the past: the actual physical position the card was at (i.e. slot 4 of 8 for previous years was the slot for the first DIO module)

Again this is just what I remember from beta test, and what I've observed from my testing. If I'm wrong, let me know so I can avoid headaches down the road. :o

Mike Copioli
22-01-2012, 14:54
From the getting started guide:

Total Cable Length
(maximum)
20 ft / 6.1m Tip: Start with this length of bulk cable and cut all
segments from it to ensure compliance.

Termination Resistance 100 At each end of the network.

Just quoting specs.

- Bryce

The 'Getting Started Guide' is not the CAN spec, IS0 11898:1993(E) is.

kingkurry
22-01-2012, 15:20
If the code isn't working, try removing the slot number. Instantiate your Jaguars with only the PWM number. Also, I've never used "SpeedController x = new Jaguar(etc)". I believe I always use "Jaguar x = new Jaguar(blah)"... If that makes any difference.
And the dashboard is just like that. No real significance. It changes color only for button-presses.

I just tried instantiating the jaguars without a slot number. This didn't work either. This is the code I have been trying. I have also tried all the code that I commented out, still without results


package edu.wpi.first.wpilibj.templates;


import edu.wpi.first.wpilibj.IterativeRobot;
import edu.wpi.first.wpilibj.Joystick;
import edu.wpi.first.wpilibj.RobotDrive;
import edu.wpi.first.wpilibj.Solenoid;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.Watchdog;
import edu.wpi.first.wpilibj.SpeedController;
import edu.wpi.first.wpilibj.Jaguar;

public class RobotTemplate extends IterativeRobot {
RobotDrive robot;
Joystick left;
Joystick right;
Jaguar leftFront;
Jaguar leftRear;
Jaguar rightFront;
Jaguar rightRear;

public void robotInit() {
Jaguar leftFront = new Jaguar(1);
Jaguar leftRear= new Jaguar(2);
Jaguar rightFront= new Jaguar(3);
Jaguar rightRear= new Jaguar(4);

robot = new RobotDrive(leftFront,leftRear,rightFront,rightRear );

//robot = new RobotDrive(1,2,3,4);
left = new Joystick(1);
right = new Joystick(2);
System.out.println("RobotInit() completed.\n");
}

public void disabledContinuous(){
leftFront.set(1);
//robot.tankDrive(1,1);


}

public void disabledPeriodic(){
leftFront.set(1);
//robot.tankDrive(1,1);
}

public void autonomousPeriodic() {
leftFront.set(1);
//robot.tankDrive(1,1);

}

public void teleopContinuous(){
leftFront.set(1);
//robot.tankDrive(1,1);
}

public void teleopPeriodic() {
//robot.tankDrive(left.getThrottle(),(-1*right.getThrottle()));
leftFront.set(1);
//rightFront.set(right.getMagnitude());
//robot.tankDrive(leftFront.get(), rightFront.get());

//robot.tankDrive(left, right);
//robot.tankDrive(1,1);


//System.out.println("left:"+left.getThrottle());
//System.out.println("right:"+right.getThrottle());
//System.out.println("LMAG:"+ left.getMagnitude());
//System.out.println("RMAG:"+ right.getMagnitude());
//System.out.println("LRAD"+left.getDirectionDegrees());
//System.out.println("RRAD"+right.getDirectionDegrees());

System.out.println("Tank Drive");
}

}


As you can see, I have tried to create a robot drive specifying the pwm outputs, then driving it with tankDrive(2,2)

I have also tried creating jaguar objects and setting their speed manually. Again this did not work.

I even took a multimeter to my sidecar, testing each of the signal pins in both the 3 pin PWM and the 3 pin Digital I/O. No matter what code I tried, the signal pins never presented any current.

What do you guys think the problem could be? My code looks fine right? Could it be the ribbon cable connecting the cRIO to the sidecar?

Bryscus
22-01-2012, 17:02
The 'Getting Started Guide' is not the CAN spec, IS0 11898:1993(E) is.

Mike,

This wouldn't be the first time a device isn't fully compliant with a spec. One thing I've learned in the industry is that if you design a system to the spec of a bus and not that of a part you'll get burned every time - SPI, I2C, EBI, you name it. The reason microprocessors have so many options for these buses is that parts are so varied.

- Bryce

dyanoshak
22-01-2012, 17:37
David,

I have to disagree with you on this. According to CAN spec IS0 11898:1993(E) Table 15, the maximum cable distance for 1Mbit/second is 40 Meters not 20 feet.

We have also tested at distances much greater than 20 feet without issue using 120 Ohm's of termination on each end of the BUS.

FYI a termination resistor of 100 ohms is outside of the spec. Teams using 120 ohms resistors should have no issues related to signal reflection.

Yes, that is what the CAN spec says. However, I am talking about what we specify for Jaguar.

They differ in the following ways:

CAN Spec states 40 meter cable lengths using twisted pair cable

Jaguar uses non-twisted modular cable

CAN Spec states 120 ohm terminators

TI specifies 100 ohm terminators for the following reasons:


The concern is with bit timing, not signal reflections.

Ideally each Jaguar would be configured with its own specific bit-timing parameters (parameters that define when the CAN module samples the bit). These parameters depend on a lot of factors including location on the bus, bus impedance, the number of drivers on the bus, etc.

In this specific application (FRC) a lot of those factors are unknown. What works for one setup may not work as well for another. During our testing of Jaguar we found that as the number of Jaguars increased and the cable lengths got longer, some Jaguars would not sample the bits correctly. We saw that the bus was taking longer to transition from the dominant to recessive states fast enough when every CAN driver on the bus was driving dominant.

We were able to successfully improve the timing by lowering the resistance of the terminator to 100 ohms. The lower resistance helped pull the CANH and CANL to the recessive state much faster. We also found that minimizing the cable lengths between the Jaguars helped a bit too.

The bottom line:

TI specifies 100 ohm termination resistors and ~20' total of cabling. This differs from the official ISO specification for CAN, but should ensure that teams have the best experience with the Jaguar when using CAN.

-David

Mike Copioli
22-01-2012, 21:38
Yes, that is what the CAN spec says. However, I am talking about what we specify for Jaguar.

They differ in the following ways:

CAN Spec states 40 meter cable lengths using twisted pair cable

Jaguar uses non-twisted modular cable

CAN Spec states 120 ohm terminators

TI specifies 100 ohm terminators for the following reasons:


The concern is with bit timing, not signal reflections.

Ideally each Jaguar would be configured with its own specific bit-timing parameters (parameters that define when the CAN module samples the bit). These parameters depend on a lot of factors including location on the bus, bus impedance, the number of drivers on the bus, etc.

In this specific application (FRC) a lot of those factors are unknown. What works for one setup may not work as well for another. During our testing of Jaguar we found that as the number of Jaguars increased and the cable lengths got longer, some Jaguars would not sample the bits correctly. We saw that the bus was taking longer to transition from the dominant to recessive states fast enough when every CAN driver on the bus was driving dominant.

We were able to successfully improve the timing by lowering the resistance of the terminator to 100 ohms. The lower resistance helped pull the CANH and CANL to the recessive state much faster. We also found that minimizing the cable lengths between the Jaguars helped a bit too.

The bottom line:

TI specifies 100 ohm termination resistors and ~20' total of cabling. This differs from the official ISO specification for CAN, but should ensure that teams have the best experience with the Jaguar when using CAN.

-David

Dave,

Our findings tell a different story. I would be happy to share them with you.

otherguy
23-01-2012, 01:19
I just tried instantiating the jaguars without a slot number. This didn't work either. This is the code I have been trying. I have also tried all the code that I commented out, still without results


package edu.wpi.first.wpilibj.templates;


import edu.wpi.first.wpilibj.IterativeRobot;
import edu.wpi.first.wpilibj.Joystick;
import edu.wpi.first.wpilibj.RobotDrive;
import edu.wpi.first.wpilibj.Solenoid;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.Watchdog;
import edu.wpi.first.wpilibj.SpeedController;
import edu.wpi.first.wpilibj.Jaguar;

public class RobotTemplate extends IterativeRobot {
RobotDrive robot;
Joystick left;
Joystick right;
Jaguar leftFront;
Jaguar leftRear;
Jaguar rightFront;
Jaguar rightRear;

public void robotInit() {
Jaguar leftFront = new Jaguar(1);
Jaguar leftRear= new Jaguar(2);
Jaguar rightFront= new Jaguar(3);
Jaguar rightRear= new Jaguar(4);

robot = new RobotDrive(leftFront,leftRear,rightFront,rightRear );

//robot = new RobotDrive(1,2,3,4);
left = new Joystick(1);
right = new Joystick(2);
System.out.println("RobotInit() completed.\n");
}



I believe you have a scope problem.
You instantiate your jaguars as class variables (green lines), then create four new jaguar variables within the robotInit() method (red lines). You're not initializing the class variables as you may think. Basically you're telling the program that within the robotInit() class it should use the local copies of those Jag variables (red), instead of the ones the rest of the program knows about (green). Any reference to the Jag variables outside of the robotInit() method will refer to the ones that aren't initialized (green), and since they aren't initialized they won't be sending commands to any motor controllers.

Remove the "Jaguar" text thats highlighted red and that should fix your problem.

Read up on scope: http://sip.clarku.edu/tutorials/java/java.html#scope

Kodiak
23-01-2012, 02:11
I believe you have a scope problem.
You instantiate your jaguars as class variables (green lines), then create four new jaguar variables within the robotInit() method (red lines). You're not initializing the class variables as you may think. Basically you're telling the program that within the robotInit() class it should use the local copies of those Jag variables (red), instead of the ones the rest of the program knows about (green). Any reference to the Jag variables outside of the robotInit() method will refer to the ones that aren't initialized (green), and since they aren't initialized they won't be sending commands to any motor controllers.

Remove the "Jaguar" text thats highlighted red and that should fix your problem.

Read up on scope: http://sip.clarku.edu/tutorials/java/java.html#scope

Yup, he is right, you having that is like pretty much trying to make two jaguars of the same variable name, and in any programming language you can't simply do that.

otherguy
24-01-2012, 00:09
Yup, he is right, you having that is like pretty much trying to make two jaguars of the same variable name, and in any programming language you can't simply do that.

Just to be clear, you CAN do that in java, you're just not going to be referring to the same variable throughout the program. If every variable name had to be completely unique, you wouldn't be able to use the same variable names as any of the variables used in the classes you import. For any large scale program it would get difficult pretty quickly to keep track of what variable names were used where.

His code will compile and run as it was, it's just not going to do what he expected it to.

Kodiak
24-01-2012, 09:55
Just to be clear, you CAN do that in java, you're just not going to be referring to the same variable throughout the program. If every variable name had to be completely unique, you wouldn't be able to use the same variable names as any of the variables used in the classes you import. For any large scale program it would get difficult pretty quickly to keep track of what variable names were used where.

His code will compile and run as it was, it's just not going to do what he expected it to.

True, I did not clarify correctly, I have a problem of doing that, my bad, haha

emusteve
25-01-2012, 14:39
Could someone kindly tell me where you found documentation on using CAN under Java? I've searched in the "Getting Started with JAVA", "WPI Robotics Library User’s Guide", and "WPI Library Cookbook" publications, but have somehow missed it if it is in there. Went back to First Forge, but couldn't locate any additional documentation that seemed like it would point me in the right direction.

If anyone knows of an example project, that would be appreciated as well.

Thanks,
Steve

nickpeq
25-01-2012, 18:36
Could someone kindly tell me where you found documentation on using CAN under Java? I've searched in the "Getting Started with JAVA", "WPI Robotics Library User’s Guide", and "WPI Library Cookbook" publications, but have somehow missed it if it is in there. Went back to First Forge, but couldn't locate any additional documentation that seemed like it would point me in the right direction.

If anyone knows of an example project, that would be appreciated as well.

Thanks,
Steve

This is the most I've ever been able to find: https://decibel.ni.com/content/docs/DOC-14865

Kodiak
25-01-2012, 20:39
Could someone kindly tell me where you found documentation on using CAN under Java? I've searched in the "Getting Started with JAVA", "WPI Robotics Library User’s Guide", and "WPI Library Cookbook" publications, but have somehow missed it if it is in there. Went back to First Forge, but couldn't locate any additional documentation that seemed like it would point me in the right direction.

If anyone knows of an example project, that would be appreciated as well.

Thanks,
Steve

http://www.wbrobotics.com/javadoc/index.html?edu/wpi/first/wpilibj/package-summary.html

That should also help some what.

emusteve
25-01-2012, 21:31
Thanks guys, I downloaded the NI doc and will look at that tonight.

I had found the wrobotics site via Google, but as I'm new to Java, it is still a bit cryptic to my eyes. I'm wondering where they found that reference. I do wish it gave some examples. Looks like it originated at WPI, but scouring FIRST Forge turned up nada. Thanks to them for putting it up.

I'll keep watching this thread to see what success you have. Share ours as well (assuming we achieve some.)

Thanks again,
Steve

otherguy
25-01-2012, 22:55
the info posted on the wrobotics site is called a JavaDoc, and it's a standard form of documentation that can be generated from JAva code automatically (as long as it'a commented properly). The JAvadocs for WPILib is distributed with the plugin package that you installed.

You can access these files locally on your machine by clicking the first logo in the bar at the top of NetBeans (Assuming that's what you're using), it should be the first link on the page that loads.

Check out some helpful guides on my teams site on:
Getting started with Java: Lecture 1 (http://team2168.org/index.php/resources/programming/84-an-introduction-to-java-programming), Lecture 2 (http://team2168.org/index.php/resources/programming/97-an-introduction-to-java-programming-lecture-2)
JavaDocs: Intro/Setup (http://team2168.org/index.php/resources/programming/89-frc-java-api-documentation), Use (http://team2168.org/index.php/resources/programming/89-frc-java-api-documentation)
CAN Jaguars (http://team2168.org/index.php/resources/electrical/210-can-jaguars)

You're going to want to focus on the CANJaguar class.

Use is as simple as placing the following lines in the right places in your code.

import edu.wpi.first.wpilibj.CANJaguar;
CANJaguar leftMotor = new CanJaguar(12); //where 12 is the CAN ID assigned to the motor controller
leftMotor.set(x.x); //where x.x is a value between -1.0 and 1.0 (or your joystick axis...)


Note the default mode of operation is %VBus, which is comparable to PWM, read up on our site and the NI docs to learn about the other modes of operation if that's your goal.