Go to Post I enjoy the brainstorming that's going on here, you guys out think me most of the time. Keep it up. - fnsnet [more]
Home
Go Back   Chief Delphi > Technical > Programming > Java
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Reply
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 05-31-2010, 01:05 AM
biojae's Avatar
biojae biojae is offline
Likes Omni drives :)
AKA: Justin Stocking
FTC #5011 (BOT SQUAD) && FTC#72(Garage bots)&& FRC#0399 (Eagle Robotics)
Team Role: College Student
 
Join Date: Oct 2008
Rookie Year: 2008
Location: Lancaster
Posts: 276
biojae is a jewel in the roughbiojae is a jewel in the roughbiojae is a jewel in the rough
Refnum like interface for CANJaguars

*Note that I have not tested this yet*

After playing around with Labview a little bit, I learned that I liked the idea of Refnums (identifier strings that can be used to describe and identify objects).

And after using Java and CAN on this years robot, I wanted something that would not use the bus for every single call to the getter methods.

So, I made a simple class that uses a Hashtable (Stores the instances of CANJaguar with a unique and descriptive name (like a refnum)) and a TimerTask that updates the data in the local cache at around 50 hertz.

Here is a simple example that uses the class (a simple arcade drive teleoperated)

Code:
package edu.wpi.first.wpilibj.templates;

import edu.wpi.first.wpilibj.CAN.CANBus;
import edu.wpi.first.wpilibj.IterativeRobot;
import edu.wpi.first.wpilibj.Joystick;


public class RobotTemplate extends IterativeRobot {

    CANBus bus = new CANBus();

    Joystick arcade = new Joystick(1);

    public void robotInit()
    {
        bus.addJaguar("LeftDrive", 2);
        bus.addJaguar("RightDrive", 3);
    }

    
    public void autonomousPeriodic() {

    }

    public void teleopPeriodic() {

        // Arcade drive implementation
        double speed = -arcade.getY();
        double turn  = arcade.getX();

        double left = speed + turn;
        double right = speed - turn;

        if(left > 1){ left = 1;}
        else if(left < -1){ left = -1;}

        if(right > 1){ right = 1;}
        else if(right < -1){ right = -1;}
        // End arcade drive implementation

        bus.setPercentOutputVoltage("LeftDrive", left);
        bus.setPercentOutputVoltage("RightDrive", right);
    }
    
}
and here is the actual class (Note that I made a slight change to the JaguarCANProtocol class, I added
Code:
public static final int LM_STATUS_FAULT_BUSERR = 0xFF;
so that I could signal to the main execution loop that there was an error in either transmission or reception.):

Code:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package edu.wpi.first.wpilibj.CAN;

import java.util.Timer;
import edu.wpi.first.wpilibj.util.UncleanStatusException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.TimerTask;

/**
 * Keeps track of all CANJaguar instances on CAN bus using unique Names.
 * Use this to access information about a jaguar without acessing the bus directly
 * This is a local cache so that data from the bus is not accessed except by one thread.
 * Will update the data around 50 times a second depending on the # of devices
 *  on the bus, and on the device used to cummunocate with the Jaguars (ie 2CAN or black jag)
 *
 * As far as controlling the JAguar goes, this only supports the Voltage control mode (for now)
 * If other modes are needed, then use the getjaguar method.
 * (Note that controlling the jaguar outside of this class will not provide any exception handling)
 *
 * @author biojae
 */
public class CANBus
{
    // Keep an instance of each CANJaguar, (Generics not supported by squawk)
    private Hashtable devices = new Hashtable();
    // Keep a local copy of status information on each jaguar so as to reduce data throughput on CAN
    private Hashtable statuses = new Hashtable();
    //Update the device information ~50 times a second (depending on # of devices)
    private Timer updateThread;

    public CANBus()
    {
        TimerTask update = new TimerTask()
        {
            public void run()
            {
                for (Enumeration name = devices.keys() ; name.hasMoreElements() ;)
                {
                    String jagName = name.nextElement().toString();
                    CANJaguar currentJag = (CANJaguar) devices.get(jagName);
                    CANJaguarInfo currentInfo = (CANJaguarInfo) statuses.get(jagName);
                    try{
                        currentJag.set(currentInfo.outputPercentVoltage);
                        
                        currentInfo.BusVoltage = currentJag.getBusVoltage();
                        currentInfo.OutVoltage = currentJag.getOutputVoltage();
                        currentInfo.Temperature = currentJag.getTemperature();
                        currentInfo.outCurrent = currentJag.getOutputCurrent();
                        currentInfo.position = currentJag.getPosition();
                        currentInfo.speed = currentJag.getSpeed();
                        currentInfo.faults = currentJag.getFaults();
                    }catch(UncleanStatusException errorOnBus)
                    {
                        errorOnBus.printStackTrace();
                        currentInfo.faults = JaguarCANProtocol.LM_STATUS_FAULT_BUSERR;
                    }
                    statuses.put(jagName, currentInfo);
                }
            }
        };

       updateThread = new Timer();
       updateThread.scheduleAtFixedRate(update, 0, 20);

    }

    public void setPercentOutputVoltage(String name, double set)
    {
        if(statuses.contains(name))
        {
            ((CANJaguarInfo)statuses.get(name)).outputPercentVoltage = set;
        }
    }

    public boolean addJaguar(String name, int ID)
    {
        try{
            devices.put(name, new CANJaguar(ID));
            statuses.put(name, new CANJaguarInfo());
        }catch(UncleanStatusException CANBusError)
        {
            devices.remove(name);
            statuses.remove(name);
            CANBusError.printStackTrace();
            return false;
        }
        return true;
    }

    public double getTemperature(String name)
    {
        if(devices.contains(name))
        {
            return ((CANJaguarInfo)statuses.get(name)).Temperature;
        }
        return -1;
    }

    public double getBusVoltage(String name)
    {
        if(devices.contains(name))
        {
            return ((CANJaguarInfo)statuses.get(name)).BusVoltage;
        }
        return -1;
    }

    public double getOutputVoltage(String name)
    {
        if(devices.contains(name))
        {
            return ((CANJaguarInfo)statuses.get(name)).OutVoltage;
        }
        return -1;
    }

    public double getOutpuCurrent(String name)
    {
        if(devices.contains(name))
        {
            return ((CANJaguarInfo)statuses.get(name)).outCurrent;
        }
        return -1;
    }

    public double getPosition(String name)
    {
        if(devices.contains(name))
        {
            return ((CANJaguarInfo)statuses.get(name)).position;
        }
        return -1;
    }

    public double getSpeed(String name)
    {
        if(devices.contains(name))
        {
            return ((CANJaguarInfo)statuses.get(name)).speed;
        }
        return -1;
    }

    public short getFaults(String name)
    {
        if(devices.contains(name))
        {
            return ((CANJaguarInfo)statuses.get(name)).faults;
        }
        return -1;
    }

    public CANJaguar getJaguar(String name)
    {
        if(devices.contains(name))
        {
            return (CANJaguar) devices.get(name);
        }
        return null;
    }
}
__________________
FTC Team 72 - No site
FRC Team 399 - http://www.team399.org
2010 Rockwell Collins Innovation in Control Award - (Use of the CAN bus, among other reasons) Phoenix, Arizona!
Reply With Quote
Reply


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
ADXL345 SPI Accelerometer set/get Refnum Jon236 NI LabVIEW 3 02-16-2010 10:20 AM
Watchdog/Refnum/Labview Problems weinbergmath NI LabVIEW 2 02-13-2010 11:24 AM
Problems with RefNum Registry get vi zebrabots NI LabVIEW 3 02-02-2010 10:16 PM
Refnum Defining Pausert NI LabVIEW 15 01-21-2010 09:45 PM
refnum registry location Wendy Holladay NI LabVIEW 1 01-17-2010 10:11 PM


All times are GMT -5. The time now is 07:36 AM.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi