locked
Turn and then Move RRS feed

  • Question

  •  

    Hello everyone!!

     

    I just need to ask,

     

    can the robot turn a little and then, immediately, move forward at some speed or translate a step?

     

    Code Snippet

     

    if (Math.Abs(final_angle) > 5) //an angle threshold to turn sometimes , and else move

    Turn(final_angle);

    else

    MoveForward((int)final_dist);

     

     

    In this code, if there was no "if" statement, the robot would move without turning most of the time.

    This code is in the laser handler somewhere, if this makes any difference.

    ( I think, for that matter,that maybe it's executed too frequently - as lasernotify happens- and doesn't have the chance to turn AND move ? )

     

    My goal is to make it piecewise linear as Trevor Taylor called it: Turn maybe a tiny bit (not the whole angle) and then Move a tiny bit, both so frequently , that it looks like a smooth motion.

     

    Any help appreciated.

     

    Note: I didn't post this in Simulation subforum because of the MS terminolgy - from what I gather, Simulation in MSDN only refers to building worlds and not moving anything. Anyway.

    Sunday, May 4, 2008 8:13 PM

Answers

  • It is not completly clear what you are asking, but it sounds like you want a way to do synchronous tasks.  For that, you use an iterator.  This is discussed in the tutorials, but i forget which one.  Remember that when you post a message like DriveDistance or RotateDegrees, it is just a message post and is not blocking.  This following code is a small example of a 'drive square' algorithm using an iterator.

     

    Code Snippet

    protected override void Start()

    {

        base.Start();

        SpawnIterator(DrawSquare);

    }

     

    IEnumerator<ITask> DrawSquare()

    {

        double ONE_METER = 1.0;

        double FULL_POWER = 1.0;

        double LESS_POWER = 0.6;

        double QUARTER_TURN = 90.0;

     

        yield return Arbiter.Receive(false, TimeoutPort(2000), delegate(DateTime t) { });

     

        for (int i = 0; i < 4; i++)

        {

            yield return Arbiter.Choice(

                _drivePort.DriveDistance(new drive.DriveDistanceRequest(ONE_METER, FULL_POWER)),

                delegate(DefaultUpdateResponseType rsp)

                { },

                delegate(Fault fault)

                { }

             );

     

            yield return Arbiter.Choice(

                _drivePort.RotateDegrees(new drive.RotateDegreesRequest(QUARTER_TURN, LESS_POWER)),

                delegate(DefaultUpdateResponseType rsp)

                { },

                delegate(Fault fault)

                { }

             );

        }

        yield break;

    }

     

     

     

    This code requires that DriveDistance and RotateDegrees send a response *after* they are finished moving.  If not, this code will just make the robot twitch, then only rotate 90 degrees since that is the last command.  If your drive service does not send a response after it is done moving, then you will have to use timers or polling.

    An advanced and very nice pattern is to do a choice on success, fault, and a timeout port.  This thread has info on how to do that: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2992298

    Sunday, May 11, 2008 5:18 PM