View unanswered posts | View active topics It is currently Tue Sep 16, 2014 7:24 am






Reply to topic  [ 28 posts ]  Go to page Previous  1, 2
RobotC bug concerning structures 
Author Message
Expert

Joined: Mon Mar 15, 2010 4:24 pm
Posts: 124
Post Re: RobotC bug concerning structures
MHTS wrote:
Like I said, the PID control code is written generically in a library. Sure, we can rewrite it without struct but then it is no longer a generic library that can apply PID control to any object. Currently, our code is using the library very heavily. Not using the library means a lot of rewrites, not to mention re-debugging. So the ideal solution is have the fix in v2.32. Alternatively, if Dick can explain what the bug is and suggest a simple work around without restructuring the code in a major way, that can do as well. Either way, the rewrite has to be minimal. I am not oppose to coding a simple workaround, but I need to understand the bug and how to work around it.


Good for sticking to your guns, MHTS! Short of full blown Objects, structs are the greatest thing since sliced bread (greatest thing since arrays? ;-)!

I have a PID controller that heavily uses structs, and I just checked and I definitely have a situation where a function accepts a structure reference as a parameter, then calls another function that also accepts a structure reference, so the bug must be something more specific than just "can't pass a structure through two layers of functions. Ask Dave, he may be able to tell you more specifically what the bug is.

Here's an example of my code that does work:

Code:
int PIDController(PIDControlData &TheData)
{
...stuff...

    UpdateMotorControlState(TheData);

...stuff...
}


Good luck!
Gary


Wed Nov 10, 2010 8:18 pm
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1347
Post Re: RobotC bug concerning structures
From what was explained to me, it is a different situation. Your code will work because you are passing the incoming struct reference to another function straight that doesn't involve computing the reference pointer. But mine involves retrieving struct references from the incoming struct and use it as a parameter to another function.


Wed Nov 10, 2010 10:40 pm
Profile
Expert

Joined: Mon Mar 15, 2010 4:24 pm
Posts: 124
Post Re: RobotC bug concerning structures
MHTS wrote:
From what was explained to me, it is a different situation. Your code will work because you are passing the incoming struct reference to another function straight that doesn't involve computing the reference pointer. But mine involves retrieving struct references from the incoming struct and use it as a parameter to another function.


Well, I have another more complicated setup with structs within structs that also works:

Code:
typedef struct
{
  PIDControlData PositionController;
  PIDControlData SpeedController;
...stuff...
} MotorControlData;

int PIDMotorController(MotorControlData &TheData)
{
  PIDController(TheData.PositionController);
  PIDController(TheData.SpeedController);
...stuff...
}


How does this square with Dick's description of the problem?

cu,
Gary


Thu Nov 11, 2010 12:22 am
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1347
Post Re: RobotC bug concerning structures
Mine is more like:
Code:
typedef struct
{
  PIDControlData &PositionController;
  PIDControlData &SpeedController;
...stuff...
} MotorControlData;


And I was planning to test a workaround that is exactly like yours (i.e. change the struct references in the struct to nested struct instead). It would be great if that will bypass the buggy compiler code path. Since you said this arrangement works for you, I am very encouraged that it would work for me as well. I will test this out in the next few days. Thanks for the suggestion.


Thu Nov 11, 2010 1:29 am
Profile
Expert
User avatar

Joined: Mon Oct 06, 2008 6:30 pm
Posts: 176
Location: Netherlands
Post Re: RobotC bug concerning structures
If the above workaround doesn't work you could also try to copy the struct into another and pass this one on.

_________________
My most recent blog: A grain of sugar


Thu Nov 11, 2010 8:16 am
Profile WWW
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1347
Post Re: RobotC bug concerning structures
Nested structure still doesn't work. So I ended up implementing global struct array and had to pass around "handles" (array index). I finally got my PID control code totally working now. Boy, the code is very messy. Since all the library functions are implemented in header files, I had to move the global array declaration before including the library header files because the library files must access the global struct arrays. I am also surprised by how much ANSI C is not supported by RobotC. For example, I could have used "extern" to forward declare the global struct arrays, but RobotC doesn't support that. I am also trying to implement some debug print functions that will take variable arguments (i.e. ...). But again, RobotC complains that only intrinsic functions support that syntax. RobotC doesn't allow you to pass array as function parameters but yet it allows "char *" which strictly speaking is a character array. It doesn't support pointers but yet "char *" is a pointer syntax.


Mon Nov 15, 2010 5:37 am
Profile
Moderator
Moderator
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3221
Location: Rotterdam, The Netherlands
Post Re: RobotC bug concerning structures
ROBOTC != ANSI C

You can't pass arrays, but you can pass a struct that's a thinly veiled array just fine. If it's ANSI C you're after, there are a couple of gcc based programming environments for the NXT but they do require a much deeper knowledge and understanding of the underlying hardware. The ease of use and higher level access to the hardware come at a price.

- 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 Nov 15, 2010 5:48 am
Profile WWW
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1347
Post Re: RobotC bug concerning structures
I understand RobotC is not ANSI C but I was hoping most of the fundamentals of the ANSI C language should be supported. I am just surprise on the some of the unsupported functionalities that are vital in modular programming. Regarding selecting an ANSI C environment, FTC only allows either RobotC or LabView. I personally don't like graphical programming, so RobotC is the only choice.


Mon Nov 15, 2010 5:59 am
Profile
Rookie

Joined: Fri Dec 31, 2010 7:01 am
Posts: 1
Post Re: RobotC bug concerning structures
If I rewrote it as the following, it works fine:


Code:
float DriveGetDistance(DRIVE &drive)
{
float dist;
float distPerClick;
int leftEncoder;
int rightEncoder;

distPerClick = drive.distPerClick;
leftEncoder = nMotorEncoder[drive.leftMotor];
rightEncoder = nMotorEncoder[drive.rightMotor];
dist = (float)(leftEncoder + rightEncoder)*
distPerClick/2.0;

return dist;
}


Fri Dec 31, 2010 7:05 am
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1347
Post Re: RobotC bug concerning structures
Yep, I have discovered this work around a while ago (that you can store them in explicit local varaibles and access the values through them). The problem is that this only addresses one of the bugs concerning passing a struct by reference. Another bug involves passing struct by reference through multiple functions. Apparently, there is no easy work around. I was told this has been fixed in RobotC 2.32 or later and I have been waiting for its release ever since. But in the meantime, I have reworked the code to avoid the bug. But the resulting code is extremely messy so I am still hoping the fix will release soon that I can clean up the mess.

Wait, your post is a cut and paste of part of my origianl post?!


Fri Dec 31, 2010 2:53 pm
Profile
Moderator
Moderator
User avatar

Joined: Wed Jan 31, 2007 3:39 am
Posts: 299
Location: San Diego, California. USA
Post Re: RobotC bug concerning structures
Hi MHTS,

I read through your original code and I noticed something, you are using pass by refrence to get the data over to the function, but the function does not need to alter the origional data in the structure, it just reads it. Can you get away with using pass by value instead of pass by reference for now? Looks like it would work for this specific function, hopefully would work for everything you guys are working on. Might only need to change the functions that pass farther than two down. :-)

float DriveGetDistance(DRIVE &drive)
{
float dist;

dist = (float)(nMotorEncoder[drive.leftMotor] + nMotorEncoder[drive.rightMotor])*drive.distPerClick/2.0;

return dist;
}

Good luck, happy new year! B-)

_________________
Mmmm Legos B-)

My Robot Projects:
http://www.freewebs.com/robotprojects/


Sat Jan 01, 2011 6:10 am
Profile WWW
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1347
Post Re: RobotC bug concerning structures
Happy New Year to you too.

Thanks for the suggestion. What do you mean by "passing by value"? Do you mean doing something like this? Would RobotC copy the DRIVE structure onto the stack as a parameter?
Code:
float DriveGetDistance(DRIVE drive)
{
    ...
}

In any case, we are no longer blocked by this issue because we already reworked the code to avoid this problem. It's not ideal but it got us through the regional competitions. We would clean up the code once RobotC v2.32 or later is released. BTW, any news on when this will be released?
Thanks.


Sat Jan 01, 2011 2:31 pm
Profile
Moderator
Moderator
User avatar

Joined: Wed Jan 31, 2007 3:39 am
Posts: 299
Location: San Diego, California. USA
Post Re: RobotC bug concerning structures
Yes, pass by value is when a copy of the parameter is pushed onto the stack. The function then uses this copy of the original variable or structure in the function. Only downside is pass by value does not allow the original variable or structure passed to be modified, it uses a copy, that's why pass by reference was created

Code:
........
{
DRIVE x;
DriveGetDistance(x);
}

float DriveGetDistance(DRIVE drive) // pass by value, a copy of x will be used in the function, not the structure x
{
    ...
}


pass by reference is when a pointer is pushed onto the stack and used by the function. Advantage is you can modify the original structure or variables data within a function. Disadvantage is that pointers are now used in the function, RobotC handles this well but if coding in pointer supported c and c++, be very very careful lol, syntax becomes very different when dealing with the pointers.

Code:
........
{
DRIVE x;
DriveGetDistance(x);
}

float DriveGetDistance(DRIVE &drive) // pass by refrence, a pointer to x will be used, can modify x this way
{
    ...
}


On a side note, my advice would be to use pass by reference only if the function really needs to modify the original variable or structure. When a different programmer reads your code and sees you using pass by reference, it implies that something special is going on inside the function. Its also a good habit to get into when moving to other languages, RobotC handles the pass by reference pointers much nicer than other languages and dialects of c do. I could see it as a bad habit to always use pass by reference when its not needed in robotC.

Glad to hear you got it working, Good luck at competition B-)
Scott

_________________
Mmmm Legos B-)

My Robot Projects:
http://www.freewebs.com/robotprojects/


Sun Jan 02, 2011 8:52 am
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 28 posts ]  Go to page Previous  1, 2

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.