Go to Post I was a rookie last year, I didn't expect much. Now I got a taste of what it is, I want more. - davidthefat [more]
Home
Go Back   Chief Delphi > Technical > Programming > C/C++
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Reply
Thread Tools Rating: Thread Rating: 2 votes, 5.00 average. Display Modes
  #1   Spotlight this post!  
Unread 02-12-2013, 10:47 PM
VCEmblem VCEmblem is offline
Registered User
FRC #3880
 
Join Date: Feb 2013
Location: Kailua-Kona
Posts: 2
VCEmblem is an unknown quantity at this point
Tasks in C++

Hello. My team has been needing to perform more than one function for competition, however, we have absolutely no idea how to multitask in Wind River. We've created a function that calculates the angle needed for our shooter to throw Frisbees directly into the goal.

We've experimented with using functions before, but when we use them user control is unresponsive until the function ends. To solve this in the past in RobotC for VEX, we've used multitasking to run functions while performing other tasks. My programming team and I have been attempting to use multitasking for FRC this year, yet we're clueless on how to proceed.

Here's our current version of the code: http://pastebin.com/RWhNkMXY
The segment of code in question is the function called "shoot." We want to be able to run that function as a separate task.

Any help and suggestions would be much appreciated
Reply With Quote
  #2   Spotlight this post!  
Unread 02-13-2013, 02:16 AM
bob.wolff68's Avatar
bob.wolff68 bob.wolff68 is offline
Da' Mentor Man
FRC #1967
Team Role: Mentor
 
Join Date: Jan 2012
Rookie Year: 2007
Location: United States
Posts: 152
bob.wolff68 is just really nicebob.wolff68 is just really nicebob.wolff68 is just really nicebob.wolff68 is just really nicebob.wolff68 is just really nice
Re: Tasks in C++

Here's our team's task-creation class. Basically, you just implement your own Run() when inheriting from it. Credit to 254 for the genesis of this code.

https://github.com/bobwolff68/FRCTea.../jankyTask.cpp

And here's a project which uses the task - the team created this in order to better understand how multi-tasking works. Take a look and ask questions if you have any.

https://github.com/bobwolff68/FRCTea...nkyTaskTestjig

Bob
__________________
~~~~~~~~~~~~~~~~~~~
Bob Wolff - Software from the old-school
Mentor / C / C++ guy
Team 1967 - The Janksters - San Jose, CA
Reply With Quote
  #3   Spotlight this post!  
Unread 02-25-2013, 09:46 PM
PaulDavis1968's Avatar
PaulDavis1968 PaulDavis1968 is offline
Embedded Software/Systems Engineer
AKA: Master of Complexity
FRC #2053 (TigerTronics)
Team Role: Mentor
 
Join Date: Jan 2012
Rookie Year: 2012
Location: Endicot NY
Posts: 91
PaulDavis1968 is just really nicePaulDavis1968 is just really nicePaulDavis1968 is just really nicePaulDavis1968 is just really nicePaulDavis1968 is just really nice
Re: Tasks in C++

Quote:
Originally Posted by bob.wolff68 View Post
Here's our team's task-creation class. Basically, you just implement your own Run() when inheriting from it. Credit to 254 for the genesis of this code.

https://github.com/bobwolff68/FRCTea.../jankyTask.cpp

And here's a project which uses the task - the team created this in order to better understand how multi-tasking works. Take a look and ask questions if you have any.

https://github.com/bobwolff68/FRCTea...nkyTaskTestjig

Bob
Am I missing something?

If your not doing this:

http://stackoverflow.com/questions/1...-calling-rules

Than how are you calling the jankyTask Constuctor without arguments in your example code ?

Last edited by PaulDavis1968 : 02-25-2013 at 10:04 PM.
Reply With Quote
  #4   Spotlight this post!  
Unread 02-25-2013, 09:53 PM
Ether's Avatar
Ether Ether is offline
systems engineer (retired)
no team
 
Join Date: Nov 2009
Rookie Year: 1969
Location: US
Posts: 7,997
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: Tasks in C++

Quote:
Originally Posted by VCEmblem View Post
Hello. My team has been needing to perform more than one function for competition, however, we have absolutely no idea how to multitask in Wind River.
It's been 2 weeks since you posted this and you haven't come back. No news is good news? If not, and you haven't figured out threads, you could use a state machine instead.


Reply With Quote
  #5   Spotlight this post!  
Unread 02-25-2013, 10:52 PM
rbmj rbmj is offline
Registered User
FRC #0612 (Chantilly Robotics)
Team Role: Alumni
 
Join Date: Apr 2011
Rookie Year: 2011
Location: DC Area/Fairfax County
Posts: 192
rbmj is a jewel in the roughrbmj is a jewel in the roughrbmj is a jewel in the rough
Re: Tasks in C++

Quote:
Originally Posted by PaulDavis1968 View Post
Am I missing something?

If your not doing this:

http://stackoverflow.com/questions/1...-calling-rules

Than how are you calling the jankyTask Constuctor without arguments in your example code ?
The arguments are defaulted.
__________________
FRC 612 '12
USNA '16
Reply With Quote
  #6   Spotlight this post!  
Unread 02-26-2013, 02:53 AM
bob.wolff68's Avatar
bob.wolff68 bob.wolff68 is offline
Da' Mentor Man
FRC #1967
Team Role: Mentor
 
Join Date: Jan 2012
Rookie Year: 2007
Location: United States
Posts: 152
bob.wolff68 is just really nicebob.wolff68 is just really nicebob.wolff68 is just really nicebob.wolff68 is just really nicebob.wolff68 is just really nice
Re: Tasks in C++

Paul & other interested programmers --

As was noted - default parameters are allowed in C++. If you look at the header file (.h), you'll see:
Code:
class JankyTask {
 public:
  /**
   * @brief Constructor which takes an optional taskname. In the absence of a task name,
   *        a task name will be created based upon the current system-time.
   */
  JankyTask(const char* taskName = NULL, UINT32 priority = Task::kDefaultPriority);
  virtual ~JankyTask();
The constructor calls for a taskName and priority. Each of these parameters has a default value ( = NULL and = Task::kDefaultPriority) respectively. If you use the constructor without passing parameters, these defaults are used. This is a C++'ism...

As for "how it works" -- the concept is simple, the semantics can be a bit tricky, but the usage is yet again simple...

If you really are just out to "use it", then take the example and run with it by implementing your own class based on JankyTask and implement Run().

If you'd like to understand it a bit further, you'll need to understand the concept of "static functions". Most classes are defined such that instantiating the class will instantiate one of each of the functions and variables in the class definition. This is "normal" or "simple". In the case of JankyTask, you'll see that there is a static function called JankyPrivateStarterTask(). When a function is static, there is only one of them for the entire world. This becomes important here because of the way the WPILib 'Task' class works. It expects that you will hand it a function which it will "launch" as the starting function for the new task. No problem yet, right? It is of type "(FUNCPTR)". Fine - pass it a function. The problem is that in C++, each class and its functions get "name mangled" when the compiler runs and each member of a class is "private to the class" unless something special is done to it... when it is defined as "static", then it is much more like a C Function and much less like a C++ member of a class. This makes using it in Task() much easier.

When a new task is created, it needs a function to call (FUNCPTR), and when it is told to Task->Start(), it is passed a "data pointer" on its startup. This data pointer, in this case, is a pointer to the JankyTask instance. This is *SUPER* critical. This allows the JankyPrivateStarterTask to actually make a call to *YOUR* Run() function since the data pointer is for this particular instance. You'll see that task->Run() is called any time that the task is enabled within its while loop and it even does a nice 2 ms wait for you as well.

From the outside, the nice thing is that you can instantiate your JankyTask-based class and then operate it from the outside with variables telling it to Pause(), Terminate(), or to get a value, state, set a solenoid, etc.

Note: I'm glossing over a few important multi-tasking principles of how variables are used and when they need to be protected from multiple uses in multiple tasks. These are usually Mutexes or Semaphores or CriticaSections. But in the case of these simpler examples, keeping things rather un-intertwined keeps one from having to cope with these otherwise more complex ideas.

Further questions - lemme know.

:-)

Good luck at regionals this weekend! We'll be at Madera - Central Valley Regional in California. Stop by and say hi to The Janksters Team 1967.

Bob Wolff - Mentor.
__________________
~~~~~~~~~~~~~~~~~~~
Bob Wolff - Software from the old-school
Mentor / C / C++ guy
Team 1967 - The Janksters - San Jose, CA
Reply With Quote
  #7   Spotlight this post!  
Unread 02-26-2013, 08:15 AM
PaulDavis1968's Avatar
PaulDavis1968 PaulDavis1968 is offline
Embedded Software/Systems Engineer
AKA: Master of Complexity
FRC #2053 (TigerTronics)
Team Role: Mentor
 
Join Date: Jan 2012
Rookie Year: 2012
Location: Endicot NY
Posts: 91
PaulDavis1968 is just really nicePaulDavis1968 is just really nicePaulDavis1968 is just really nicePaulDavis1968 is just really nicePaulDavis1968 is just really nice
Re: Tasks in C++

Quote:
Originally Posted by rbmj View Post
The arguments are defaulted.
Thanks I see that now. I want to change the priority so I will have to call with the different priority. Thanks.
Reply With Quote
  #8   Spotlight this post!  
Unread 02-26-2013, 08:23 AM
PaulDavis1968's Avatar
PaulDavis1968 PaulDavis1968 is offline
Embedded Software/Systems Engineer
AKA: Master of Complexity
FRC #2053 (TigerTronics)
Team Role: Mentor
 
Join Date: Jan 2012
Rookie Year: 2012
Location: Endicot NY
Posts: 91
PaulDavis1968 is just really nicePaulDavis1968 is just really nicePaulDavis1968 is just really nicePaulDavis1968 is just really nicePaulDavis1968 is just really nice
Re: Tasks in C++

Quote:
Originally Posted by bob.wolff68 View Post
Paul & other interested programmers --

As was noted - default parameters are allowed in C++. If you look at the header file (.h), you'll see:
Code:
class JankyTask {
 public:
  /**
   * @brief Constructor which takes an optional taskname. In the absence of a task name,
   *        a task name will be created based upon the current system-time.
   */
  JankyTask(const char* taskName = NULL, UINT32 priority = Task::kDefaultPriority);
  virtual ~JankyTask();
The constructor calls for a taskName and priority. Each of these parameters has a default value ( = NULL and = Task::kDefaultPriority) respectively. If you use the constructor without passing parameters, these defaults are used. This is a C++'ism...

As for "how it works" -- the concept is simple, the semantics can be a bit tricky, but the usage is yet again simple...

If you really are just out to "use it", then take the example and run with it by implementing your own class based on JankyTask and implement Run().

If you'd like to understand it a bit further, you'll need to understand the concept of "static functions". Most classes are defined such that instantiating the class will instantiate one of each of the functions and variables in the class definition. This is "normal" or "simple". In the case of JankyTask, you'll see that there is a static function called JankyPrivateStarterTask(). When a function is static, there is only one of them for the entire world. This becomes important here because of the way the WPILib 'Task' class works. It expects that you will hand it a function which it will "launch" as the starting function for the new task. No problem yet, right? It is of type "(FUNCPTR)". Fine - pass it a function. The problem is that in C++, each class and its functions get "name mangled" when the compiler runs and each member of a class is "private to the class" unless something special is done to it... when it is defined as "static", then it is much more like a C Function and much less like a C++ member of a class. This makes using it in Task() much easier.

When a new task is created, it needs a function to call (FUNCPTR), and when it is told to Task->Start(), it is passed a "data pointer" on its startup. This data pointer, in this case, is a pointer to the JankyTask instance. This is *SUPER* critical. This allows the JankyPrivateStarterTask to actually make a call to *YOUR* Run() function since the data pointer is for this particular instance. You'll see that task->Run() is called any time that the task is enabled within its while loop and it even does a nice 2 ms wait for you as well.

From the outside, the nice thing is that you can instantiate your JankyTask-based class and then operate it from the outside with variables telling it to Pause(), Terminate(), or to get a value, state, set a solenoid, etc.

Note: I'm glossing over a few important multi-tasking principles of how variables are used and when they need to be protected from multiple uses in multiple tasks. These are usually Mutexes or Semaphores or CriticaSections. But in the case of these simpler examples, keeping things rather un-intertwined keeps one from having to cope with these otherwise more complex ideas.

Further questions - lemme know.

:-)

Good luck at regionals this weekend! We'll be at Madera - Central Valley Regional in California. Stop by and say hi to The Janksters Team 1967.

Bob Wolff - Mentor.

Thanks I see that it is defaulted now. As far as "how" it works I had to dust off a 12 year old college knowledge of a C++ obtained when getting my CS degree but I get it (We use C at work). We will not be needing to do any thing that requires locking using mutexs or semaphores so my data structures won't need to be thread safe. I appreciate the walk-through. Good luck to you too.
Reply With Quote
  #9   Spotlight this post!  
Unread 02-28-2013, 12:10 AM
makahn64 makahn64 is offline
Registered User
FRC #0256
 
Join Date: Nov 2011
Location: United States
Posts: 27
makahn64 is infamous around these partsmakahn64 is infamous around these partsmakahn64 is infamous around these partsmakahn64 is infamous around these partsmakahn64 is infamous around these partsmakahn64 is infamous around these parts
Re: Tasks in C++

You might want to just switch to using the Command based model which takes care of scheduling commands for you. We had been writing our own scheduled objects with update loops we kicked each pass through the loop. We switched to Command this year and it is so much easier.

So in your case of moving the arm, you'd created a "MoveArm" command which subclasses command. There's a method called when the Command is initted, one that's called every 20ms while it is alive, another called to ind out if the command is done, another clean up when it is done. Quite tidy.

Having said that, it doesn't work great if you need better than 20ms resolution on any given feedback measurement (i.e. a fast spinning acutuator).
Reply With Quote
  #10   Spotlight this post!  
Unread 02-28-2013, 10:12 PM
bob.wolff68's Avatar
bob.wolff68 bob.wolff68 is offline
Da' Mentor Man
FRC #1967
Team Role: Mentor
 
Join Date: Jan 2012
Rookie Year: 2007
Location: United States
Posts: 152
bob.wolff68 is just really nicebob.wolff68 is just really nicebob.wolff68 is just really nicebob.wolff68 is just really nicebob.wolff68 is just really nice
Re: Tasks in C++

Yea, our team has not moved to the IterativeRobot base class. That's required in order to use the Command items, correct?

bob
__________________
~~~~~~~~~~~~~~~~~~~
Bob Wolff - Software from the old-school
Mentor / C / C++ guy
Team 1967 - The Janksters - San Jose, CA
Reply With Quote
  #11   Spotlight this post!  
Unread 03-04-2013, 05:41 PM
JefferMC JefferMC is offline
Registered User
AKA: Jeff Corbett
FRC #1319 (Flash)
Team Role: Mentor
 
Join Date: Nov 2012
Rookie Year: 2005
Location: United States
Posts: 44
JefferMC will become famous soon enough
Re: Tasks in C++

Quote:
Originally Posted by bob.wolff68 View Post
Yea, our team has not moved to the IterativeRobot base class. That's required in order to use the Command items, correct?

bob
Command Based programming is based upon the Iterative framework (which you should probably understand before using either) but is its own project type. And these both make it easier for your robot to "multi-task" without you necessarily having to have multiple scheduled tasks. In either you can throw multiple balls in the air (so to speak) on each iteration, and then check back on progress on subsequent iterations.

I had done something similar, but much simpler, than the CBP back in 2009/2010.
Reply With Quote
  #12   Spotlight this post!  
Unread 03-09-2013, 12:05 AM
wireties's Avatar
wireties wireties is offline
Principal Engineer
AKA: Keith Buchanan
FRC #1296 (Full Metal Jackets)
Team Role: Mentor
 
Join Date: Jan 2006
Rookie Year: 2004
Location: Rockwall, TX
Posts: 1,168
wireties has a reputation beyond reputewireties has a reputation beyond reputewireties has a reputation beyond reputewireties has a reputation beyond reputewireties has a reputation beyond reputewireties has a reputation beyond reputewireties has a reputation beyond reputewireties has a reputation beyond reputewireties has a reputation beyond reputewireties has a reputation beyond reputewireties has a reputation beyond repute
Send a message via AIM to wireties
Re: Tasks in C++

Any task can change its own priority with a simple C function ...

#include "taskLib.h"
...
taskPrioritySet(0, iNewPriority);


... where iNewPriority is from 0 to 99, the lower the number the greater the priority
__________________
Fast, cheap or working - pick any two!
Reply With Quote
  #13   Spotlight this post!  
Unread 03-10-2013, 09:08 PM
AlexBrinister AlexBrinister is offline
Registered User
AKA: Alex Brinister
FRC #1768 (RoboChiefs)
Team Role: Alumni
 
Join Date: Jan 2013
Rookie Year: 2012
Location: Bolton, MA
Posts: 93
AlexBrinister will become famous soon enough
Re: Tasks in C++

You could just use pthreads.

Or you could usr our pre-made abstractions:

github.com/Nashoba-Robotics/Nashoba-Robotics2013-SimpleRobot

Alex Brinister
Reply With Quote
  #14   Spotlight this post!  
Unread 02-22-2016, 07:35 AM
dvdbot dvdbot is offline
Registered User
FRC #5412
 
Join Date: Feb 2016
Location: Netherlands
Posts: 1
dvdbot is an unknown quantity at this point
Re: Tasks in C++

Our team is currently trying to get tasking working,
above code show in JankyTask doesn't work with the 2016 library.

We're trying to get Tasking working because we would like to try to split driver one and two into two seperate tasks on the RoboRio, does someone know if this is possible?

If so, can someone help us?
Reply With Quote
  #15   Spotlight this post!  
Unread 02-22-2016, 09:11 AM
jreneew2's Avatar
jreneew2 jreneew2 is offline
Alumni of Team 2053 Tigertronics
AKA: Drew Williams
FRC #2053 (TigerTronics)
Team Role: Programmer
 
Join Date: Jan 2014
Rookie Year: 2013
Location: Vestal, NY
Posts: 189
jreneew2 has a spectacular aura aboutjreneew2 has a spectacular aura aboutjreneew2 has a spectacular aura about
Re: Tasks in C++

You resurrected an old thread from 2013. Anyway, take a look at our code here. It works fine for us using WPILib's built in task setup (which I think is really just a wrapper for a pthread).

https://github.com/team2053tigertron.../src/Robot.cpp
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 03:39 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