Go to Post There are 10 types of people in the world: those that understand binary and those that do not. - Stephen P [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 12-12-2012, 15:19
apples000's Avatar
apples000 apples000 is offline
Registered User
no team
 
Join Date: Mar 2012
Rookie Year: 2012
Location: United States
Posts: 222
apples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant future
Quick Question about Threads

I'm currently writing some robot code, and I've been wondering about using multiple threads in java. As far as I know, it's the same as using threads in any other java application, but some people on my team think differently. Here's what I think should work. I'm not sure that starting the thread in the constructor is the best idea, and I'm also not sure that I'm using thread.sleep() the right way. I know that I could start the thread from somewhere else by using new Thread(Vision).start();, but what would work with java for FRC?
Code:
public class Vision implements Runnable{
    public Vision(){
         new Thread(this).start();
   }
    public void run() {
        while(processImages){
            //image stuff here
                 try {
                    Thread.sleep(100);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }
}
Reply With Quote
  #2   Spotlight this post!  
Unread 12-12-2012, 15:29
joelg236 joelg236 is offline
4334 Retired Mentor & Alumni
AKA: Joel Gallant
no team
Team Role: Mentor
 
Join Date: Dec 2011
Rookie Year: 2012
Location: Calgary
Posts: 733
joelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond repute
Re: Quick Question about Threads

It would work. But I am very sceptical of you starting a thread in a constructor. I can't imagine a situation where that would be a good idea (in frc coding at least). But yes, the Thread class works just like Java SE.
__________________
All opinions are my own.
Reply With Quote
  #3   Spotlight this post!  
Unread 12-12-2012, 15:31
joelg236 joelg236 is offline
4334 Retired Mentor & Alumni
AKA: Joel Gallant
no team
Team Role: Mentor
 
Join Date: Dec 2011
Rookie Year: 2012
Location: Calgary
Posts: 733
joelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond repute
Re: Quick Question about Threads

As to Thread.sleep(), I would refer you here: http://stackoverflow.com/questions/3...h-thread-sleep
__________________
All opinions are my own.
Reply With Quote
  #4   Spotlight this post!  
Unread 12-12-2012, 15:57
apples000's Avatar
apples000 apples000 is offline
Registered User
no team
 
Join Date: Mar 2012
Rookie Year: 2012
Location: United States
Posts: 222
apples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant future
Re: Quick Question about Threads

You're right, starting a thread in the constructor is wrong. It should be placed in a method named startVision instead of the constructor. Also, we're using thread.sleep instead of thread.yield because it seems to give us more consistent vision loop timings, but I'm not really sure why. It also keeps the cpu usage away from 100%. We know that the vision loop will slow down when other stuff starts up, but it's nice to be able to watch the cpu usage and see what functions use the most resources. What do you think the best way to free up the CPU?
Reply With Quote
  #5   Spotlight this post!  
Unread 12-12-2012, 16:15
Butter's Butter's is offline
Registered User
AKA: Joe Kent
FRC #0522 (Robo Wizards)
Team Role: Programmer
 
Join Date: Feb 2012
Rookie Year: 2010
Location: Staten Island, New York
Posts: 21
Butter's is an unknown quantity at this point
Re: Quick Question about Threads

Might be because of this?

Thread.sleep(100);

Never used threading for FRC, but I have for game programming. In which my sleep time varies based off a few factors (Another words, it's not just a while loop with a constant sleep time). Not sure how to implement this in FRC, just throwing out the possibility.

Also, you're sleeping for a tenth of a second. Try making the value 1000 (1 second) and see if the usage goes down.

If neither of these work, you might want to use a debugger & pin point what in specific is maxing out the CPU.
Reply With Quote
  #6   Spotlight this post!  
Unread 12-12-2012, 16:28
apples000's Avatar
apples000 apples000 is offline
Registered User
no team
 
Join Date: Mar 2012
Rookie Year: 2012
Location: United States
Posts: 222
apples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant future
Re: Quick Question about Threads

Sorry, my last post was a bit confusing. What I was trying to say was that using thread.yield() caused the cpu usage to go to 100% but didn't cause any lag. The disadvantage was that it was unpredictable with the vision loop. What we used instead was thread.sleep. This does work for us because waiting 100ms doesn't increase the cpu usage very much. 6-10 fps seems like a good target frame rate for our camera. I don't really understand how the thread.sleep can be improved without making a much more complicated method of threading. I am aware that the sleep function tends to be off because of the way that thread scheduling works, but the difference is so small, that for us it won't really make a difference. We're not waiting for something to happen, we're just trying to reduce CPU usage. I'm trying to keep it simple, and since we only have 3 threads right now including the main thread, and they interact in such a way that they don't need to be synchronized with each other, I don't see why I'd have to do anything differently.
Reply With Quote
  #7   Spotlight this post!  
Unread 12-12-2012, 16:45
joelg236 joelg236 is offline
4334 Retired Mentor & Alumni
AKA: Joel Gallant
no team
Team Role: Mentor
 
Join Date: Dec 2011
Rookie Year: 2012
Location: Calgary
Posts: 733
joelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond repute
Re: Quick Question about Threads

Thread.yield() tells the CPU to pause the current thread and allow other threads to run. See : http://stackoverflow.com/questions/4...sleep0-in-java

Unless that is what you are going for, I'm thinking that yield() doesn't find any other threads to run, so it just runs right away, making the loop incredibly fast (100% usage).
__________________
All opinions are my own.
Reply With Quote
  #8   Spotlight this post!  
Unread 12-12-2012, 16:57
joelg236 joelg236 is offline
4334 Retired Mentor & Alumni
AKA: Joel Gallant
no team
Team Role: Mentor
 
Join Date: Dec 2011
Rookie Year: 2012
Location: Calgary
Posts: 733
joelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond repute
Re: Quick Question about Threads

Also, if you are feeling lazy, the wpilibj has a class called Timer that has a static method delay(double seconds). It just uses Thread.sleep(), but converts the double correctly and catches the exception.
__________________
All opinions are my own.
Reply With Quote
  #9   Spotlight this post!  
Unread 13-12-2012, 09:40
JesseK's Avatar
JesseK JesseK is offline
Expert Flybot Crasher
FRC #1885 (ILITE)
Team Role: Mentor
 
Join Date: Mar 2007
Rookie Year: 2005
Location: Reston, VA
Posts: 3,710
JesseK has a reputation beyond reputeJesseK has a reputation beyond reputeJesseK has a reputation beyond reputeJesseK has a reputation beyond reputeJesseK has a reputation beyond reputeJesseK has a reputation beyond reputeJesseK has a reputation beyond reputeJesseK has a reputation beyond reputeJesseK has a reputation beyond reputeJesseK has a reputation beyond reputeJesseK has a reputation beyond repute
Re: Quick Question about Threads

I don't know whether this works on the robot, but this is how we plan to implement it on our driver's station this year. We may add an interrupt timer that will re-process a new image if the old image hasn't been processed, but we also don't expect the driver's station laptop to bog down enough that it can't keep up. This method doesn't depend on a sleep() or a timer, it simply processes images as they chronologically come in (even if they're asynchronous due to network lag).

The big issue with doing threading like this comes when you go to fold the results back into whatever other robot logic you have. You MUST make sure your data is thread-safe (i.e. use synchronized blocks on critical path items OR make sure that only one single thread can access/modify a specific set of critical data). With gui's, it's easy: SwingUtilities.invokeLater() will update data on a GUI using the EventDispatchThread. For your own internal robot stuff though, it isn't quite as clear-cut.

Code:
/**
 * IUpdate<T> is just a type-safe interface that I commonly use
 * for event-driven items that only need 1 input parameter.
 * 
  public interface IUpdate<T>
  {
    public void update(T pObject);
  }  
 *
 */
public abstract class ImageProcessor implements IUpdate<BufferedImage>
{
  private final Executor mExecutor = Executors.newSingleThreadExecutor();
  
  public ImageProcessor(IImageProvider pProvider)
  {
    pProvider.addListener(this);
  }

  @Override public void update(final BufferedImage pObject)
  {
    mExecutor.execute(new Runnable()
    {
        @Override public void run()
        {
           processImpl(pObject);
        }
    });
  }
  
  protected abstract void processImpl(BufferedImage pImage);
}
__________________

Drive Coach, 1885 (2007-present)
CAD Library Updated 5/1/16 - 2016 Curie/Carver Industrial Design Winner
GitHub

Last edited by JesseK : 14-12-2012 at 09:13. Reason: Abstract method is much more extendable than a private inner class
Reply With Quote
  #10   Spotlight this post!  
Unread 13-12-2012, 16:58
apples000's Avatar
apples000 apples000 is offline
Registered User
no team
 
Join Date: Mar 2012
Rookie Year: 2012
Location: United States
Posts: 222
apples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant future
Re: Quick Question about Threads

My idea, which is my attempt to keep things simple, was to have a thread that would process the image, store the coordinates of the image in a variable, then wait 100ms. This would keep the processor happy. If we wanted, we could time the processing stuff then subtract that time from 100ms to make sure that we got exactly 10fps. Then, our PID loop for targeting would look to the most recently calculated image coordinate by using a method in the vision class which gets the variables with the coordinates. I realize that the PID loop may be sometimes getting bad information, for instance, it may grab the same coordinates twice before the cRIO can process another image. We used labview to do the same thing on the cRIO, and it worked fine. If my logic is flawed, I think I could just call a method which processes the image in the PID loop, which is threaded. What is the easiest way to get the image stuff working in a thread?
Reply With Quote
  #11   Spotlight this post!  
Unread 13-12-2012, 21:19
inkspell4's Avatar
inkspell4 inkspell4 is offline
Registered User
FRC #3650 (Robo Raptors)
Team Role: Programmer
 
Join Date: Jan 2011
Rookie Year: 2011
Location: Maryland
Posts: 326
inkspell4 will become famous soon enough
What are thread used for and do you have any resources for using them?
__________________
Chesapeake Regional : 2013, 2012, 2011
Rookie Year: 2011
2013 RoboRaptors Team 3650 Programming Team Captain
Team Website : http://www.roboraptorsfrcteam3650.com/index.html
_____________________________________________
Reply With Quote
  #12   Spotlight this post!  
Unread 13-12-2012, 22:11
F22Rapture's Avatar
F22Rapture F22Rapture is offline
College Student, Mentor
AKA: Daniel A
FRC #3737 (4H Rotoraptors)
Team Role: Mentor
 
Join Date: Jan 2012
Rookie Year: 2012
Location: Goldsboro, NC
Posts: 476
F22Rapture has a brilliant futureF22Rapture has a brilliant futureF22Rapture has a brilliant futureF22Rapture has a brilliant futureF22Rapture has a brilliant futureF22Rapture has a brilliant futureF22Rapture has a brilliant futureF22Rapture has a brilliant futureF22Rapture has a brilliant futureF22Rapture has a brilliant futureF22Rapture has a brilliant future
Re: Quick Question about Threads

Quote:
Originally Posted by inkspell4 View Post
What are thread used for and do you have any resources for using them?
Multitasking and keeping certain functions of the robot isolated from others.

General information on Java threads can be found with Google.

FRC-specific information can be found using the handy "search" bar up at the top of the page...
__________________
Research is what I’m doing when I don’t know what I’m doing.
- Wernher von Braun
Attending: Raleigh NC Regional
Reply With Quote
  #13   Spotlight this post!  
Unread 14-12-2012, 09:09
JesseK's Avatar
JesseK JesseK is offline
Expert Flybot Crasher
FRC #1885 (ILITE)
Team Role: Mentor
 
Join Date: Mar 2007
Rookie Year: 2005
Location: Reston, VA
Posts: 3,710
JesseK has a reputation beyond reputeJesseK has a reputation beyond reputeJesseK has a reputation beyond reputeJesseK has a reputation beyond reputeJesseK has a reputation beyond reputeJesseK has a reputation beyond reputeJesseK has a reputation beyond reputeJesseK has a reputation beyond reputeJesseK has a reputation beyond reputeJesseK has a reputation beyond reputeJesseK has a reputation beyond repute
Re: Quick Question about Threads

Quote:
Originally Posted by apples000 View Post
My idea, which is my attempt to keep things simple, was to have a thread that would process the image, store the coordinates of the image in a variable, then wait 100ms. This would keep the processor happy. If we wanted, we could time the processing stuff then subtract that time from 100ms to make sure that we got exactly 10fps. Then, our PID loop for targeting would look to the most recently calculated image coordinate by using a method in the vision class which gets the variables with the coordinates. I realize that the PID loop may be sometimes getting bad information, for instance, it may grab the same coordinates twice before the cRIO can process another image. We used labview to do the same thing on the cRIO, and it worked fine. If my logic is flawed, I think I could just call a method which processes the image in the PID loop, which is threaded. What is the easiest way to get the image stuff working in a thread?
Why 100ms?
What happens if your image processor take 10ms to process (for a total loop time of 110ms), but the images still come in at 10Hz (every 100ms)?

Quote:
Originally Posted by inkspell4 View Post
What are thread used for and do you have any resources for using them?
Threads are used to keep critical code (like your robot drive code) from being interfered with by errant processing algorithms that augment, but do not supercede, the data that the critical code uses (like image processing). Separating the threads allows for the critical code to always have enough processor to run so that the robot remains responsive. On a multi-core processor even if the image rate is increased to something obscene like 100fps, the robot drive code should still remain responsive. As far as I know, the cRIO is not multi-core -- so image rate does still matter -- yet 2-3 non-intensive threads are still great ways to ensure the non-critical data is processed separately. If there's an error in the data that causes the thread to die (uncaught exceptions anyone???) -- the thread that died should not be the main robot code thread.

However, there is no free lunch: dedicating more threads than you have CPU cores will still CPU cause scheduling conflicts. For example, if I dedicate 8 threads to heavy processing and expect my 9th main critical thread to main responsive (in a quad-core HT system), I'm really just fooling myself. The system has 7 available threads for heavy (100% cpu) processing.
__________________

Drive Coach, 1885 (2007-present)
CAD Library Updated 5/1/16 - 2016 Curie/Carver Industrial Design Winner
GitHub

Last edited by JesseK : 14-12-2012 at 09:22.
Reply With Quote
  #14   Spotlight this post!  
Unread 14-12-2012, 11:26
joelg236 joelg236 is offline
4334 Retired Mentor & Alumni
AKA: Joel Gallant
no team
Team Role: Mentor
 
Join Date: Dec 2011
Rookie Year: 2012
Location: Calgary
Posts: 733
joelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond reputejoelg236 has a reputation beyond repute
Re: Quick Question about Threads

A much simpler explanation of threading is this:

Being able to do more than 1 thing at a time. It basically lets you do two (or more) things simultaneously, without any expectations of one of them being done before the other. Keep in mind there are a lot of concurrency problems that you need to deal with if you use multiple threads. (see synchronized blocks, atomic variables and volatile variables)
__________________
All opinions are my own.
Reply With Quote
  #15   Spotlight this post!  
Unread 14-12-2012, 15:11
apples000's Avatar
apples000 apples000 is offline
Registered User
no team
 
Join Date: Mar 2012
Rookie Year: 2012
Location: United States
Posts: 222
apples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant futureapples000 has a brilliant future
Re: Quick Question about Threads

Quote:
Originally Posted by JesseK View Post
Why 100ms?
What happens if your image processor take 10ms to process (for a total loop time of 110ms), but the images still come in at 10Hz (every 100ms)?
Well, we chose 100ms because it is what is used in LabVIEW for the vision loop wait time. Also, when we use the AxisCamera.getInstance.getImage() method it will get the most recent image. Since the images come in faster than 100 ms, there's no way for the loop to grab the same image twice. I'm not sure that this is the best way. I'd like to know if there is a better way to do this.
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:51.

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