Go to Post Prototype! Always prototype, regardless how crazy! - onenerdyguy [more]
Home
Go Back   Chief Delphi > Technical > Programming
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Closed Thread
 
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 11-06-2010, 12:55
Ether's Avatar
Ether Ether is offline
systems engineer (retired)
no team
 
Join Date: Nov 2009
Rookie Year: 1969
Location: US
Posts: 8,077
Ether has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond repute
Re: no control of bot when kicker is operating

It sounds like your "driving" code has to wait for your "kicking" code to complete.

If this is the case, there are two (at least) different ways to solve this:

1) put your kicking code and driving code into separate tasks so that the OS can multitask them for you,

or

2) use a state machine for your kicker code, so that it doesn't bring everything to a halt while it's waiting for the delay
  #2   Spotlight this post!  
Unread 11-06-2010, 13:01
isaacdl isaacdl is offline
I have a white hat..it's just dirty
AKA: Isaac Dontje Lindell
FRC #3018 (Nordic Storm)
 
Join Date: Oct 2009
Rookie Year: 2010
Location: St. Peter
Posts: 32
isaacdl is an unknown quantity at this point
Re: no control of bot when kicker is operating

Quote:
Originally Posted by Ether View Post
It sounds like your "driving" code has to wait for your "kicking" code to complete.

If this is the case, there are two (at least) different ways to solve this:

1) put your kicking code and driving code into separate tasks so that the OS can multitask them for you,

or

2) use a state machine for your kicker code, so that it doesn't bring everything to a halt while it's waiting for the delay

We're trying option one right now, but having never had to program multiple threads, could you explain how to do it? We're trying various things we're finding on the internet, but none of it is exactly what we need.
If it matters, we're using SimpleRobotTemplate (so like Independent from LabView ) as opposed to IterativeRobot.
  #3   Spotlight this post!  
Unread 11-06-2010, 13:19
Ether's Avatar
Ether Ether is offline
systems engineer (retired)
no team
 
Join Date: Nov 2009
Rookie Year: 1969
Location: US
Posts: 8,077
Ether has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond repute
Re: no control of bot when kicker is operating

Quote:
Originally Posted by isaacdl View Post
We're trying option one right now, but having never had to program multiple threads, could you explain how to do it?
I wish I could give you more specific help, but I am unfamiliar with Java. I'm sure there's a way to do it. There are lots of good Java programmers on CD. One fellow is even currently writing a Java programming manual for FIRST:

http://www.chiefdelphi.com/forums/sh...ad.php?t=85836

maybe you could ask him.


~
  #4   Spotlight this post!  
Unread 11-06-2010, 21:34
buildmaster5000 buildmaster5000 is offline
Trying to program the swerve drive
AKA: Alex
FRC #2421 (Rolling Thunder Robotics)
Team Role: Alumni
 
Join Date: May 2009
Rookie Year: 2009
Location: Northern Virginia
Posts: 207
buildmaster5000 has much to be proud ofbuildmaster5000 has much to be proud ofbuildmaster5000 has much to be proud ofbuildmaster5000 has much to be proud ofbuildmaster5000 has much to be proud ofbuildmaster5000 has much to be proud ofbuildmaster5000 has much to be proud ofbuildmaster5000 has much to be proud of
Re: no control of bot when kicker is operating

Another option is to create a kickerLoops variable, and allow a certain loops to go by before operating your cylinders. We did this for our kicker and it worked great, but getting the initial setup/timing down might take a while.
__________________
-Alex



2010 Washington DC Regional: Engineering Excellence Award
  #5   Spotlight this post!  
Unread 11-06-2010, 21:50
synth3tk's Avatar
synth3tk synth3tk is offline
Volunteer / The Blue Alliance
AKA: David Thomas
no team
Team Role: Alumni
 
Join Date: Jan 2007
Rookie Year: 2007
Location: Ohio
Posts: 2,005
synth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond repute
Re: no control of bot when kicker is operating

Give me a few minutes, and I can pull up our code, which an on-hand programming helper at the regional assisted us with. We had that exact same issue.
  #6   Spotlight this post!  
Unread 11-06-2010, 22:03
synth3tk's Avatar
synth3tk synth3tk is offline
Volunteer / The Blue Alliance
AKA: David Thomas
no team
Team Role: Alumni
 
Join Date: Jan 2007
Rookie Year: 2007
Location: Ohio
Posts: 2,005
synth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond repute
Re: no control of bot when kicker is operating

Notes:

This is setup so that a button on a USB gamepad triggers the kicker.

Replace the sFire/sLatch/etc parts with your actual kicking code.

Depending on how your kicker works, you may need more or less "sections".

kickTime.start in the first block is required, and kickTimer.stop(); and kickTimer.reset();.

Code:
        // Set kicking loop to start when button 7 on gamepad is pressed and not in loop already
        Watchdog.getInstance().feed();
        if(gamePad.getRawButton(7) == true && kickTimer.get() == 0.0)
        {
            kickTimer.start();
            sFire.set(true);
            sLatch.set(false);

            sExt.set(true);
            sRet.set(false);
        }
        if (kickTimer.get() > 0.75 && kickTimer.get() < 1.05)
        {
            sFire.set(true);
            sLatch.set(false);

            sExt.set(false);
            sRet.set(true);
        }
        if (kickTimer.get() > 1.05 && kickTimer.get() < 1.35)
        {
            sFire.set(false);
            sLatch.set(true);

            sExt.set(false);
            sRet.set(true);
        }
        if (kickTimer.get() > 1.35)
        {
            sFire.set(false);
            sLatch.set(true);

            sExt.set(true);
            sRet.set(false);
            kickTimer.stop();
            kickTimer.reset();
        }
  #7   Spotlight this post!  
Unread 11-06-2010, 22:59
Ether's Avatar
Ether Ether is offline
systems engineer (retired)
no team
 
Join Date: Nov 2009
Rookie Year: 1969
Location: US
Posts: 8,077
Ether has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond repute
Re: no control of bot when kicker is operating

What you've posted is essentially a state machine, where the state variable is the value of kickTimer.

A generic state machine might look like this:


Quote:
// Set kicking loop to start when button 7 on gamepad is pressed and not in loop already


switch(kickState) {

case 0: // kicking is not in progress

if(gamePad.getRawButton(7) == true) {
start_the_kick_sequence_and_initialize_variables_a s_necessary();
kickState = 1;
}
break;

case 1:

if case_1_timer_or_event_has occurred(){
perform_case_1_action();
initialize_variables_for_case_2_as_necessary();
kickState=2;
}
break;

case 2:

if case_2_timer_or_event_has occurred(){
perform_case_2_action();
initialize_variables_for_case_3_as_necessary();
kickState=3;
}
break;

.
.
.


case n:

if case_n_timer_or_event_has occurred(){
perform_casen2_action();
initialize_variables_for_case_0_as_necessary();
kickState=0;
}
break;

}

The above has the advantage that it's a little easier to see how to use events (like limit switches etc) to change states, instead of being strictly timer-based.


~

Last edited by Ether : 12-06-2010 at 00:53.
  #8   Spotlight this post!  
Unread 12-06-2010, 00:44
synth3tk's Avatar
synth3tk synth3tk is offline
Volunteer / The Blue Alliance
AKA: David Thomas
no team
Team Role: Alumni
 
Join Date: Jan 2007
Rookie Year: 2007
Location: Ohio
Posts: 2,005
synth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond repute
Re: no control of bot when kicker is operating

Thanks for the suggestions. I should have also stated:

I'm a non-student member (I guess a mentor, in some ways), and our team is extremely small. I couldn't even coerce any students to learn programming, so I had to learn Java with some small help from the team mentor (who knew very little more about Java than I did) and the internet starting 2 days from Kick-Off.

We were just getting the bare minimum working. But I'll keep that in mind for the future, if/when we teach the new programmers.
  #9   Spotlight this post!  
Unread 12-06-2010, 16:16
frasnow's Avatar
frasnow frasnow is offline
Software
no team
Team Role: Mentor
 
Join Date: Jun 2010
Rookie Year: 2010
Location: Oregon
Posts: 83
frasnow is a splendid one to beholdfrasnow is a splendid one to beholdfrasnow is a splendid one to beholdfrasnow is a splendid one to beholdfrasnow is a splendid one to beholdfrasnow is a splendid one to beholdfrasnow is a splendid one to behold
Re: no control of bot when kicker is operating

One solution for solving this in Java is threads. Team 997’s kicker this year takes 4.5 seconds to reload. It was extremely important for us to make sure the driver maintained control during this time. I’ve copied in some of our code below and removed most of the extra stuff it for you to see how we did threading on our robot.

A couple things to keep in mind.
1. It is vital your each thread of execution have either a Thread.yield() and/or a Timer.delay(). These are required to ensure each thread gets time on the CPU. Otherwise one thread could starve (not get any time on the CPU).
2. Put things like kicking that take a long time in separate threads, but keep quick things in the main thread. I accidentally put our gear shift in the kicker thread and the driver couldn’t shift while the kicker was reloading. We fixed this after regionals.

Main thread that starts kicker thread:
Code:
public class RobotMain extends SimpleRobot {

    final int Preload = 1;
    final int Retract = 0;
    final int Latch = 1;
    final int Unlatch = 0;
    private Joystick leftStick = new Joystick(1);
    private Joystick rightStick = new Joystick(2);
    
    public RobotMain() {
    }

  
    public void operatorControl() {
        
        getWatchdog().setEnabled(true);
       
        KickerThread kickerThread = new KickerThread(this);
        kickerThread.start();
        while (true && isOperatorControl() && isEnabled()) {
            
            drivetrain.tankDrive(leftStick, rightStick);
            getWatchdog().feed();
            
            // DO NOT remove this yield. Required for kicker thread to execute.
            Thread.yield();
        }
        try {
            kickerThread.join();
        } catch (InterruptedException ex) {
            System.out.println(ex.getMessage());
        }

    }

    /**
     * Gets the right joystick
     * @return The right joystick
     */
    public Joystick getRightStick() {
        return rightStick;
    }

    /** 
     * Gets the robot ready for the big kick.
     */
    private void makeReadyForKick() {
        //Not latched and needs to be preloaded.
        if ((preloaded == false) && (latched == false)) {
            driveLatchSolenoid(Latch);
            Timer.delay(1);
            driveShooterSolenoid(Preload);
            Timer.delay(1);
        }
        //Latched, but needs to preload.
        if ((preloaded == false) && (latched == true)) {
            driveShooterSolenoid(Preload);
            Timer.delay(1);
        }
        //Preloaded, but needs to latch.
        if ((preloaded == true) && (latched == false)) {
            driveShooterSolenoid(Retract);
            Timer.delay(2);
            driveLatchSolenoid(Latch);
            Timer.delay(1);
            driveShooterSolenoid(Preload);
            Timer.delay(1);
        }
    }

    /**
     * Peforms the kick routine.  First loads the kicker if needed.
     * After kicking it loads the kicker for the next big kick.
     */
    public void performKick() {
        makeReadyForKick();
        //Kick!
        driveLatchSolenoid(Unlatch);
        Timer.delay(.5); // If this changed, change the delay in autoKick!!!
        //Reload for big kick.
        driveShooterSolenoid(Retract);
        Timer.delay(2);
        driveLatchSolenoid(Latch);
        Timer.delay(1);
        driveShooterSolenoid(Preload);
        Timer.delay(1);
        System.out.println("Kick Performed");
    }

}
Kicker Thread:
Code:
public class KickerThread extends Thread {
    private RobotMain mRobot997;
    private Joystick mRightStick;
    public KickerThread(RobotMain robot) {
        mRobot997 = robot;
        mRightStick = mRobot997.getRightStick();
    }

    public void run() {
        while (mRobot997.isOperatorControl() && mRobot997.isEnabled()) {
            if (mRightStick.getTrigger()) {
                mRobot997.performKick();
            }
            Thread.yield();
        }
    }
}
In order to allow us to drive to the next ball in autonomous while reloading, we also used threads. The main thread just set a flag on the autonomous kicker thread's class to let it know when to go ahead and perform the kick. Does require being sure to write thread safe code.
  #10   Spotlight this post!  
Unread 12-06-2010, 16:36
frasnow's Avatar
frasnow frasnow is offline
Software
no team
Team Role: Mentor
 
Join Date: Jun 2010
Rookie Year: 2010
Location: Oregon
Posts: 83
frasnow is a splendid one to beholdfrasnow is a splendid one to beholdfrasnow is a splendid one to beholdfrasnow is a splendid one to beholdfrasnow is a splendid one to beholdfrasnow is a splendid one to beholdfrasnow is a splendid one to behold
Re: no control of bot when kicker is operating

One point of clarification, since multithreading can be a confusing topic for some. Event though the performKick() method is located in the RobotMain class, the call to performKick() located in the KickerThread class' run() method still executes on the second thread. Any methods called during the While loop in the operatorControl() method are executing on the main thread.
  #11   Spotlight this post!  
Unread 12-06-2010, 16:59
Ether's Avatar
Ether Ether is offline
systems engineer (retired)
no team
 
Join Date: Nov 2009
Rookie Year: 1969
Location: US
Posts: 8,077
Ether has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond repute
Re: no control of bot when kicker is operating

Hey, welcome aboard frasnow. Check your Private Message inbox, I had a question about your post. :-)
  #12   Spotlight this post!  
Unread 13-06-2010, 03:18
virtuald's Avatar
virtuald virtuald is offline
RobotPy Guy
AKA: Dustin Spicuzza
FRC #1418 (), FRC #1973, FRC #4796, FRC #6367 ()
Team Role: Mentor
 
Join Date: Dec 2008
Rookie Year: 2003
Location: Boston, MA
Posts: 1,058
virtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant future
Re: no control of bot when kicker is operating

I'm not sure if Java has the same thing, but in C++ another easy way to do something like this (without having to worry about yielding, since it does it for you automatically) in a different thread is via the Notifier class. It calls a function every N seconds (we specified 0.0025 seconds) on a different thread. Then you just have your state machine in a single function and have it do the right thing (ie, operate the right switches and such) every time the function gets called. And as the other poster said, you have a different function that gets called by the main thread that touches the state variables.

Of course, a key thing when dealing with multiple threads is to make sure you deal with potential synchronization problems, by using the appropriate locking mechanisms. In C++, you can use the Synchronized class to do that.

I've attached our Kicker code in C++. The full version of our 2010 code is at http://www.virtualroadside.com/FRC/
Attached Files
File Type: h Kicker.h (7.5 KB, 20 views)
__________________
Maintainer of RobotPy - Python for FRC
Creator of pyfrc (Robot Simulator + utilities for Python) and pynetworktables/pynetworktables2js (NetworkTables for Python & Javascript)

2017 Season: Teams #1973, #4796, #6369
Team #1418 (remote mentor): Newton Quarterfinalists, 2016 Chesapeake District Champion, 2x Innovation in Control award, 2x district event winner
Team #1418: 2015 DC Regional Innovation In Control Award, #2 seed; 2014 VA Industrial Design Award; 2014 Finalists in DC & VA
Team #2423: 2012 & 2013 Boston Regional Innovation in Control Award


Resources: FIRSTWiki (relaunched!) | My Software Stuff
  #13   Spotlight this post!  
Unread 13-06-2010, 09:10
Ether's Avatar
Ether Ether is offline
systems engineer (retired)
no team
 
Join Date: Nov 2009
Rookie Year: 1969
Location: US
Posts: 8,077
Ether has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond repute
Re: no control of bot when kicker is operating

Some thoughts for discussion:

Threads in C++ can be preemptive, regardless of whether or not they are created by the Notifier class. In any case, using cooperative multitasking techniques like releasing the CPU to service other tasks while waiting for an event or timer (block waiting) is good programming practice. It makes your code more responsive and avoids wasting CPU resources.

If the kicker code is properly implemented as a state machine, you don't need concurrency, and you don't need to worry about synchronization.

~

Last edited by Ether : 13-06-2010 at 10:00.
Closed Thread


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
842 Kicker On Bot kE7JLM General Forum 36 29-01-2010 11:51
How & where do you build the bot when it snows and your robo-base (school) is closed? Elgin Clock General Forum 28 03-03-2008 00:12
paper: Control an FRC bot with a Wiimote Greg Marra Extra Discussion 8 21-01-2008 12:41
1189 - Human-Bot Arm Control jmcr8on Robot Showcase 50 13-10-2007 22:58


All times are GMT -5. The time now is 03:32.

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