View unanswered posts | View active topics It is currently Mon Sep 01, 2014 8:02 am






Reply to topic  [ 18 posts ]  Go to page 1, 2  Next
In-function Task Handling 
Author Message
Rookie

Joined: Fri Apr 08, 2011 4:31 pm
Posts: 11
Post In-function Task Handling
Well, I've been developing a universal function to handle a task using joystick buttons. The main problem I'm having is that after I press the button, the NXT stops and gives some kind of a warning. After some testing, I found it stops at:

if(taskState == taskStateStopped)

I used to have it just as

if(getTaskState(TaskName) == taskStateStopped)

but that didn't work either. Any help would be great!

Code:
void handleTask(void TaskName, int actionButton)
{
  TTaskStates taskState;
  if(controller == 1)
  {
    if(joy1Btn(actionButton) == true)
    {
      taskState = getTaskState(TaskName);
      if(taskState == taskStateStopped)
      {
        StartTask(TaskName);
      }
      else
      {
        return;
      }
    }
    if(joy1Btn(KButton) == true)
    {
      taskState = getTaskState(TaskName);
      if(taskState == taskStateRunning)
      {
        StopTask(TaskName);
        allStop();
      }
    }
  }
  if(controller == 2)
  {
    if(joy2Btn(actionButton) == true)
    {
      taskState = getTaskState(TaskName);
      if(taskState == taskStateStopped)
      {
        StartTask(TaskName);
      }
      else
      {
        return;
      }
    }
    if(joy2Btn(KButton) == true)
    {
      taskState = getTaskState(TaskName);
      if(taskState == taskStateRunning)
      {
        StopTask(TaskName);
        allStop();
      }
    }
  }
}


Wed Oct 26, 2011 5:15 pm
Profile
Moderator
Moderator
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3207
Location: Rotterdam, The Netherlands
Post Re: In-function Task Handling
What warning did it display and do you have a complete program to demonstrate the issue? Try to get rid of as much cruft as possible so it will work for people without a joystick as well.

- Xander

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]


Thu Oct 27, 2011 1:58 am
Profile WWW
Rookie

Joined: Wed Jul 21, 2010 11:23 pm
Posts: 39
Post Re: In-function Task Handling
ajhl49 wrote:
Well, I've been developing a universal function to handle a task using joystick buttons. The main problem I'm having is that after I press the button, the NXT stops and gives some kind of a warning. After some testing, I found it stops at:

if(taskState == taskStateStopped)

I used to have it just as

if(getTaskState(TaskName) == taskStateStopped)

but that didn't work either. Any help would be great!

Last week I had some issues when I tried to use the NXT buttons to each start a specific task within a program. At first my code didn't wait for the NXT button to be released, if it saw the button pressed it just started the task and moved on. That meant that on the next loop the NXT button was most likely still pressed so it reran the starttask command. That gave me some very odd and unpredictable results that took a while to figure out. Once I changed the code to wait for the NXT button to be pressed and released before starting the task everything worked fine.


Fri Oct 28, 2011 11:25 am
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1347
Post Re: In-function Task Handling
When dealing with any kind of buttons whether NXT buttons or joystick buttons, it is usually more useful if your code acts on edge events instead of the button state. This means instead of testing the state of the button whether it is pressed or not, the code should detect the transition from released to pressed or from pressed to released. Usually, it involves code like this:
Code:
#define DEBOUNCE_TIME   50
int prevState = nxtButtonPressed;
int currState;
while (true)
{
    currState = nxtButtonPressed;
    if (currState != prevState)
    {
        if (currState == kLeftButton)
        {
            //
            // Left button is pressed, do something here.
            //
        }
        else if (currState == kRightButton)
        {
            //
            // Right button is pressed, do something here.
            //
        }
        else if (currState == kEnterButton)
        {
            //
            // Enter button is pressed, do something here.
            //
        }
        else if (currState == kNoButton)
        {
            //
            // Button was released.
            //
        }
        prevState = currState;
    }
    wait1Msec(DEBOUNCE_TIME);
}

BTW, we have a library module that allows you to display a menu of choices and the user can pick the choices by pressing the NXT buttons left, right and enter. We use it to display a number of autonomous routines so the driver can make a choice before the game starts. The number of choices can be greater than the number of lines on the LCD display because it can scroll the lines up and down if it needs to.
http://proj.titanrobotics.net/hg/Ftc/20 ... lib/menu.h
An example on how to use the menu code can be found here in the RobotInit function.
http://proj.titanrobotics.net/hg/Ftc/20 ... AutoMain.h


Last edited by MHTS on Tue Nov 01, 2011 4:56 pm, edited 3 times in total.



Fri Oct 28, 2011 12:45 pm
Profile
Rookie

Joined: Wed Jul 21, 2010 11:23 pm
Posts: 39
Post Re: In-function Task Handling
MHTS wrote:
Code:
        else if (currState == kNoButton)
        {
            //
            // Button was released.
            //
        }
        prevState = currState;
       // debounce wait should be here 
    }
    wait1Msec(DEBOUNCE_TIME);  // this wait is really the loop sample time, not debounce
}



I'd suggest that the debounce wait should be inside the if statement, so it only limits subsequent button sampling after it sees a change of state. With the wait in the main loop you slow down overall button sampling, which at some point could cause the program to miss a very short button press.


Fri Oct 28, 2011 1:30 pm
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1347
Post Re: In-function Task Handling
I thought about it some more. A robot program may have other tasks going on. So it is generally not preferrable to have a tight loop. In that regard, you probably need at least an EndTimeSlice() statement like the code below. However, if you yield your timeslice, the button sampling code will not be monitoring the buttons for at least one or more time slices (depending on the number of tasks running in the system). However, if a press and a release happened within a timeslice or DEBOUNCE_TIME, it is a bounce. I don't think it is crucial to try not missing such a short bounce.
Code:
#define DEBOUNCE_TIME   50
int prevState = nxtButtonPressed;
int currState;
while (true)
{
    currState = nxtButtonPressed;
    if (currState != prevState)
    {
        if (currState == kLeftButton)
        {
            //
            // Left button is pressed, do something here.
            //
        }
        else if (currState == kRightButton)
        {
            //
            // Right button is pressed, do something here.
            //
        }
        else if (currState == kEnterButton)
        {
            //
            // Enter button is pressed, do something here.
            //
        }
        else if (currState == kNoButton)
        {
            //
            // Button was released.
            //
        }
        prevState = currState;
        wait1Msec(DEBOUNCE_TIME);
    }
    EndTimeSlice();
}


Fri Oct 28, 2011 1:35 pm
Profile
Rookie

Joined: Fri Apr 08, 2011 4:31 pm
Posts: 11
Post Re: In-function Task Handling
Sorry I haven't replied in a while. Our robotics team only meets every Wed - Fri, so I haven't had access to our forum account.

The NXT gives this error:

Code:
PgmCnt: 0005A5
Type:   18


Also, here is a sample of the main program code using the function.

Code:
#include "UsefulFunctions/UsefulFunctionsV2_0.c"
task doStuff
{
  int i = 0;
  while(true)
  {
    nxtDisplayTextLine(2, "%d times looped", i);
    i++;
  }
}
task main
{
  initUsefulFunctions(13000, 10);
  while(true)
  {
    handleTask(doStuff, 2);
  }
}


initUsefulFunctions code:

Code:
void initUsefulFunctions(int BattVal, int KillButton)
{
  RegBattPower = BattVal;
  controller = 1;
  KButton = KillButton;
  StartTask(getJoystick);
}


Wed Nov 02, 2011 4:23 pm
Profile
Rookie

Joined: Fri Apr 08, 2011 4:31 pm
Posts: 11
Post Re: In-function Task Handling
Maybe I can't pass task names indirectly? Or I can't put the task name into the void variable?


Thu Nov 03, 2011 4:57 pm
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1347
Post Re: In-function Task Handling
RobotC is a weird breed. It doesn't support pointers so in theory you should not pass a function name or task name as a parameter but yet the StartTask or StopTask functions accept task name as a parameter. So I do not know if you can do this or not and I haven't tried it myself.


Thu Nov 03, 2011 5:04 pm
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1347
Post Re: In-function Task Handling
Several observations...
Did your code really compile without error? First, I thought the proper syntax of task is:
Code:
task <taskName> ()
{
}

Your doStuff task has no () and so is task main. Secondly, what is handleTask? Is it your function or a RobotC built-in function? I don't have RobotC in front of me so I can't verify it. I would like to see its function prototype on whether it can accept task name as a parameter.


Thu Nov 03, 2011 5:13 pm
Profile
Rookie

Joined: Fri Apr 08, 2011 4:31 pm
Posts: 11
Post Re: In-function Task Handling
It does compile, without any warning or error.

handleTask is a task I wrote to handle tasks using joystick buttons, on any program I include it in. The code should be in the first post.

Here are a few variables it has that aren't in the included code:

Code:
int controller;//selected controller to run KButton
int KButton //selected button to stop running tasks


these are given variables in the initUsefulFunctions function(also in a post above)


Thu Nov 03, 2011 5:27 pm
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1347
Post Re: In-function Task Handling
Hmm, I am surprised the compiler did not give you error on the following line:
Code:
void handleTask(void TaskName, int actionButton)

You cannot specify void as a type to a parameter because void is nothing and it gives the compiler no clue on the size of the parameter and therefore the compiler doesn't know how much space to allocate on the stack to pass this parameter. I tried this on the Microsoft C compiler, this will give you error C2182: illegal use of type 'void'.
I am also surprised getTaskState() and StartTask() allow you to pass it a type 'void' parameter.


Thu Nov 03, 2011 6:04 pm
Profile
Rookie

Joined: Fri Apr 08, 2011 4:31 pm
Posts: 11
Post Re: In-function Task Handling
I thought that using a void would work because I found this sifting through code:

Code:
StartTask(void TaskID)


From that I thought task names were of type void, and that I could store them in void variables.


Fri Nov 04, 2011 4:28 pm
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1347
Post Re: In-function Task Handling
That's something I don't understand about RobotC compiler because it breaks many compiler syntax rules. StartTask must be very special. I don't think you can do this to a regular C function. This should be a question for the RobotC folks.


Fri Nov 04, 2011 4:35 pm
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1347
Post Re: In-function Task Handling
In general, I would avoid using task anyway. What is the main goal of your code? I am sure you can rewrite it without using tasks. For example, my library has a module that handles joystick buttons. It's using a "callback" mechanism instead of task. It has a "task" function (not really a task but a function that got called periodically in the robot main loop). This function checks for state changes of any joystick buttons whether a button is pressed or released. If something changed, it calls back a ButtonEvent function to process the change. So in effect, I am detecting transition events of the joystick buttons and notify somebody who cares about them.


Fri Nov 04, 2011 4:43 pm
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 18 posts ]  Go to page 1, 2  Next

Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  



Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.