Home→Forums→MonoBrick EV3 Firmware→Preparations for GyroBot
- This topic has 31 replies, 3 voices, and was last updated 10 years, 7 months ago by Anders Søborg.
-
AuthorPosts
-
January 6, 2014 at 21:46 #3774
Martin WagnerParticipantHi everybody,
I have built the GyroBoy mechanically
http://robotsquare.com/2013/10/01/education-ev3-45544-instruction/ (via Laurens’ pages)
and downloaded and adapted the mindstorm program from
http://forums.usfirst.org/showthread.php?20729-Gyro-Boy-Program (thanks Dean)
It runs okay and I want to rebuild a MonoBrick version (in my dreams I am using the tilt angles of my android-phone to control it 😉 ). It will need a tight control loop for the balancing and shall be as responsive as possible to user commands and for displaying information.Before starting, I read a lot about threads, tasks, … since I am new in this part of the programming world. I want to reuse as many of the standard .Net features and I am not fully familiar yet with the features of the monobrick dll. I hope to raise an interesting discussion with this suggestion:
One thread with high priority has a continuous loop which performs the measuring and controlling and then waits for an autoresetevent which is triggered by a timer. Thus, the thread creation overhead is only relevant in the beginning. Fortunately system.timers.timer has a better resolution on the brick (2-5ms) than on windows (ca. 16ms). All other activities are handled in one (ore more) standard thread(s) with normal priority with button events, message events, … This thread also holds display handling (e.g. variation in cycle times, remaining idle time, …).
Comments:
Modern (DotNet4-)features like thread pools and tasks do not allow to influence thread priorities, which seems a good way to guarantuee enough CPU time for the control loop. E.g. the control loop shall interrupt an ongoing display routine.
“Sleep” can not react to changes in CPU-consumption after start, so I’d rather go with “WaitOne” on the timer triggered autoresetevent.
I tried to find the best compromise between context switching context and programming complexity, also regarding intertask communication (thus processes seemed to be “too big bullets”).I did a first implementation as a windows console project, which I could debug more easily within VisualStudio. There the concept worked as expected.
Current questions:
Isolate timer in even higher priority thread to improve accuracy?
How to debug this on the brick? Xamarin seems to have a bug with mono on windows currently.
How to use brick sounds which could support “oral debugging”?
…
What do you think? Did I miss anything? Any experiences with it?Waiting for any comments,
MartinJanuary 6, 2014 at 22:03 #3778
Anders SøborgKeymasterHi
This is really amazing – I hope you succeed to help boost the popularity of MonoBrick firmware…
Isolate timer in even higher priority thread to improve accuracy?
I already think that your approach with the hight priority thread seems good enough (if I understand correctly)
How to debug this on the brick? Xamarin seems to have a bug with mono on windows currently.
Log values to an array and when done write these to a file to plot in matlab. This way you only spend time on “saving” values to the array. It would be nice to debug over a WiFi connection – but for a real-time system it does not make sense. So from your point of view it does not matter if debugging is working or not. Also make sure that when running tests use a release build to get the best performance.
How to use brick sounds which could support “oral debugging”?
Sound support will be available in the next release.
I hope this answers your questions.
Anders
January 7, 2014 at 15:46 #3796
Martin WagnerParticipantI just saw issue#13 in the GitHub and it still seems to be missing: Can I place a strong vote for implementing the educational gyro-sensor?
This might be a kind of blocking-stone for my GyroBoy 😉
Thanks a lot in advance,
MartinJanuary 7, 2014 at 19:22 #3800
Anders SøborgKeymasterWill also be added for the next release… I will add this tonight… so you can grab the code from Github.
Anders
January 8, 2014 at 13:53 #3805
Jacek SParticipantHi Martin,
I’m interested in writing GyroBoy program too. Now I’m only waiting for my wifi dongle.
I have read your post, and I think there are simplest approaches to do this program.
Maybe I’m wrong, but you are trying to think like in real-time os, but this is linux it is not real time.
You can’t specify timers and expect results in desired time. My approach is to think that is lego toy
not high precision robot. Program needs some simplifications, thread prioritization and other advanced thread managment functions are not needed.
Oryginal program is not ideal, I have found some bugs and glitches.I don’t analyze all the tricky gyro stuff from oryginal program yet, but i have some initial
plan for my program:
– tasks with infinite loops for sensor sampling. Idle time (sleep) will determine sample rate.
– main thread with task handling loop
– priority queue for message handling.I think I accomplish project in two weeks, then will share results/program with monobrick community.
PS
Sorry for my poor english.Jacek
- This reply was modified 10 years, 11 months ago by Jacek S.
January 8, 2014 at 14:17 #3807
Anders SøborgKeymasterI added support for the Gyro sensor last night. You can download it from the github repository. You will probably need to download the entire project and build your own DLL.
Anders
January 8, 2014 at 22:10 #3810
Martin WagnerParticipantHi Jacek,
great to have someone to share experiences. I know that it won’t be a real-time OS, but I am trying to find the DotNet components that make it as “real-timish” as possible. Maybe I described it too complicated, but the only difference between our ideas seems to be, that I want to use a timer-triggered WaitOne instead the Sleep to pause the measurement thread. The rest is planned to be similar. Based on our experiences, maybe we could suggest some easy-to-use-classes for the project afterwards.
See you,
MartinJanuary 8, 2014 at 22:22 #3812
Anders SøborgKeymasterHi
Please let all of us know how this ends
Anders
January 24, 2014 at 11:58 #3872
Jacek SParticipantHi,
I did some initial test of my gyro boy.
And I encountered some problems.
First and least important is gyro sensor only works in port1.
Second is that I don’t know how to use motor methods to simulate “unregulated motor” block.
SetPower do not start motor, and I was using sequence motor.On(0) and motor.SetPower(power).
I’m not sure is equivalent. After that the motor start rotating, but when i set it to off and quit program,
then start program again motors starting after new Motor(…) constructor,
before i set them to on. I don’t know how to avoid this.
The next thing is that the gyro sensor doesn’t have “rate and angle” mode
I have read that swithching to this mode is used to remove drift effect.
Last thing. Please confirm getTacho from motor is angle in degrees.Jacek
January 24, 2014 at 19:15 #3875
Anders SøborgKeymasterHi Jacek
We really really appreciate all your hard work on getting your project up and running – it is a great thing that you report errors/bugs on github. I have been sick the last week so I haven’t been able to look at the issues – but I will look into it once I am well.
However I am not sure I understand what you mean by
Second is that I don’t know how to use motor methods to simulate “unregulated motor” block.
Anders
January 26, 2014 at 20:29 #3877
Jacek SParticipantHi Anders,
I mean labview block. I’m trying to translate block sequence from original program to c# code.
I spend many hours during weekend but still with no success. Robot is far from balancing.
Still don’t know where is diffrence. Two points where I’m not sure is gyro sensor rate read and “unregulated motor”.
“Unregulated motor” in my program is sequence: motor.On() (if power < 0) motor.Reverse and motor.SetPower(power).
The oryginal program is very tricky and depends strongly on enviroment and even on battery level.Fragment of my program(balance method):
private void Balance() { var lastSumMotor = sumMotor; sumMotor = leftMotor.GetTachoCount() + rightMotor.GetTachoCount(); var diffMotor = (sumMotor - lastSumMotor); rateMotor = 0.75 * rateMotor + 0.25 * (diffMotor / avgLoopTimer); angleMotor = moveMotor * avgLoopTimer + angleMotor + diffMotor; var gyroRead = (double)gyro.Read(); rateGyro = gyroRead - offsetGyro; offsetGyro = 0.001 * gyroRead + 0.999 * offsetGyro; angleGyro = angleGyro + avgLoopTimer * rateGyro; motorPower = rateGyro * GYRO_RATE + angleGyro * GYRO_ANGLE + rateMotor * MOTOR_RATE + angleMotor * MOTOR_POS; if (motorPower < 0) { motorPower *= -1d; if (!leftMotor.Reverse) rightMotor.Reverse = leftMotor.Reverse = true; } else { if (leftMotor.Reverse) rightMotor.Reverse = leftMotor.Reverse = false; } if (motorPower > 100d) motorPower = 100d; leftMotor.SetPower((byte)motorPower); rightMotor.SetPower((byte)motorPower); }
Jacek
January 27, 2014 at 23:03 #3891
Anders SøborgKeymasterHi
Please don’t use setpower use on instead
Anders
January 27, 2014 at 23:28 #3893
Jacek SParticipantHi Anders,
In all code examples I found setpower equivalent is used(in lejos segway.java and hitec nxc example, and labview ev3 program) I dont know why.In lejos source code i found that power param for setpower is byte(in java is signed type) I changed this in monobrickfirmware to sbyte, now i dont need to change polarization(Reverse attr).
Now I’m analyzing lejos source code to find differences. And I think they are using some filters for gyro.
Maybe this is a problem.Jacek
January 28, 2014 at 15:35 #3895
Anders SøborgKeymasterHi Jacek
Keep up the good work
Anders
January 31, 2014 at 08:34 #3915
Anders SøborgKeymasterHi
JacekThe sensor problem has been fixed see this post. Download the lastest DLL to get the fix
Anders
-
AuthorPosts
You must be logged in to reply to this topic.
Follow