AForge.NET

  :: AForge.NET Framework :: Articles :: Forums ::

LEGO NXT: What does BRAKE flag really do?

Forum to discuss AForge.NET Framework, its features, API, how-tos, etc.

Re: LEGO NXT: What does BRAKE flag really do?

Postby linusa » Wed May 18, 2011 9:43 pm

jtracymn wrote:1. The only drive control I can find is using the "tacholimit" variable. This does not seem reliable, repeatable and precise [gave them info from my testing].

It is reliable in "it does what it was designed for". It turns off the motor power when the motor comes by the the tacholimit. But the motor is still spinning. It has a rotational moment. It turns too far (i.e. overshooting). All the firmware does is switch from runstate RUNNING to IDLE.

If it turns too far, the next time it will turn less than you expect. I posted the according links above. This is complicated and might be confusing, but once you understood what it does (i.e. you understand the underlying system), you can predict exactly what's going to happen with the next motor command.

jtracymn wrote: Is there another command set to send that can control the exact rotations?

No. Not with standard FW and via direct commands. That's why I developed motor control. There is however much development been going on, but all on firmware level. You can
- use the LeJOS firmware. It reacts differently on the direct commands and might do what you want, but it's not strictly compatible and has other problems. We evaluated this thoroughly before developing MotorControl.
- You can read this http://nxt-firmware.ni.fr.eu.org/change ... egulation/ and try to use this new experimental firmware. I'm not sure if there is a direct command to access this functionality...
- Modify the firmware on your own. Extremly complicated.

I compiled links for futher reading here: http://www.mindstorms.rwth-aachen.de/tr ... rInternals

jtracymn wrote:Since we can query this value, and based on my testing, it is very accurate, why can we not control the motor using this as the variable (similar to closed loop motion control systems I have controlled for years).

Yes, you can of course do that. Two big advantages:
1.) Bluetooth lag. About 20 to 30ms, i.e. 60ms for one whole "read value and set new power" round trip cycle. That's too slow for a good controller, I believe. If not, I'd be happy to see your results or read links you have about that topic.
2.) You "waste the valuable bandwidth" for the control loop. With Bluetooth you have about 15 "packet requests" per second (the 60ms from above). If all that is used for motor control, you don't have anything left to read sensors or other motors etc...

Even for USB (about 3ms lag), overall this lag still is a dealbraker. Loading motor control off to the brick is a far better idea, and has proven to be the superior concept.


jtracymn wrote:2. The "Brake" flag does not seem to do what it is supposed. to. I verified that it is being set (it does cause a change in function) but does not do what we expect it to do: which is brake the motor after the move is done. Can they verify this [gave them the detailed info and code from my test].

The BRAKE flag, as I posted above, has nothing to do with "motor braking" via direct commands or TachoLimit etc. We've not yet observed a difference in many years of development when disabling thsi flag, but a bachelor thesis which examined the NXT when it came out said: "it uses more battery power when enabled, but overal motor control is slightly better". This applies to NXT-G, and firmware. It has something to do with the hardware motor control H-bridge mode. If you want to read that thesis, I can dig out the link. I think it was from the ETH Zürich.

jtracymn wrote:In order to solve these two problems for the short term, i wrote my own control method:
1. I set the tacholimit to "0" (run forever).
2. then set the motor state and the motor start turning.
3. I then query the rotationcount parameter until I get to the distance I want.
4. then set the motor state to off. even though the "brake" mode is set, it will not brake (although it does behave differently if the brake paraemter is not set, this is how I know the change is being accepted). Thus, I have to do the following to brake it.
a. set the power to -10 (or whatever the opposite sign of the move is).
b. set the tacholimit to 1 (i think... cant recall, it is at home)
c. set the motorstate to run.

this works fairly well.

If you want to "brake" the motor really hard, you can issue a command with tacholimit 0, speed regulation enabled, and power = 0. It's very powerful. The motor stops at once, however oscillating. Look at the blue line here: http://www.mindstorms.rwth-aachen.de/tr ... _NoReg.png

If you use this combination of parameters from here: http://www.mindstorms.rwth-aachen.de/tr ... ns.nxc#L68 , you get the desired effect. This is far more effective than using power -10.

jtracymn wrote:One of the main problems with this of course is the communication time. Thus, when I reach the counts I want, then tell it to stop, it will go a distance beyond this. However, this distance is very consistent. So I wrote a small calibration routine which calcluates the offset for different speeds (and you would do it when you change surfaces or tires, etc). Then this offset is used to determine when to brake the motor.

anyway, it is an OK short term solution, but hopefully we will get the correct one soon.

Yes, this approach is ok in the beginning, but not really great and versatile on the long run. It also doesn't work for changing loads on the motor. I think nxt-python has (or had) this implemented. The problem is, it's not general, it depends on your robot and on communication lag specifics and many other factors.

jtracymn wrote:by the way, the lego representative said the NXT-G program is written in Labview.

Well, that's not entirely correct. Basically NXT-G is a "high-level, kid-friendly" interface for LabView, that's correct. It probably somehow translates the NXT-G program to LabView internally, and then compiles it to LEGO Firmware Bytecode, executed by the virtual machine. You can get a LabView program to either create "NXT-G like programs" directly in Labview (being compiled for the brick), or to use direct commands.

jtracymn wrote: Thus, I am guessing that perhaps some of the control is similar to what I have started to do above.

Well, internally they use a PID controller, you can look at the original firmware sourcecode, but it's not greatly documented. If you want to know what the Move- and the Motor-Blocks in NXT-G do, I analyzed them back a while ago. You can try to emulate this via a certain sequence of direct commands, but it's time critical, so the lag comes in.

The motor block has a HARD brake: http://www.mindstorms.rwth-aachen.de/tr ... _NoReg.png
The move block does a softer stop: http://www.mindstorms.rwth-aachen.de/tr ... eBlock.png

jtracymn wrote: The advantage they have is that this runs resident on the brick, thus no communication and execution delay similar to sending real time commands via bluetooth as I am doing in C#. I wonder if we can run a compiled C# program resident... probably not.

You have only 32kb of RAM, and I believe 256kb of flash (but look it up). So it's gonna be hard. On the other hand, LeJOS exists (Java). The most popular on-brick language is probably NXC. It's a C-dialekt.
User avatar
linusa
 
Posts: 18
Joined: Mon May 16, 2011 5:04 pm
Location: Aachen, Germany

Re: LEGO NXT: What does BRAKE flag really do?

Postby linusa » Wed May 18, 2011 9:45 pm

jtracymn wrote:p.s. I just received a reply from lego... they are still working on getting the answers to my questions, but it's nice to see they are responding.

In my experience LEGO support wasn't always the quickest, nor were they always correct. The best place to get answers from the experts and some great developrs is at the Mindboards forums (google or see link from above).
User avatar
linusa
 
Posts: 18
Joined: Mon May 16, 2011 5:04 pm
Location: Aachen, Germany

Re: LEGO NXT: What does BRAKE flag really do?

Postby linusa » Wed May 18, 2011 9:50 pm

mrbencowell wrote:Last night I started experimenting with the Motor Control software running on the NXT brick that Linus has produced and suggested as that seems possibly the quickest and neatest solution for my particular project. I didn't actually get very far as it means digging back through aforge to see how Andrew is communicating and sending bytes to the brick and then building a new interface based on what I learn. I'm not a C# programmer by any means so I'm pretty slow. I do think I'll have something working in a day or two though !.

Luckily the information here : http://www.mindstorms.rwth-aachen.de/trac/wiki/MotorControl is very clear .. I'm more grappling with C# and my lack of ability than anything else.

I'm sorry that I don't have time to look at this myself, but basically all you have to do is to get the MessageWrite and MessageRead commands, and then use them accordingly to the documentation link. I hope you also saw THIS link: http://sourceforge.net/apps/phpbb/mindb ... rt=0#p1607

It's a tutorial about the crucial part of PC<->NXT communication. If the MessageWrite and MessageRead commands don't exist, then unfortunately, it get's nasty when composing byte-packets, yes :-/
User avatar
linusa
 
Posts: 18
Joined: Mon May 16, 2011 5:04 pm
Location: Aachen, Germany

Re: LEGO NXT: What does BRAKE flag really do?

Postby linusa » Wed May 18, 2011 9:57 pm

one_eddie wrote:(I mean current Aforge implementation) to fix it but what if there were something like stored procedures? This can be a very simple solution. AForge should deliver basic programs like move, moveWithTurn, turnNDegree, turn180, etc. which should be downloaded to the brick (say auto after connected to robot). Then AForge should allow us to run those programs. This will allow to combine few simple actions in one command and compress the communication command used. I think I see how this should be implemented but whether it will be practical to use, can't say. What do you think?


I've researched this approach before developing MotorControl. In theory, it works. The direct command StartProgram does what you want. Unfortunately, there's a little additional "start up" time lag until the program is up and running. In the end this concept is to inflexible. You want customizable procedures, how do you pass the parameters?

And sooner or later you'll run in the timing conflicts like "start program A, wait for it to finish -- has it finish yet? start program B -- stop probram B -- has it stopped yet?", and so in. Eventually you either insert long safe pauses, and everything is slow, OR you want it faster and keep polling stuff until it becomes too much work and overhead to do all the polling...


If you guys want some more technical details about HOW we developed our remote control solution for MATLAB and WHY we did the things the way we did, I could recommend this free book chapter: "Teaching Practical Engineering for Freshman Students Using the RWTH - Mindstorms NXT Toolbox for MATLAB ". Section 2.1 give a brief overview of existing programming languages... There are more resources on the web, one of them is here: http://en.wikipedia.org/wiki/Lego_Minds ... anguages_2
User avatar
linusa
 
Posts: 18
Joined: Mon May 16, 2011 5:04 pm
Location: Aachen, Germany

Re: LEGO NXT: What does BRAKE flag really do?

Postby one_eddie » Thu May 19, 2011 12:44 pm

@linusa: I think till yesterday I didn't realized how RWTH and MotorControl was implemented. I just started digging into the guts to see how it's done I after a while I found you're using a dedicated program (framework as you like) to execute the commands. I have I an existing implementation of robot behavior made using Aforge. Those movements are not precise and I came to a conclusion I could probably use your work to fix those issues. I came to few ideas:

1. Build your plugin which is written in M code to a DLL (as I remember MATLAB has such features and appropriate tools)
2. Translate you M files to C# (What about license, does it allow such work?)
3. Use MC on the brick but build special interface for it in C#.

O course I hope I understand it correct if not please correct me.

Because I already started learning RWTH and MC I would like to ask what do you think. Are those approaches valid? Which one is best in your opinion (All my behavior and tools are written in C# so I must so .NET environment must be the caller)?

Best regards,
Krzysztof
one_eddie
 
Posts: 25
Joined: Tue Mar 29, 2011 2:59 pm
Location: Poland

Re: LEGO NXT: What does BRAKE flag really do?

Postby linusa » Thu May 19, 2011 2:57 pm

one_eddie wrote:1. Build your plugin which is written in M code to a DLL (as I remember MATLAB has such features and appropriate tools)

Don't do that. I'm not sure about the license, but MATLAB is proprietary software and expensive. Also it's really big. I tried compiling an exe-file from a program once, and the runtime is > 160MB. Apart from that, you'd port the whole RWTH toolbox to C#. I think it's not what you want.

one_eddie wrote:2. Translate you M files to C# (What about license, does it allow such work?)

See above, I don't think you'd want that. It's definitely allowed by the license (GPLv3), and I could answer questions. But don't underestimate that process. You can of course use the source-code as a help guideline!

one_eddie wrote:3. Use MC on the brick but build special interface for it in C#.

Yes, I'd recommend that. That's what we do. We have an interface inside our toolbox to talk to MotorControl on the brick. That's what's actually documented here http://www.mindstorms.rwth-aachen.de/tr ... torControl . It tells you exactly what to do in ANY language you want, to treat MotorControl "as a black box" or "plugin" and write your own interface to it. Once done, it all works nicely. Unfortunately it's a bit of work, as is described there, since you need to compose the string messages and make sure you keep the timing pauses...


I'd go for 3.). An alternative would be to call MATLAB from C#, but then you always have to have MATLAB installed or distribute it and have a license, and it might be slow (i.e. have a MATLAB "server" or "slave" running in the background that talks to the NXT, and you just remote control MATLAB)...
User avatar
linusa
 
Posts: 18
Joined: Mon May 16, 2011 5:04 pm
Location: Aachen, Germany

Re: LEGO NXT: What does BRAKE flag really do?

Postby mrbencowell » Thu May 19, 2011 3:02 pm

Option 3 is what I'm working on. I'll update here once I get something working.

cheers !
ben
User avatar
mrbencowell
 
Posts: 17
Joined: Sat May 14, 2011 4:29 pm

Re: LEGO NXT: What does BRAKE flag really do?

Postby one_eddie » Thu May 19, 2011 4:05 pm

mrbencowell wrote:Option 3 is what I'm working on. I'll update here once I get something working.


Are you working on some kind of own/custom interface? or maybe you are going to make a contribution to AForge and allow us to talk to MC using existing AF interface?
one_eddie
 
Posts: 25
Joined: Tue Mar 29, 2011 2:59 pm
Location: Poland

Re: LEGO NXT: What does BRAKE flag really do?

Postby mrbencowell » Thu May 19, 2011 4:23 pm

Yeah I'm just trying to hack together something that sends the correct byte codes and take it from there. I'm extremely new to C# programming and so I doubt I'll be able to manage creating a complete solution for communicating with the MotorControl that'd work for everyone. However I'd very happily post my code on here so people can use it or someone more experienced than myself could integrate it into aforge as a supported motor class method.
cheers !
ben
User avatar
mrbencowell
 
Posts: 17
Joined: Sat May 14, 2011 4:29 pm

Re: LEGO NXT: What does BRAKE flag really do?

Postby mrbencowell » Thu May 19, 2011 11:57 pm

Well .. after a night of tinkering and trying to get my head wrapped around bluetooth communication I've got somewhere and nowhere.

Somewhere in that I can manually connect to the brick and I can get it to play a tone. So I know I'm partly on the right track with my bluetooth commands.

However I can't raise a response from MotorControl running on the brick.

This is a sample of my code.

Code: Select all
  public static byte[] MC_MoveMotors(SerialPort BluetoothConnection, string MotorCommand)
        {
            byte[] Command = new byte[17];

            // Mailbox command
            Command[0] = (byte)(0x00);
            Command[1] = (byte)(0x09); // Leave in Mailbox
            Command[2] = (byte)(1); // Mailbox number -1 (e.g. for mailbox 1 use 0)
            Command[3] = (byte)(13); // Byte 5: 0x05 (this is the datalength: 1 byte + a 1 byte terminator)

            // Motor control command
            Command[4] = (byte)(1); // MotorControl Header

            // Put the Motor Command into the Array
            for (int f = 0; f < (MotorCommand.Length); f++)
            {
                Command[f + 5] = (byte)(int.Parse(Convert.ToString(MotorCommand[f])));
            }

            // Motor control Terminator
            Command[16] = (byte)(0); //  Byte 10: 0x00 (terminator)

            // Create Message Header -- Declare a 2 bytes vector to store the message length header
            Byte[] MessageLength = { 0x00, 0x00 };

            //set the LSB to the length of the message
            MessageLength[0] = (byte)Command.Length;

            //send the 2 bytes header
            BluetoothConnection.Write(MessageLength, 0, MessageLength.Length);

            // send the message itself
            BluetoothConnection.Write(Command, 0, Command.Length);

            return (Command);
        }


I've been following this tutorial http://www.codeproject.com/KB/cs/nxtBluetooth.aspx?display=Print on Bluetooth communication with the NXT so I believe I'm using the correct commands to write to a mailbox.

I've been following this guide : http://www.mindstorms.rwth-aachen.de/trac/wiki/MotorControl to find the correct commands to send to MotorControl.

I've been using the Command : "10990010002" to attempt to run motor B, although I've tried a number of combinations to no avail. I'm going to try again tomorrow night when I have some time, but if anyone can see anything obviously foolish in my method please let me know !.

All the best,
ben
User avatar
mrbencowell
 
Posts: 17
Joined: Sat May 14, 2011 4:29 pm



PreviousNext

Return to AForge.NET Framework