View unanswered posts | View active topics It is currently Sat Apr 19, 2014 1:30 pm






Reply to topic  [ 31 posts ]  Go to page 1, 2, 3  Next
Hitechnic IR link with multitasking 
Author Message
Rookie

Joined: Mon Jun 11, 2012 9:28 pm
Posts: 37
Post Hitechnic IR link with multitasking
Hello there,

I have a quick question. It seems that when using the Hitechic IR link, or indeed, any sensor with Xander's Driver Suite, it seems I have memory access issues when calling any of the functions within multiple tasks.

I tried to work it around by having one task which sets the motors in accordance with some global variables set by other tasks. However, it seems to be strangely slow to respond. Is there a better way?

Code: (I stripped some of the unnecessary parts, so it probably won't compile, but you should see the gist of what I tried to do.)

Code:
#pragma config(Sensor, S1,     HTIRL,          sensorI2CCustom)
#pragma config(Sensor, S2,     orangeLight,    sensorLightInactive)
#pragma config(Sensor, S3,     whiteLight,     sensorLightInactive)
#pragma config(Sensor, S4,     resetButton,    sensorTouch)
#pragma config(Motor,  motorA,          trolley,       tmotorNormal, PIDControl, encoder)
#pragma config(Motor,  motorB,          clear,         tmotorNormal, PIDControl, encoder)
#pragma config(Motor,  motorC,          elevator,      tmotorNormal, openLoop)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

#include "drivers/HTIRL-driver.h"
#include "drivers/LEGOLS-driver.h"

bool orangeGateControl = false;
bool whiteGateControl = false;
bool orangeValveControl = false;
bool whiteValveControl = false;

tPFmotor orangeGate = pfmotor_S1_C1_A;
tPFmotor whiteGate = pfmotor_S1_C1_B;

tPFmotor orangeValve = pfmotor_S1_C2_A;
tPFmotor whiteValve = pfmotor_S1_C2_B;

ePWMMotorCommand orangeGateOpen = MOTOR_REV_PWM_4;
ePWMMotorCommand orangeGateClose = MOTOR_FWD_PWM_4;

ePWMMotorCommand whiteGateOpen = MOTOR_FWD_PWM_4;
ePWMMotorCommand whiteGateClose = MOTOR_REV_PWM_4;

ePWMMotorCommand orangeValveOpen = MOTOR_REV_PWM_4;
ePWMMotorCommand orangeValveClose = MOTOR_FWD_PWM_4;

ePWMMotorCommand whiteValveOpen = MOTOR_FWD_PWM_4;
ePWMMotorCommand whiteValveClose = MOTOR_REV_PWM_4;

task orangeValveCheck()
{
  while(true)
  {
    //code to set orangeValveControl
  }
}

task whiteValveCheck()
{
  while(true)
  {
    //code to set whiteValveControl
  }
}

//I put a separate task here to avoid memory access conflicts in the functions.

task PFMotorControl()
{
  while(true)
  {
    if (whiteGateControl == false) {PFMotor(whiteGate,whiteGateClose);}
    if (whiteGateControl == true) {PFMotor(whiteGate,whiteGateOpen);}
   
    if (orangeGateControl == false) {PFMotor(orangeGate,orangeGateClose);}
    if (orangeGateControl == true) {PFMotor(orangeGate,orangeGateOpen);}
   
    if (whiteValveControl == false) {PFMotor(whiteValve,whiteValveClose);}
    if (whiteValveControl == true) {PFMotor(whiteValve,whiteValveOpen);}
   
    if (orangeValveControl == false) {PFMotor(orangeValve,orangeValveClose);}
    if (orangeValveControl == true) {PFMotor(orangeValve,orangeValveOpen);}
   
    //Not sure about this, just trying to stop it hogging the CPU.
    wait1Msec(1);
  }
}

task main()
{
  startTask(PFMotorControl);
  startTask(orangeValveCheck);
  startTask(whiteValveCheck);

  while(true)
  {
    //some code to control whiteGateControl and orangeGateControl    
  }
}


Sun Jul 15, 2012 5:19 pm
Profile
Moderator
Moderator
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3105
Location: Rotterdam, The Netherlands
Post Re: Hitechnic IR link with multitasking
You can only do I2C related things from a single task. This has to do with a ROBOTC limitation in that a single function cannot be called from two different tasks simultaneously without risking conflict. Good news is that in th every near future, ROBOTC will have re-entrant functions and recursion. When that's been added, this should no longer be an issue. Until then, do all your sensor stuff from a single task, if you're using my suite.

- 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]


Sun Jul 15, 2012 11:49 pm
Profile WWW
Rookie

Joined: Mon Jun 11, 2012 9:28 pm
Posts: 37
Post Re: Hitechnic IR link with multitasking
mightor wrote:
You can only do I2C related things from a single task. This has to do with a ROBOTC limitation in that a single function cannot be called from two different tasks simultaneously without risking conflict. Good news is that in th every near future, ROBOTC will have re-entrant functions and recursion. When that's been added, this should no longer be an issue. Until then, do all your sensor stuff from a single task, if you're using my suite.

- Xander


Thanks, Xander. As you can see from the code, I have attempted to do this, however I am getting a really strange delay in my program - the motors fire off late, or sometimes not at all. Am I doing it wrong?


Mon Jul 16, 2012 8:05 am
Profile
Moderator
Moderator
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3105
Location: Rotterdam, The Netherlands
Post Re: Hitechnic IR link with multitasking
It might help to see the rest of the code to see what the problem might be. The stuff you pasted doesn't really look like it could cause a delay.

- 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]


Mon Jul 16, 2012 8:21 am
Profile WWW
Expert

Joined: Tue Feb 28, 2012 3:10 pm
Posts: 195
Post Re: Hitechnic IR link with multitasking
I haven't used the PFMotor function, but I do notice in
Code:
task PFMotorControl()
{
  while(true)
  {
    if (whiteGateControl == false) {PFMotor(whiteGate,whiteGateClose);}
    if (whiteGateControl == true) {PFMotor(whiteGate,whiteGateOpen);}
   
    if (orangeGateControl == false) {PFMotor(orangeGate,orangeGateClose);}
    if (orangeGateControl == true) {PFMotor(orangeGate,orangeGateOpen);}
   
    if (whiteValveControl == false) {PFMotor(whiteValve,whiteValveClose);}
    if (whiteValveControl == true) {PFMotor(whiteValve,whiteValveOpen);}
   
    if (orangeValveControl == false) {PFMotor(orangeValve,orangeValveClose);}
    if (orangeValveControl == true) {PFMotor(orangeValve,orangeValveOpen);}
   
    //Not sure about this, just trying to stop it hogging the CPU.
    wait1Msec(1);
  }
}


you are calling that function 4 times a loop, every time, as opposed to an on/off toggle, and only waiting 1 msec. That is a pretty busy and tight loop, and would be my suspect.

_________________
Mike aka Spiked3
http://www.spiked3.com


Mon Jul 16, 2012 10:26 am
Profile
Rookie

Joined: Mon Jun 11, 2012 9:28 pm
Posts: 37
Post Re: Hitechnic IR link with multitasking
Spiked3 wrote:
I haven't used the PFMotor function, but I do notice in

snip

you are calling that function 4 times a loop, every time, as opposed to an on/off toggle, and only waiting 1 msec. That is a pretty busy and tight loop, and would be my suspect.


I tried with different waits, doesn't help.
I can put up the whole program when I get home, if you guys don't mind ignoring irrelevant parts. Just trying to make it easier on you :P

Thanks!


Mon Jul 16, 2012 1:14 pm
Profile
Moderator
Moderator
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3105
Location: Rotterdam, The Netherlands
Post Re: Hitechnic IR link with multitasking
Just attach it to a post as a file, rather than pasting the whole thing.

- 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]


Mon Jul 16, 2012 1:51 pm
Profile WWW
Rookie

Joined: Mon Jun 11, 2012 9:28 pm
Posts: 37
Post Re: Hitechnic IR link with multitasking
Here you go!

Thanks for your help.


Attachments:
Grid.c [4.34 KiB]
Downloaded 144 times
Mon Jul 16, 2012 6:43 pm
Profile
Moderator
Moderator
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3105
Location: Rotterdam, The Netherlands
Post Re: Hitechnic IR link with multitasking
When I compile it, I get the following warnings:
Code:
File "Grid.c" compiled on Jul 17 2012 17:43:37
*Warning*:There are possible simultaneous variable memory access conflicts for
               subroutine 'LSvalNorm' called from multiple tasks 'orangeValveCheck' and 'whiteValveCheck'
**Info***:There are possible simultaneous variable memory access conflicts for
               subroutine 'LSvalNorm' called from multiple tasks 'orangeValveCheck' and 'whiteValveCheck'
**Info***:There are possible simultaneous variable memory access conflicts for
               subroutine 'LSvalNorm' called from multiple tasks 'orangeValveCheck' and 'whiteValveCheck'

I would work on fixing that first. There were other warnings too, which you should fix as well, you use 'startTask' instead of 'StartTask'. The compiler will fix that one for you, but you should avoid that kind of thing as it can lead to unexpected behaviour.

- 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]


Tue Jul 17, 2012 11:46 am
Profile WWW
Moderator
Moderator
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3105
Location: Rotterdam, The Netherlands
Post Re: Hitechnic IR link with multitasking
I took the liberty of hacking your code to make a little more readable and remove the warnings. I think I know where the problem might be. Take another good, hard look at the wait statements in your main task.

Also if you have something like this
Code:
if (statement == false)
{
  // do something
}
if (statement == true)
{
  // do something else
}

It is better to make that into something like this:
Code:
if (something == false)
{
  // do something
}
else
{
   // do something else
}

Even better would be to flip it around and handle the "true" part first and let the code for the "false" part go below in the else part. I didn't change that in your code.
Also, avoid doing things like
Code:
if (statement == true) {//dosomething;}

It makes your code harder to read and it's easy to overlook things.
Also never have empty while loops, add a simple "EndTimeSlice();" to it or a longer wait.

Regards,
Xander


Attachments:
Grid-XS.c [4.17 KiB]
Downloaded 155 times

_________________
| 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]
Tue Jul 17, 2012 12:03 pm
Profile WWW
Rookie

Joined: Mon Jun 11, 2012 9:28 pm
Posts: 37
Post Re: Hitechnic IR link with multitasking
Thank you so much, Xander. I didn't know about endTimeSlice(), seems useful.

I took another look at the wait statements in the main task. Not sure what's going wrong. Am I not understanding the nature of multitasking here?

Thanks again.


Tue Jul 17, 2012 2:52 pm
Profile
Moderator
Moderator
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3105
Location: Rotterdam, The Netherlands
Post Re: Hitechnic IR link with multitasking
Sometimes it is simply not necessary to use multitasking :) I am pretty sure most of your code could be made into a single task but may require a little rethinking on your part :)

PS: Read my signature to get an idea of what threads (tasks) can do for you :)

- 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]


Tue Jul 17, 2012 3:03 pm
Profile WWW
Expert

Joined: Tue Feb 28, 2012 3:10 pm
Posts: 195
Post Re: Hitechnic IR link with multitasking
MultiTasking can be a hard concept to crack. The performance of multitasking is tightly coupled to decisions the vendor made in implementing it, and a lot depends on the scheduler. There are dozens of types of schedulers. Priority, where the highest priorities task that are ready to run do, round robin where everyone gets a bit of time, deadline where a task indicates it must run within a certain time etc. Unfortunately 9 times out of 10, the types get combined with the intention of getting the best of both worlds, like a priority scheduler and a round robin, and you end up with something not quite as expected. I suspect RobotC tries to do this.

Xander's comment about not using tasks is dead on; don't do it unless you have to, and then experiment to make sure it is doing things when you thought it would.

I would add to his comment about simplifying if statements
Code:
if (whiteGateControl == false) {PFMotor(whiteGate,whiteGateClose);}
    if (whiteGateControl == true) {PFMotor(whiteGate,whiteGateOpen);}


becomes
Code:
if (whiteGateControl)
     PFMotor(whiteGate,whiteGateOpen);
else
    PFMotor(whiteGate,whiteGateClose);


no extra brackets, or ==

I still also think (guess) that a toggle is what you want there. This would save cycles by not going through the system code to set a motor when the conditions are unchanged. maybe that helps, maybe not - I don't know the firmware internals, but in most other places in real life, it does help, and is probably a good habit.

Code:
bool lastWhitegate;
if (whiteGateControl != lastWhitegate)
{
    if (whiteGateControl)   
         PFMotor(whiteGate,whiteGateOpen);
    else
        PFMotor(whiteGate,whiteGateClose);
    lastWhitegate = whiteGateControl;
}

_________________
Mike aka Spiked3
http://www.spiked3.com


Tue Jul 17, 2012 4:48 pm
Profile
Rookie

Joined: Mon Jun 11, 2012 9:28 pm
Posts: 37
Post Re: Hitechnic IR link with multitasking
@Xander
Thanks, Xander. I have no idea how to do this without multitasking. The fact is, if I have certain routines (e.g. motor move such and such, wait a few seconds, then move back, wait a few seconds, and repeat) I am not sure how to achieve this in only one task - and I am not sure why you would try so hard not to use multitasking, either.

Show me the error of my ways ;)

@Spiked3
Thanks for that! I am not sure a toggle is what I want. Basically, I want my motors to run either one way or another, and I need to be able to control this.

Again, still not sure why and how I can avoid multitasking here.


Tue Jul 17, 2012 4:52 pm
Profile
Expert

Joined: Tue Feb 28, 2012 3:10 pm
Posts: 195
Post Re: Hitechnic IR link with multitasking
The last code snippet I posted should accomplish exactly what your code does, but only setting a new power when your value changes. Look at it a little more.

There is often an assumption that with tasks, if I wait 20 msec, that is what will happen. But truth is, it seldom is. What happens is your task waits, and after 20 msec, it is ready to run, but it will not run until the currently running task waits. The trick to accomplishing better tighter timing control is to do everything in a loop, and set a NextEventAt variable to tell you when to act.

Here is some pseudo code, not tested or compiled, but should convey the idea;

Code:
int nextOpenAt = -1;
int nextCloseAt = 32767;

while (true)
{
  int t = Timer[T1];
  if (t > nextOpenAt)
  {
    DoOpen();
    nextcloseAt = t+6000;
    nextOpenAT = 32767;
  }
  if (t > nextCloseAt)
  {
    DoClose();
    nextOpenAt = t+6000;
    nextcloseAt = 32767;
   }
   // do other stuff here as needed
}


There probably is some 'overflow' you need to think about (or use long if timers support them), but I hope this gets the idea across. You can also use an encoder value to trigger the next event, if that is more accurate than time, and it usually is.

Code:
task main()
{
    while (true)
    {
        if (nMotorEncoder[motorA] > 360)
            nMotorEncoderTarget[motorA] = -360;
        else if (nMotorEncoder[motorA] < -360)
            nMotorEncoderTarget[motorA] = 360;
        motor[motorA] = 50 * (nMotorEncoder[motorA] < nMotorEncoderTarget[motorA]?1:-1); //study this line a bit, it sets the direction
    }
}


I hope this gives you some ideas to think about.

_________________
Mike aka Spiked3
http://www.spiked3.com


Tue Jul 17, 2012 7:26 pm
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 31 posts ]  Go to page 1, 2, 3  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.