airblader wrote:
Yes, that is what I want to do. And well, precision is never a bad thing to have, is it?
No, of course not. I know it sounds silly I asked that. In this case, the problem is that you have to take care of "precise braking" yourself if you don't want to use RotateMotor. Now we can try to figure out if it's worth it for you to do something else / more advanced.
airblader wrote:
...
However, this does cost tons of time and since it's a competition it'll be about time. So a much more effective way would be to detect the obstacle and without stopping just turning a smooth curve to the left, drive by it and after the obstacle turn back in again with a smooth curve and without stopping.
This is going to be really really tough. I think I wouldn't recommend doing it. In my experience, the curve driving works empirical: You set some value, you see if it's the curve you want, and you keep that setting. Changing this on the fly or trying to understand how this TurnRatio exactly works will be difficult. We tried that, and we couldn't really find a formula or understand how this works. LEGO say they interpolate from 0 (both wheels spin equally fast), to 50 (one wheel spins, other is stopped), to 100 (both wheels spin in opposite directions). 0 works (driving straight line), but 50 doesn't all the time, and the whole thing doesn't seem linear.
The really cool and advanced thing which might be VERY promising (and since your working with control theory anyway): Code your own (PID) controller, but power the wheels independently on your own (without speed regulation, without sync). This way you can make your own sync, and your own turn ratio. Unfortunately, that'll be quite some development time.
airblader wrote:
However, this might take a while since having a working version is more important at the moment. Improving details like this shouldn't be the task with the highest priority at the moment, because a smooth curve doesn't help if we don't even finish the lap.
But I might just try some things in my spare time.
Sure, as always
airblader wrote:
For that matter I am going to try updating the flags by using the SetOutput command.
airblader wrote:
Does it mean RotateMotorEx internally calls OnFwdSync which itself calls SetOutput? Would you recommend fully working with SetOutput myself to get better results (meaning: are the built-in commands that crappy?)?
Ok, it basically works like this:
The firmware checks the output module map every tick (= 1ms). This map is basically just some variables / registers. Depending on what params are set, the motors are operated (and regulated). So you can set a new power value, and then have to set the "UPDATE_POWER" flag. 1 ms the firmware realizes this, and acts accordingly. So, at the lowest level, it's always about these motor registers. And they are set via SetOutput. Be careful: Don't overwrite your own flags. Sometimes a Wait(1) is needed to "commit" a setting.
OnFwd* commands are macros / convenient calls to certain parameter combos (which are set, as mentioned, with SetOutput).
Now, RotateMotor is uses the same motor fields. If RotateMotor uses OnFwd or SetOutput, I don't know, I'd guess SetOutput. But in the end it's all the same. RotateMotor is blocking as you've noticed. It's a macro / function, which starts a motor and then monitors it inside a loop (so by stalling a motor, you can keep your program (or at least your task) inside this loop).
Here you can see a log of how RotateMotor works:
http://www.mindstorms.rwth-aachen.de/tr ... tateEx.png
You can see the different runstates and regmodes. Note the oscillations: Once the TachoLimit is reached, the brakes are enabled, leading to a very hard stop (not nice). Braking is just SetOutput with runstate RUNNING and regmode SPEED and power = 0.
This is btw. the same thing the NXT-G "MotorBlock" does:
http://www.mindstorms.rwth-aachen.de/tr ... _NoReg.png
Only the NXT-G "MoveBlock" uses the RAMPDOWN runstate:
http://www.mindstorms.rwth-aachen.de/tr ... eBlock.png . Similar pictures were posted by gloomyandy a couple of days ago in a thread "Motor Control" I think. But sorry, I disgress, that's not important right now.
As you said, you should do some more tests and focus on the basics. My overall experience was: "doing things on your own" helps, as in: "don't trust the firmware regulating your motors". On the other thing, that's a very complicated, big task.
airblader wrote:
Or do you want to drive an "8-shaped figure" on the floor? I've done that once. You can try to update certain motor values (like TurnRatio) during runtime using the SetOutput command, but it might get "buggy" then.
As described above, that basically is what I want to do, yes. It's not like there is much of a difference between 8-shaped figures and smooth curves in general. I might take a look at updating motor values using SetOutput. It seems like some work, but some work that might be worth the time. However, I'd appreciate if you could say anything about what kind of "buggy" you mean? What problems can it cause?
The "figure 8" I was driving on the floor was static. All I had to do was switch directions when one circle was done, to get the other circle. (so 8 = OO basically ^^). Dynamically adjusting TunRatio etc. "on the fly" is another thing.
With "buggy" I mean: Driving in sync means sending two SetOutput commands, one for each motor. You set certain flags, and then commit the settings. The motors start running. If you just set new values, the firmware won't accept it. You have to reset certain counters and turn off the motors in between (something like a "soft restart"), otherwise your robot will dance
. Honestly. The firmware's internal error corrections will "rewind" the difference in distance of the two wheels, it's all crazy. So you have to reset the BlockTachoCount. All manageable, not a problem. The thing is: During this short "dead spot" of the motors (couple of ms), they keep on spinning. You commit the new commands, and it's not a very nice smooth movement anymore. You can do it, but in my experience: Some strange effects, lots of experiments necessary, the occasional "duh?" moment, etc.
Anyway, I don't want to discourage you AT ALL. Please, try it. You have more information to start with now than I had years ago, that could make a difference. Maybe I simply "didn't get it" or something, or I wanted to try different things. I don't want to sound too negative. I'm just trying to tell you what's "most time consuming" from my point of view.
airblader wrote:
Another thing:
Today we built our robot using the design ideas we had. However, the robot is very asymmetrical (but that's needed for the task we have to achieve). The funny thing is: Using OnFwdSync (with OUT_REGMODE_SYNC) makes it drive a curve again (likely because of the asymmetry) .. instead of driving straight forward.
I don't get that. Yes, asymmetry might be a problem, but that's what SYNC is for. On the other hand, if you neither use SYNC nor SPEED, the motors run more stable (not regulated, but with a constant power).
Since both commands just use certain SetOutput parameters, they SHOULD be the same, yes. But you have to really find out what state your motors are in.
If you have access to MATLAB, try our toolbox. It comes with a tool called GUI_WatchMotorState. This will monitor your Output flags during runtime, even while an NXC program is running. You can watch what's happening in realtime. This looks like this:
http://www.mindstorms.rwth-aachen.de/tr ... rState.png
There might be similar tools in BricxCC. I don't have an NXT right now and can't test, but check the "Tools" menu in BricxCC, maybe this will help too.
Right now, looking at your results, it's impossible that both commands do the same, since you see different results...
airblader wrote:
Thanks again, I really appreciate your help.
cheers