ROBOTC.net forums
http://www.robotc.net/forums/

RobotC bug concerning structures
http://www.robotc.net/forums/viewtopic.php?f=52&t=2712
Page 1 of 2

Author:  MHTS [ Mon Nov 01, 2010 3:00 am ]
Post subject:  RobotC bug concerning structures

I have a function that passed in a structure by reference. When I referenced a field in the structure, it hung the NXT brick. If I retrieved the value of the field to a separate variable first, then it succeeded. Here is a simplified example:

Code:
typedef struct
{
  int leftMotor;
  int rightMotor;
  float distPerClick;
  ...
} DRIVE;

float DriveGetDistance(DRIVE &drive)
{
  float dist;

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

  return dist;
}

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;
}

Author:  MHTS [ Mon Nov 01, 2010 3:04 am ]
Post subject:  Re: RobotC bug concerning structures

BTW, forgot to mention this is with the latest version of RobotC (version 2.26).

Author:  mightor [ Mon Nov 01, 2010 6:46 am ]
Post subject:  Re: RobotC bug concerning structures

Next time please include a fully working sample program, it will make attempting to reproduce the problem much easier.

This piece of code works fine for me:
Code:
typedef struct
{
  int leftMotor;
  int rightMotor;
  float distPerClick;
} _DRIVE;

float DriveGetDistance(_DRIVE &drive)
{
  float dist;

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

  return dist;
}

task main () {
  float distance = 0.0;
  _DRIVE drive;
  motor[motorA] = 100;
  motor[motorB] = 50;
  wait1Msec(1000);
  motor[motorA] = 0;
  motor[motorB] = 0;

  drive.leftMotor = motorA;
  drive.rightMotor = motorB;
  drive.distPerClick = 1.2;

  distance = DriveGetDistance(drive);
  nxtDisplayTextLine(2, "%f", distance);
  while(true);
}


Regards,
Xander

Author:  Aswin [ Mon Nov 01, 2010 12:48 pm ]
Post subject:  Re: RobotC bug concerning structures

I work with structs quite a lot. In my experience with 2.26 structs work fine as long as you pass structs only one level deep. But if the function you passed the structs to passes this struct to another function then you'll get the problems you describe. So try to avoid nesting of functions that accept call by reference.

In older versions of robotc I have noticed that it does make a difference where in the program you defined your structs and variables. Relocating the definitions sometimes solved my problems with structs.

Author:  MHTS [ Sat Nov 06, 2010 4:06 pm ]
Post subject:  Re: RobotC bug concerning structures

Yep, I was busy the last few weeks. I finally got some time to stripe away all my code to isolate the simplest repro scenario. It seems you are right, my code involved passing a struct deeper than one function. Here is the simplified repro code:
Code:
#pragma config(Motor,  motorB,          motorRight,    tmotorNormal, openLoop, encoder)
#pragma config(Motor,  motorC,          motorLeft,     tmotorNormal, openLoop, encoder)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

//
// Type definitions.
//
typedef struct
{
    int   leftMotor;
    int   rightMotor;
    float distPerClick;
} DRIVE;

typedef struct
{
    float setPoint;
} PIDCTRL;

typedef struct
{
    DRIVE   &drive;
    PIDCTRL &drivePIDCtrl;
} PIDDRIVE;

//
// Global data.
//
DRIVE    g_Drive;
PIDCTRL  g_DrivePIDCtrl;
PIDDRIVE g_PIDDrive;

float
DriveGetDistance(
    DRIVE &drive,
    )
{
    float dist;

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

void
PIDDriveSetTarget(
    PIDDRIVE &pidDrive,
    float distSetPoint
    )
{
    pidDrive.drivePIDCtrl.setPoint = distSetPoint +
                        DriveGetDistance(pidDrive.drive);
}   //PIDDriveSetTarget

task main()
{
    g_Drive.leftMotor = motorLeft;
    g_Drive.rightMotor = motorRight;
    g_Drive.distPerClick = 6.83/360.0;
    g_PIDDrive.drive = g_Drive;
    g_PIDDrive.drivePIDCtrl = g_DrivePIDCtrl;
    PIDDriveSetTarget(g_PIDDrive, 120.0);
}   //main

I am getting a little bit frustrated of finding the limitations of RobotC though. Can this be fixed? It would be nice to support as close to ANSI C as possible so that I don't have to wonder when something doesn't work that whether I hit another limitation or it is really a bug in my code. The reason I am doing a lot of struct like this is to simulate C++ objects.

Author:  Aswin [ Sun Nov 07, 2010 6:14 am ]
Post subject:  Re: RobotC bug concerning structures

Hi,

I noticed that your structs are defined globally. So there is no need to pass them to functions. This will solve your problem.

You should not get frustrated by the limitations of robotic. Try to accept it.

Author:  MHTS [ Sun Nov 07, 2010 7:06 am ]
Post subject:  Re: RobotC bug concerning structures

I do need to pass those structs even if they are defined globally because I could pass in different instances of the struct. The function needs to know which struct it is operating on. That's why I said I am simulating C++ objects here. Without this capability, it is very difficult to write modular code.

Author:  Aswin [ Sun Nov 07, 2010 11:21 am ]
Post subject:  Re: RobotC bug concerning structures

I see. I couldn't make that up from the code.

But if you have multiple instances then his solution might work for you. Place the structs in an array, each instance corresponding to one array item. You can hen refer to an instance of he struct by passing only the index number from he array.

I know this isn't really a C++ like solution.

Author:  MHTS [ Sun Nov 07, 2010 2:25 pm ]
Post subject:  Re: RobotC bug concerning structures

The example program is a much simplified version of the code to demonstrate the problem. That's why you don't see multiple instances of the struct. I did think about using an array of structs and passing an index but if RobotC is going to fix this, I rather not massively change my code to this "workaround". I used struct everywhere so it is a lot of code. However, it is true that I don't pass the struct references in functions more than one deep everywhere. So you could suggest I just change the code that did. But then, some code will pass the struct by reference and some code will pass by index (or "handle"). It will be ugly and inconsistent. I am developing a Robotics library, so consistency of the interface is important. Besides, in writing future modules or even changing existing modules, I have to be careful not to pass the references more than one deep and if I do I need to change the interface to pass by handle. That's why I am frustrated with it. I rather figure out a temporary workaround that doesn't involve changing the interface and wait for RobotC to have it fixed, but I don't have time to experiment with workarounds and figure out which one works! So I need help from the RobotC folks to:
    Confirm the issue
    Suggest a simple workaround
    Communicate an ETA of a fix
I'd really appreciate that.

Thanks.

Author:  mightor [ Sun Nov 07, 2010 4:24 pm ]
Post subject:  Re: RobotC bug concerning structures

If you want the devs to respond, I suggest you mail support@robotc.net.

- Xander

Author:  MHTS [ Sun Nov 07, 2010 6:08 pm ]
Post subject:  Re: RobotC bug concerning structures

I already have an open ticket on it. But Dick replied saying he couldn't repro the problem so I replied the ticket with the isolated sample code yesterday. I haven't heard anything yet. I am not familiar with the ticket system. Does it generate a notification to the devs when I replied the ticket? Or do I send another email to support?

Author:  mightor [ Mon Nov 08, 2010 2:52 am ]
Post subject:  Re: RobotC bug concerning structures

Pretty sure he'll be notified.

- Xander

Author:  MHTS [ Wed Nov 10, 2010 5:44 pm ]
Post subject:  Re: RobotC bug concerning structures

Dick found and fixed the bug in RobotC version 2.32. The question now is: when is version 2.32 going to be released? Our team is getting nervous since we don't have much time left. We need this fix for our PID control code. Without it, everything using PID will hang the NXT brick with a faint clicking noise (BTW, what caused this clicking noise?). An ETA would be very much appreciated.
Thanks.

Author:  mightor [ Wed Nov 10, 2010 5:48 pm ]
Post subject:  Re: RobotC bug concerning structures

Is there no way to rewrite your code? I've written PID controllers before and they never needed structs. Sticking to a piece of code that is known to trigger a bug and then waiting for a fix is a really risky approach. Find a solution that works -now- and not later.

- Xander

Author:  MHTS [ Wed Nov 10, 2010 6:06 pm ]
Post subject:  Re: RobotC bug concerning structures

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.

Page 1 of 2 All times are UTC - 5 hours [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/