Go to Post only here would you find someone calling a motor cute.... - Denman [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 31-03-2011, 19:12
pigpc1993 pigpc1993 is offline
Registered User
AKA: Colin Feeney
FRC #3716 (WARP)
Team Role: Programmer
 
Join Date: Jan 2011
Rookie Year: 2009
Location: Manhasset, NY
Posts: 41
pigpc1993 is an unknown quantity at this point
Line Following

Our line following code works great until it start going straight. The speed has a sudden jolt and then gets off track. We tried setting the speed as low as .05 and yet it still jolts the same amount

Drive Method
Code:
public class Drive implements Mechanism{
    private static final double SPEED_STOP            =  0.0;
    private static final double SPEED_FWD_MAX         =  -.2;
    private static final double SPEED_REV_MAX         = .2;
    RobotDrive m_drive = new RobotDrive(2,1,4,3);
    DStation d = new DStation();

    public Drive(){
        m_drive.setInvertedMotor(RobotDrive.MotorType.kFrontRight, true);
        m_drive.setInvertedMotor(RobotDrive.MotorType.kRearRight, true);
    }
    public void initialize(){
        stop();
    }

    public void run(double x, double y){
    }
    
    public void joystick(double x, double y){
        m_drive.arcadeDrive(y, x);
        d.toLCDLine(2, "" + x);
        d.toLCDLine(3, "" + y);
    }
    
     public void stop(){
        m_drive.arcadeDrive(SPEED_STOP,SPEED_STOP,false);
    }

    public void goForward() {
        m_drive.arcadeDrive(SPEED_FWD_MAX, SPEED_STOP, false);
    }

    public void goBackward() {
        m_drive.arcadeDrive(SPEED_REV_MAX, SPEED_STOP, false);
    }
    public void goLeft() {
        m_drive.arcadeDrive(SPEED_STOP, -SPEED_FWD_MAX, false);
    }
    public void goRight() {
        m_drive.arcadeDrive(SPEED_STOP, -SPEED_REV_MAX, false);
    }
    public void goRightBackward() {
        m_drive.arcadeDrive(SPEED_REV_MAX, SPEED_FWD_MAX, false);
    }
    public void goLeftBackward() {
        m_drive.arcadeDrive(SPEED_REV_MAX, SPEED_REV_MAX, false);
    }
    public void goForwardLeft() {
        m_drive.arcadeDrive(SPEED_FWD_MAX, SPEED_FWD_MAX, false);
    }
    public void goForwardRight() {
        m_drive.arcadeDrive(SPEED_FWD_MAX, SPEED_REV_MAX, false);
    }
}
Line Follow Method
Code:
public class LightSensor extends Maneuver {

    DigitalInput l1;
    DigitalInput l2;
    DigitalInput l3;
    Drive drive;
    DStation station;

    public LightSensor(DigitalInput l1, DigitalInput l2, DigitalInput l3, Drive drive,DStation station,  Maneuver pass, Maneuver fail, Maneuver timeout,
            double maxTime){
        super(pass, fail, timeout, maxTime);
        this.drive = drive;
        this.station = station;
        this.l1 = l1;
        this.l2 = l2;
        this.l3 = l3;

    }

    public void run(){

            station.toLCDLine(2, l1.get() + "");
            station.toLCDLine(3, l2.get() + "");
            station.toLCDLine(4, l3.get() + "");
        if((l1.get() == false) && (l2.get() == true) && (l3.get() == false)){
            drive.goForward();
        }
        else if((l1.get() == false) && (l2.get() == false) && (l3.get() == true)){
            drive.goRight();
        }
        else if((l1.get() == true) && (l2.get() == false) && (l3.get() == false)){
            drive.goLeft();
        }
        else if((l1.get() == true) && (l2.get() == true) && (l3.get() == true)){
            drive.stop();
        }
        else{
                drive.goRight();
        }
    }

    public void stop(){
        drive.stop();
            station.toLCDLine(1, "Stop");
    }
Reply With Quote
  #2   Spotlight this post!  
Unread 31-03-2011, 22:25
youxinche95 youxinche95 is offline
Registered User
AKA: Eugene Che
FRC #0649 (MSET)
Team Role: Programmer
 
Join Date: Jan 2011
Rookie Year: 2010
Location: Saratoga, CA
Posts: 18
youxinche95 is an unknown quantity at this point
Re: Line Following

do you have a method that you can supply the cartesian x and y. I looked at your Drive method, and there is an arcadeDrive() that accepts an x and and y and a boolean... not sure what the boolean does, but oh well, it seems to be all set to false. I assume the line trackers are assembled in a linear fashion as in

FRONT
|
1 2 3
|
CENTER

Anyways, It looks as though you have a mecanum drive so you can strafe...

Anyways, try this pseudocode out.

double myX = 0;
double myY = 0.5; //some constant forward velocity
if(l1.get()) { //if a boolean returns true, ie the get(), go into if
myX -= 0.5; //0.5 is just some horizontal feed for motors.
if(13.get()) { //no need for == true
myX += 0.5;
if(l2.get()) {
myX /= 2; // close to lining up to line, so slow down
if(l1.get() && l2.get() && l3.get()) {
myY = 0;

arcadeDrive(myY, myX, false);

This was really quickly made, so I'm not sure if it will work... anyways, good luck
Reply With Quote
  #3   Spotlight this post!  
Unread 01-04-2011, 11:46
pigpc1993 pigpc1993 is offline
Registered User
AKA: Colin Feeney
FRC #3716 (WARP)
Team Role: Programmer
 
Join Date: Jan 2011
Rookie Year: 2009
Location: Manhasset, NY
Posts: 41
pigpc1993 is an unknown quantity at this point
Re: Line Following

Quote:
Originally Posted by youxinche95 View Post
do you have a method that you can supply the cartesian x and y. I looked at your Drive method, and there is an arcadeDrive() that accepts an x and and y and a boolean... not sure what the boolean does, but oh well, it seems to be all set to false. I assume the line trackers are assembled in a linear fashion as in

FRONT
|
1 2 3
|
CENTER

Anyways, It looks as though you have a mecanum drive so you can strafe...

Anyways, try this pseudocode out.

double myX = 0;
double myY = 0.5; //some constant forward velocity
if(l1.get()) { //if a boolean returns true, ie the get(), go into if
myX -= 0.5; //0.5 is just some horizontal feed for motors.
if(13.get()) { //no need for == true
myX += 0.5;
if(l2.get()) {
myX /= 2; // close to lining up to line, so slow down
if(l1.get() && l2.get() && l3.get()) {
myY = 0;

arcadeDrive(myY, myX, false);

This was really quickly made, so I'm not sure if it will work... anyways, good luck
Thanks for the help. I don't know much about the drive. Right now we are using a kitbot so we can finish up the code so we can apply it all at the competition. I'll let you know how it goes. Thanks again.
Reply With Quote
  #4   Spotlight this post!  
Unread 01-04-2011, 13:06
Jared Russell's Avatar
Jared Russell Jared Russell is offline
Taking a year (mostly) off
FRC #0254 (The Cheesy Poofs), FRC #0341 (Miss Daisy)
Team Role: Engineer
 
Join Date: Nov 2002
Rookie Year: 2001
Location: San Francisco, CA
Posts: 3,080
Jared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond repute
Re: Line Following

Unless your line sensors are really far apart (and even if they are), it will always be possible for two of the three to see the line at once. You don't seem to have coded logic to take care of this case.

For example, currently, if your LEFT and MIDDLE see the tape, but the right does not, you would turn right with the code you posted. Is this really what you want?

If you start driving straight but then seem to veer off to the side, perhaps this is the issue?
Reply With Quote
  #5   Spotlight this post!  
Unread 01-04-2011, 13:10
pigpc1993 pigpc1993 is offline
Registered User
AKA: Colin Feeney
FRC #3716 (WARP)
Team Role: Programmer
 
Join Date: Jan 2011
Rookie Year: 2009
Location: Manhasset, NY
Posts: 41
pigpc1993 is an unknown quantity at this point
Re: Line Following

Quote:
Originally Posted by Jared341 View Post
Unless your line sensors are really far apart (and even if they are), it will always be possible for two of the three to see the line at once. You don't seem to have coded logic to take care of this case.

For example, currently, if your LEFT and MIDDLE see the tape, but the right does not, you would turn right with the code you posted. Is this really what you want?

If you start driving straight but then seem to veer off to the side, perhaps this is the issue?
Maybe. I'll do some testing today. I'll keep you guys posted.
Reply With Quote
  #6   Spotlight this post!  
Unread 01-04-2011, 23:38
Fletch1373's Avatar
Fletch1373 Fletch1373 is offline
Registered User
AKA: Fletch
FRC #3181 (Panthers)
Team Role: Mentor
 
Join Date: Jan 2008
Rookie Year: 2004
Location: Rochester, NY
Posts: 251
Fletch1373 has much to be proud ofFletch1373 has much to be proud ofFletch1373 has much to be proud ofFletch1373 has much to be proud ofFletch1373 has much to be proud ofFletch1373 has much to be proud ofFletch1373 has much to be proud ofFletch1373 has much to be proud ofFletch1373 has much to be proud ofFletch1373 has much to be proud of
Re: Line Following

What is the reasoning for inverting the front-right and back-left motors? Was youxinche95 correct that you're using mecanum wheels? If so, there are drive functions available in the WPILib Library to handle that.


Going on the assumption that you are using mecanum, I would recommend reading about these functions in the RobotDrive class: mecanumDrive_Polar and mecanumDrive_Cartesian. With either of these, you specify a direction vector(in either X- and Y-speed values, or as separate magnitude and direction).

You can simply strafe to the right or left, or rotate independent of direction depending on the values returned from the line sensors.

As for testing for all possible cases, you would have to write a lot of code... or would you?

While working with my team, 3555 and also a rookie this year, the programmers and I decided to figure out all possible cases and when they could happen. Knowing that we have 3 sensors that return boolean true/false values, we can use simple algebra to calculate the number of possible cases as 2^3 or 8. We also decided that a switch-case statement would work best to allow us to group similar cases together(such as left only and left/middle being tripped both telling the robot it has to move left). In order to use the switch-case, we need all the sensor values to be packed together into a single variable.

Now converting from boolean to integer is kinda weird in Java. (int)l1.get() doesn't work... from what I've found, the simplest way to do it would be with a ternary operator(don't know what this is? then run away while you still can....). For anyone that doesn't know, a ternary operator takes a condition statement and does something based on it's result, all on a single line(basically it's an if-else, but all on one line... and makes sight-reading of code very difficult sometimes[usually])... So to build our packed variable, we took 3 ternary operators, bit-shifted them to the appropriate place, then bitwise-OR'd them together.
Code:
int lineL = ((L1.get())?1:0);
int lineM = ((L2.get())?1:0);
int lineR = ((L3.get())?1:0);
int line = lineL<<2 | lineM<<1 | lineR;
After this, we can use the line variable in our switch statement. Our cases are the base-10 integer representation of the 3bit packed variable(0,1,2,3,4,5,6,7). Doing some simple binary conversions(and leaving comments with them already done), allows you to organize your cases in a logical way(if you plan to group them at least. Otherwise order doesn't matter.). Just remember not to include a break; for the cases you plan to group. When they are used the program can run down the list executing code for the similar case instead(so you don't have to write the code multiple times).
Code:
switch(line)
{
case 4:          // 1_0_0
   // notice no break
case 6:          // 1_1_0
   // do some code
   break;
<insert more cases>
}
__________________
Student:
<04: FRC0213> <05-08: FRC1373>
Mentor:
<09-10: FRC0809> <11-12: FRC3555> <12-14: FRC0073> <15-??: FRC3181>
Volunteer:
<FTAA> <CSA> <Defense Coordinator> <Scorekeeper> <Robot Inspector> <Official Scorer>
2016 Tour:
CTWAT [DefCoord] > Pittsburgh[Mentor/DefCoord] > TVR[FTAA] > FLR[CSA] > NE DCMP[CSA] > CMP[CSA]
Reply With Quote
  #7   Spotlight this post!  
Unread 02-04-2011, 12:10
pigpc1993 pigpc1993 is offline
Registered User
AKA: Colin Feeney
FRC #3716 (WARP)
Team Role: Programmer
 
Join Date: Jan 2011
Rookie Year: 2009
Location: Manhasset, NY
Posts: 41
pigpc1993 is an unknown quantity at this point
Re: Line Following

Quote:
Originally Posted by Fletch1373 View Post
What is the reasoning for inverting the front-right and back-left motors? Was youxinche95 correct that you're using mecanum wheels? If so, there are drive functions available in the WPILib Library to handle that.


Going on the assumption that you are using mecanum, I would recommend reading about these functions in the RobotDrive class: mecanumDrive_Polar and mecanumDrive_Cartesian. With either of these, you specify a direction vector(in either X- and Y-speed values, or as separate magnitude and direction).

You can simply strafe to the right or left, or rotate independent of direction depending on the values returned from the line sensors.

As for testing for all possible cases, you would have to write a lot of code... or would you?

While working with my team, 3555 and also a rookie this year, the programmers and I decided to figure out all possible cases and when they could happen. Knowing that we have 3 sensors that return boolean true/false values, we can use simple algebra to calculate the number of possible cases as 2^3 or 8. We also decided that a switch-case statement would work best to allow us to group similar cases together(such as left only and left/middle being tripped both telling the robot it has to move left). In order to use the switch-case, we need all the sensor values to be packed together into a single variable.

Now converting from boolean to integer is kinda weird in Java. (int)l1.get() doesn't work... from what I've found, the simplest way to do it would be with a ternary operator(don't know what this is? then run away while you still can....). For anyone that doesn't know, a ternary operator takes a condition statement and does something based on it's result, all on a single line(basically it's an if-else, but all on one line... and makes sight-reading of code very difficult sometimes[usually])... So to build our packed variable, we took 3 ternary operators, bit-shifted them to the appropriate place, then bitwise-OR'd them together.
Code:
int lineL = ((L1.get())?1:0);
int lineM = ((L2.get())?1:0);
int lineR = ((L3.get())?1:0);
int line = lineL<<2 | lineM<<1 | lineR;
After this, we can use the line variable in our switch statement. Our cases are the base-10 integer representation of the 3bit packed variable(0,1,2,3,4,5,6,7). Doing some simple binary conversions(and leaving comments with them already done), allows you to organize your cases in a logical way(if you plan to group them at least. Otherwise order doesn't matter.). Just remember not to include a break; for the cases you plan to group. When they are used the program can run down the list executing code for the similar case instead(so you don't have to write the code multiple times).
Code:
switch(line)
{
case 4:          // 1_0_0
   // notice no break
case 6:          // 1_1_0
   // do some code
   break;
<insert more cases>
}
I'm sorry but I don't understand what a Mecanum drive is exactly. I'm going to research it. Anyway we found out what our problem was. youxinche95 was correct with the else statement and we also had a bad Victor. Apparently it smoked at one point or another and was only able to go at full power even after multiple calibration attempts. I don't understand why it happened like that. We tried running it again after calibration and it started smoking more so we replaced it. Thanks for the help guys.

Edit:
I looked at pictures and information about Mecanum drives and we don't have that.

Last edited by pigpc1993 : 02-04-2011 at 12:16.
Reply With Quote
  #8   Spotlight this post!  
Unread 02-04-2011, 22:47
youxinche95 youxinche95 is offline
Registered User
AKA: Eugene Che
FRC #0649 (MSET)
Team Role: Programmer
 
Join Date: Jan 2011
Rookie Year: 2010
Location: Saratoga, CA
Posts: 18
youxinche95 is an unknown quantity at this point
Re: Line Following

Glad to be of assistance. Go FIRST!
Reply With Quote
  #9   Spotlight this post!  
Unread 03-04-2011, 01:36
pigpc1993 pigpc1993 is offline
Registered User
AKA: Colin Feeney
FRC #3716 (WARP)
Team Role: Programmer
 
Join Date: Jan 2011
Rookie Year: 2009
Location: Manhasset, NY
Posts: 41
pigpc1993 is an unknown quantity at this point
Re: Line Following

Quote:
Originally Posted by youxinche95 View Post
Glad to be of assistance. Go FIRST!
Thanks a lot again! We would have been in a little bit of trouble if we didn't figure this out since our competition is this week.
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


All times are GMT -5. The time now is 12:35.

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