NXC Motor Functions

Discussion specific to NXT-G, NXC, NBC, RobotC, Lejos, and more.
Post Reply
monxc
Posts: 18
Joined: 17 Oct 2011, 10:23

NXC Motor Functions

Post by monxc »

Hello,

I've just started programming the NXT using the NXC language and I've come up against a problem I'm hoping some kind soul here can help me with...

I'm trying to write a function that centres the rack-and-pinion steering on a buggy using the following logic:
1. Turn the steering (motor) until it stalls (i.e. MotorRotationCount() returns the same number either side of a Wait(100))
2. Turn the steering (motor) back a known rotation (400 degrees in this case)
3. Store the value now returned by MotorRotationCount() as the centred steering value (I've tried using ResetRotationCount() but it doesn't seem to do anything)

However, when I set the steering (motor) to the stored "centred" value, the motor stops in a different position. I've tried using MotorTachoCount() as well, and I get slightly different results (sometimes) that I can't seem to predict...

Can anybody tell me what exactly MotorRotationCount() and MotorTachoCount() do and how they differ, please? Do they return absolute (i.e. position) or some sort of relative value (e.g. degrees rotation since the motor was last turned on or something...). Also, why don't ResetRotationCount() or ResetTachoCount() seem to set their respective values to zero?

Thanks for any help with this,

monxc


p.s. Just for completeness, here's my code:

Code: Select all

sub cntrSteer()
{
  bool stalled = FALSE;
  int curCnt;
  
  ResetRotationCount(OUT_C);
  NumOut(0,LCD_LINE1,MotorRotationCount(OUT_C),TRUE);
  OnFwd(OUT_C, 25);
  while(!stalled)
  {
    curCnt = MotorRotationCount(OUT_C);
    Wait(100);
    if(curCnt == MotorRotationCount(OUT_C))
    {
      stalled = TRUE;
    }
  }
  taskBeep();
  NumOut(0,LCD_LINE2,MotorRotationCount(OUT_C),DRAW_OPT_LOGICAL_OR);
  RotateMotor(OUT_C, 60, -440);
  //ResetRotationCount(OUT_C);
  Wait(500);
  CNTR = MotorRotationCount(OUT_C);
  NumOut(0,LCD_LINE3,MotorRotationCount(OUT_C),DRAW_OPT_LOGICAL_OR);
  taskBeep();
}

Code: Select all

sub truckCntr()
{
  while(MotorRotationCount(OUT_C) != CNTR)
  {
    if(turnAngle < 0)
    {
      OnFwd(OUT_C,60);
    }
    if(turnAngle > 0)
    {
      OnRev(OUT_C,60);
    }
  }
  Off(OUT_C);
  NumOut(0,LCD_LINE4,MotorRotationCount(OUT_C),DRAW_OPT_LOGICAL_OR);
}
turnAngle is an int that stores the current direction of the steering - it can only be 250, 0 or -250 at the moment...
---111 040 150 141 166 145 040 156 157 040 151 144 145 141 040 167 150 141 164 040 111 047 155 040 144 157 151 156 147 056 056 056---
linusa
Posts: 228
Joined: 16 Oct 2010, 11:44
Location: Aachen, Germany
Contact:

Re: NXC Motor Functions

Post by linusa »

monxc wrote: Can anybody tell me what exactly MotorRotationCount() and MotorTachoCount() do and how they differ, please? Do they return absolute (i.e. position) or some sort of relative value (e.g. degrees rotation since the motor was last turned on or something...). Also, why don't ResetRotationCount() or ResetTachoCount() seem to set their respective values to zero?
The reset-commands do set the according counters to zero, but it takes one firmware tick to get the counters updated. If you want to use (e.g. display) the values right away, you have to insert a Wait(1);. Please do so and repeat your test -- it should show the intended result.

The LEGO firmware has 3 independent counters for each motor. They are "absolute", as long as they aren't reset. BlockTachoCount is usually used by NXT-G to create a relative reading between certain NXT-G motor blocks, and during synchronized driving of two motors. The use of RotationCount and TachoCount depends on the software you use. You have to do some tests, as I can't remember which one it is, but each call of RotateMotor() resets one of those counts (I think it's TachoCount) when it starts. So if you want to go to -440 degrees, TachoCount (or the other one) is reset to 0 and the motor runs until it reads -440.

The other counter (I think it's RotationCount) is "free for you to use", it keeps tracking and adding up all movements until you reset it.

I just saw your RotateMotor(OUT_C, 60, -440);. Are you sure that's possible? Please look it up in the documentation. I think maybe it has to be RotateMotor(OUT_C, -60, 440);, as you control the direction of movement via the sign of power, not via TachoLimit.
RWTH - Mindstorms NXT Toolbox for MATLAB
state of the art in nxt remote control programming
http://www.mindstorms.rwth-aachen.de
MotorControl now also in Python, .net, and Mathematica
monxc
Posts: 18
Joined: 17 Oct 2011, 10:23

Re: NXC Motor Functions

Post by monxc »

Hi,

thanks for your help - adding a Wait(1) has fixed the ResetRotationCounter() problem.

I've tried controlling the rotation of the motor by inverting both the Power argument and the Degrees argument - either work fine (I'm running the Firmware 1.36 - perhaps it allows for this?)

I think it may be MotorTachoCount() that gets reset by RotateMotor() - I haven't exhaustively tested this, but it would explain some of the behaviour I get from my code...

I still can't get the motor to rotate back to its original position, though. The value returned by MotorRotationCount() is 0, but the motor stops short of where it was when it was last 0...

Is there any better documentation than that found at http://bricxcc.sourceforge.net/nbc/nxcdoc/index.html or http://bricxcc.sourceforge.net/nbc/nxcdoc/nxcapi/? The guide by Daniele Benedettelli is very helpful, but doesn't cover everything - the NXC "help" files are typically of the form "long MotorTachoCount(byte output) - Get motor tachometer counter." - no explanation of their actual function/purpose...

Thanks again,

monxc
---111 040 150 141 166 145 040 156 157 040 151 144 145 141 040 167 150 141 164 040 111 047 155 040 144 157 151 156 147 056 056 056---
monxc
Posts: 18
Joined: 17 Oct 2011, 10:23

Re: NXC Motor Functions

Post by monxc »

Hello,

after a bit of playing about, I've come up with the following theory (and solution to my problem).

The optical (I'm assuming) sensor in the motor has some degree of width to it and, depending on which way the motor is rotating, it will alter the MotorRotationCount() value either at the original point or slightly short of it. I've compensated for this in my code by adding 50 degrees to the rotation if it's rotating clockwise but not if its rotating anti-clockwise and this brings the steering more accurately into line.

Accuracy to +/-50 degrees seems unlikely to me, but it appears to work - any further thoughts on the matter will be very gratefully received...

Thanks,

monxc
---111 040 150 141 166 145 040 156 157 040 151 144 145 141 040 167 150 141 164 040 111 047 155 040 144 157 151 156 147 056 056 056---
linusa
Posts: 228
Joined: 16 Oct 2010, 11:44
Location: Aachen, Germany
Contact:

Re: NXC Motor Functions

Post by linusa »

monxc wrote: Is there any better documentation than that found at http://bricxcc.sourceforge.net/nbc/nxcdoc/index.html or http://bricxcc.sourceforge.net/nbc/nxcdoc/nxcapi/? The guide by Daniele Benedettelli is very helpful, but doesn't cover everything - the NXC "help" files are typically of the form "long MotorTachoCount(byte output) - Get motor tachometer counter." - no explanation of their actual function/purpose...
What helped me is the "NXT Executable File Specification" PDF, from page 49, here: http://cache.lego.com/upload/contentTem ... B2A1F6.pdf

Also there used to be an old NXC documentation, one single PDF file, which is now the Doxygen API doc you linked to. This old file contains a table similar to the LEGO PDF, which helped me a lot. Here's this old version, http://css.engineering.uiowa.edu/~cie/L ... _Guide.pdf , page 48 (PDF page 53).

The current NXC PDF is huge and you might get lost http://bricxcc.sourceforge.net/nbc/nxcdoc/NXC_Guide.pdf -- but I'd suggest you also browse around the pp. 751ff., section 6.126 (PDF pp. 811ff.)

The +/- 50 degree accuracy is not observed with NXT motors. Check your motor, maybe replace it with another one to verify. The internal counter is accuraty to 1 degree. If your whole gear / steering varies in one direction and not the other, there must be mechanical reasons in your construction. When you turn a gear in one direction and back in another, there is a "gap" / "space" space between the gears. This problem is very common. You can counter it by pre- / spring-loading gears, or create a better way to calibrate the TachCount you need. You might also need to store "whether you're coming from the right or from the left", to get the one-side error of + 50 you have to +/- 25 and then smaller...
Edit: Ah, I see, that's what you did with your clockwise / counter-clockwise thing. Anyway, the rotation counter is not the reason, unless its broken! Try it with an NXT motor by turning it by hand, and monitoring the degrees output.
RWTH - Mindstorms NXT Toolbox for MATLAB
state of the art in nxt remote control programming
http://www.mindstorms.rwth-aachen.de
MotorControl now also in Python, .net, and Mathematica
monxc
Posts: 18
Joined: 17 Oct 2011, 10:23

Re: NXC Motor Functions

Post by monxc »

Hi,

I quite agree - the +/- 50 degree accuracy thing must be a problem with that motor (my steering assembly has very little backlash to avoid precisely this problem) - I somewhat regret building it into my "robot" quite as thoroughly as I have done - replacing it will be difficult :(

I'll read the pages you recommend - from a brief scan of the uiowa.edu link, it looks very helpful - many thanks for your guidance on this.

Time to dig out a spare motor and run some tests...

Thanks for your help again,

monxc
---111 040 150 141 166 145 040 156 157 040 151 144 145 141 040 167 150 141 164 040 111 047 155 040 144 157 151 156 147 056 056 056---
Post Reply

Who is online

Users browsing this forum: No registered users and 26 guests