Jacek S

Forum Replies Created

Viewing 8 posts - 31 through 38 (of 38 total)
  • Author
    Posts
  • in reply to: Preparations for GyroBot #3918
    Author Image
    Jacek S
    Participant

    Hi Anders,
    Thanks, I grabbed this fixed line of code yesterday.
    I have no progress in my GyroBoy implementation.
    I can’t get it working and I have no idea what may be wrong.
    I paste my code, maybe someone can look at the code or try run.

    I used decimals(to be extremely close to original labview program), but initially there were doubles

    Program.cs

    
    using System.Threading;
    using System.Threading.Tasks;
    using MonoBrickFirmware.UserInput;
    
    namespace GyroBoy
    {
        internal class Program
        {
            private static void Main(string[] args)
            {
                ManualResetEvent terminateProgram = new ManualResetEvent(false);
                GyroBoy gyroBoy = new GyroBoy();
                ButtonEvents buts = new ButtonEvents();
    
                buts.EscapePressed += () =>
                {
                    terminateProgram.Set();
                };
    
                Task.Factory.StartNew(() => gyroBoy.Run(terminateProgram));
    
                terminateProgram.WaitOne();
                gyroBoy.Stop();
            }
        }
    }
    

    GyroBoy.cs

    
    using System;
    using System.Collections.Generic;
    using System.Threading;
    using MonoBrickFirmware.Display;
    using MonoBrickFirmware.Movement;
    using MonoBrickFirmware.Sensors;
    
    namespace GyroBoy
    {
        public class GyroBoy
        {
            private GyroSensor gyro = null;
            private Motor leftMotor = null;
            private Motor rightMotor = null;
            private Lcd lcd = new Lcd();
    
            private const decimal MOTOR_RATE = 0.08m;
            private const decimal MOTOR_POS = 0.08m;
    
            private const decimal GYRO_RATE = 0.7m;
            private const decimal GYRO_ANGLE = 12m;
    
            private decimal avgLoopTimer = 0.01m;
    
            private decimal gyroRate = 0;
            private decimal gyroAngle = 0;
            private decimal gyroOffset = 0;
    
            private decimal gyroRawRead = 0;
            
            private decimal motorPos = 0;
            private decimal motorAngle = 0;
            private decimal motorRate = 0;
            private decimal motorPower = 0;
    
            private decimal motorDelta3 = 0;
            private decimal motorDelta2 = 0;
            private decimal motorDelta1 = 0;
    
            private void Init()
            {
                gyro = new GyroSensor(SensorPort.In1, GyroMode.AngularVelocity);
                LcdConsole.WriteLine("GYRO init... done");
    
                leftMotor = new Motor(MotorPort.OutD); leftMotor.Off();
                rightMotor = new Motor(MotorPort.OutA); rightMotor.Off();
                LcdConsole.WriteLine("MOTORS init... done");
            }
    
            private void Reset()
            {
                gyro.Reset();
                LcdConsole.WriteLine("GYRO reset... done");
                int gyroRate = 0;
                int gyroReads = 0;
                //reset gyro to eliminate drift effect.
                while (true)
                {
                    Thread.Sleep(10);
                    gyroRate += gyro.Read();
                    if (++gyroReads == 200)
                    {
                        if (gyroRate > 0)
                        {
                            gyro.Reset();
                            LcdConsole.WriteLine("GYRO drift reset... done");
                        }
                        else break;
                        gyroRate = 0;
                        gyroReads = 0;
                    }
                }
    
                //in some examples i found initial offset calculation, but i dont think this is needed
                //CalcGyroOffset();
    
                leftMotor.On(0);
                rightMotor.On(0);
    
                leftMotor.ResetTacho();
                rightMotor.ResetTacho();
                LcdConsole.WriteLine("MOTORS reset... done");
            }
    
            public void Stop()
            {
                if (leftMotor != null && rightMotor != null)
                {
                    leftMotor.SetPower(0);
                    rightMotor.SetPower(0);
    
                    leftMotor.Off();
                    rightMotor.Off();
                }
            }
    
            public void Run(ManualResetEvent resetEvent)
            {
                LcdConsole.WriteLine("Start GyroBoy");
                Init();
                Reset();
                Thread.Sleep(1500);
                LcdConsole.WriteLine("Start balancing...");
    
                var fallDownCntr = 0;
    
                lcd.Clear();
    
                while (true)
                {
                    var startTime = DateTime.Now;
    
                    Balance();
                    Thread.Sleep(8);
    
                    PrintDebug();
    
                    if (Math.Abs(motorPower) > 99m) fallDownCntr++;
                    else fallDownCntr = 0;
                    if (fallDownCntr >= 50)
                    {
                        LcdConsole.WriteLine("Falll down...");
                        resetEvent.Set();
                        break;
                    }
    
                    avgLoopTimer = 0.7m * avgLoopTimer + 0.3m * (decimal)(DateTime.Now - startTime).TotalSeconds;
                }
            }
    
            private void PrintDebug()
            {
                lcd.Clear();
                lcd.WriteText(Font.MediumFont, new Point(5, 15), "GYRO ANGLE: " + gyroAngle.ToString("0.0000"), true);
                lcd.WriteText(Font.MediumFont, new Point(5, 35), "GYRO RATE: " + gyroRate.ToString("0.0000"), true);
                lcd.WriteText(Font.MediumFont, new Point(5, 55), "LOOP TIME: " + avgLoopTimer.ToString("0.0000"), true);
                lcd.Update();
            }
    
            private void Balance()
            {
                gyroRawRead = (decimal)gyro.Read();
    
                gyroRate = gyroRawRead - gyroOffset;
                gyroOffset = 0.001m * gyroRawRead + (1 - 0.001m) * gyroOffset;
                gyroAngle += avgLoopTimer * gyroRate;
    
                var motorLastPos = motorPos;
                motorPos = leftMotor.GetTachoCount() + rightMotor.GetTachoCount();
    
                var motorDelta = motorPos - motorLastPos;
                motorRate = (motorDelta + motorDelta1 + motorDelta2 + motorDelta3) / (4 * avgLoopTimer);
                //second option for rate calculation I dont noticed any differences
                //rateMotor = (0.75m * rateMotor) + (0.25m * (deltaMotor / avgLoopTimer));
                motorAngle += motorDelta;
    
                motorDelta3 = motorDelta2; motorDelta2 = motorDelta1; motorDelta1 = motorDelta;
    
                motorPower = gyroRate * GYRO_RATE
                    + gyroAngle * GYRO_ANGLE
                    + motorRate * MOTOR_RATE
                    + motorAngle * MOTOR_POS;
    
                if (motorPower > 100m) motorPower = 100m;
                if (motorPower < -100m) motorPower = -100m;
    
                // !!! this is modified version of setPower that accepts sbyte. You need to use Reverse property and Abs(motorPower)
                leftMotor.SetPower((sbyte)(motorPower));
                rightMotor.SetPower((sbyte)(motorPower));
            }
        }
    }
    
    • This reply was modified 10 years, 10 months ago by Author ImageJacek S.
    • This reply was modified 10 years, 10 months ago by Author ImageJacek S.
    in reply to: Preparations for GyroBot #3893
    Author Image
    Jacek S
    Participant

    Hi 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

    in reply to: Motor Control not behaving #3882
    Author Image
    Jacek S
    Participant

    You don’t need to decompile. You can grab sources from github. There is a visual studio solution with several examples.

    in reply to: Preparations for GyroBot #3877
    Author Image
    Jacek S
    Participant

    Hi 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

    in reply to: Preparations for GyroBot #3872
    Author Image
    Jacek S
    Participant

    Hi,
    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

    in reply to: Controlling EV3 by WiFi from a PC application? #3844
    Author Image
    Jacek S
    Participant

    Hi Marta,
    There is a guide with c# sample http://www.monobrick.dk/guides/how-to-establish-a-wifi-connection-with-the-ev3-brick/

    BR
    Jacek

    • This reply was modified 10 years, 11 months ago by Author ImageJacek S.
    in reply to: Preparations for GyroBot #3805
    Author Image
    Jacek S
    Participant

    Hi 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 Author ImageJacek S.
    in reply to: Monobrick on Android #3671
    Author Image
    Jacek S
    Participant

    Hi,
    Do I need to buy license for xamarin studio? I think xamarin free starter limitation to 64kb IL size is not sufficient (monobrick library have more than 100kb). Are there any alternatives to use monobrick library for android without buying xamarin license?

    Jacek

Viewing 8 posts - 31 through 38 (of 38 total)
Posted in

Make a donation