Click here to Skip to main content
Click here to Skip to main content

Amble Avalona

, 2 Feb 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
A WPF animaloid
Screenshot1.png

Introduction

Following in the footsteps of my previous article, it would have been improper not to take on the task of xamlizing a four-legged creature. In short, I decided to work on a WPF project that replicated a walking four-legged animal.

Requirements

To run the project provided from the download link above, you require either of the following:

  • Visual Studio 2010
  • Expression Blend

If you're using VS 2008, you can download the source files from here.

NB: Ensure that you open the solution using Visual Basic Express if you're using the Express edition of Visual Studio.

Avalona

How It Works

To make Avalona walk, just press the right arrow key. Avalona will amble on a treadmill, this time the action taking place inside the M Labs Animaloid Research Centre.

Ambling

The amble is an easy gait (way of walking), most common in horses, where at least one leg/hoof touches the ground during the phases of motion. There is no suspension phase, i.e., a phase where all the legs are entirely off the ground. This was the primary reason I decided to replicate the amble. During this gait, a maximum of two legs can/will support the weight of the animal. The following sequence of photographs show the phases followed during this gait.

Screenshot2.png

A short and detailed explanation of the phases of movement shown above can be found here.

There are 11 phases in the photos above, which are a bit of a handful, so I narrowed it down to 5 phases which would offer me equally suitable results.

Screenshot3.png

From the initial sequence of photos, I chose the 4th, 5th, 6th, 7th, and 9th phases.

If you want to, you can watch a video of a horse ambling here.

Design and Layout

I designed Avalona, Treadmill, and the Lab_Screen in Expression Design. The rest of the elements were added in Expression Blend. The following image shows the layout of the elements of concern and their names (the same applies to the left legs),

Screenshot4.png

NB: The center of the joints of each section of Avalona act as center points.

Leg Movement

The standing posture of Avalona and that of a horse are slightly different. Avalona's limbs are more slightly angled especially those of the hind legs.

Screenshot5.png

This presented a bit of a challenge in my attempt at replicating the amble. Because of this difference, Avalona's gait is a slightly modified version of a horse's amble.

In order to get a better picture of how to proceed, I drew stick figures of the ambling horse and then drew stick figures of a ambling Avalona, taking into account their differences in standing posture. I then adjusted the elements of concern in Expression Blend, at positions similar to those of the stick figures, noting down the angles which I felt would offer suitable results. These were the results:

Screenshot6.png

Screenshot7.png

The Code

The calculations that provide us with the necessary wizardry are found in the module MovementCalculations:

Module MovementCalculations
    Public RhtHindLeg_A_Angles() As Integer = {4, 8, 14, -4, -14}
    Public RhtHindLeg_B_Angles() As Integer = {4, 8, 14, 20, -10}
    Public RhtHindLeg_C_Angles() As Integer = {-4, -10, -31, -42, 4}
    Public RhtHindLegPawAngles() As Integer = {-4, 2, 3, 22, 20}

    Public LeftHindLeg_A_Angles() As Integer = {-14, -12, -9, -5, 4}
    Public LeftHindLeg_B_Angles() As Integer = {-10, -14, -20, -10, 4}
    Public LeftHindLeg_C_Angles() As Integer = {4, 9, 21, 12, -4}
    Public LeftHindLegPawAngles() As Integer = {20, 22, 8, 3, -4}

    Public RhtForeLeg_A_Angles() As Integer = {3, 4, 5, 9, 6}
    Public RhtForeLeg_B_Angles() As Integer = {2, 9, 13, 15, -41}
    Public RhtForeLeg_C_Angles() As Integer = {0, 0, 0, 18, 68}
    Public RhtForeLegPawAngles() As Integer = {-5, -13, -18, -25, -31}

    Public LeftForeLeg_A_Angles() As Integer = {6, 9, 1, -8, 3}
    Public LeftForeLeg_B_Angles() As Integer = {-41, -60, -46, -8, 2}
    Public LeftForeLeg_C_Angles() As Integer = {68, 66, 55, 0, 0}
    Public LeftForeLegPawAngles() As Integer = {-31, -16, -8, 29, -5}

    ' Get to Phase 1
    Public LeftHindLeg_A_Shift1 As Double = _
    Math.Abs(LeftHindLeg_A_Angles(0) / RhtHindLeg_A_Angles(0))
    Public LeftHindLeg_B_Shift1 As Double = _
    Math.Abs(LeftHindLeg_B_Angles(0) / RhtHindLeg_A_Angles(0))
    Public LeftHindLeg_C_Shift1 As Double = _
    (LeftHindLeg_C_Angles(0) / RhtHindLeg_A_Angles(0))
    Public LeftHindLegPawShift1 As Double = _
    (LeftHindLegPawAngles(0) / RhtHindLeg_A_Angles(0))

    Public RhtForeLeg_A_Shift1 As Double = _
    (RhtForeLeg_A_Angles(0) / RhtHindLeg_A_Angles(0))
    Public RhtForeLeg_B_Shift1 As Double = _
    (RhtForeLeg_B_Angles(0) / RhtHindLeg_A_Angles(0))
    Public RhtForeLegPawShift1 As Double = _
    Math.Abs(RhtForeLegPawAngles(0) / RhtHindLeg_A_Angles(0))

    Public LeftForeLeg_A_Shift1 As Double = _
    (LeftForeLeg_A_Angles(0) / RhtHindLeg_A_Angles(0))
    Public LeftForeLeg_B_Shift1 As Double = _
    Math.Abs(LeftForeLeg_B_Angles(0) / RhtHindLeg_A_Angles(0))
    Public LeftForeLeg_C_Shift1 As Double = _
    (LeftForeLeg_C_Angles(0) / RhtHindLeg_A_Angles(0))
    Public LeftForeLegPawShift1 As Double = _
    Math.Abs(LeftForeLegPawAngles(0) / RhtHindLeg_A_Angles(0))

    ' Phase 2s
    Public Phase2Shift As Double = _
    (RhtHindLeg_A_Angles(1) - RhtHindLeg_A_Angles(0))

    Public RhtHindLeg_B_Shift2 As Double = _
    (RhtHindLeg_B_Angles(1) - RhtHindLeg_B_Angles(0)) / Phase2Shift
    Public RhtHindLeg_C_Shift2 As Double = _
    Math.Abs(RhtHindLeg_C_Angles(1) - RhtHindLeg_C_Angles(0)) / Phase2Shift
    Public RhtHindLegPawShift2 As Double = _
    (RhtHindLegPawAngles(1) - RhtHindLegPawAngles(0)) / Phase2Shift

    Public LeftHindLeg_A_Shift2 As Double = _
    (LeftHindLeg_A_Angles(1) - LeftHindLeg_A_Angles(0)) / Phase2Shift
    Public LeftHindLeg_B_Shift2 As Double = _
    Math.Abs(LeftHindLeg_B_Angles(1) - LeftHindLeg_B_Angles(0)) / Phase2Shift
    Public LeftHindLeg_C_Shift2 As Double = _
    (LeftHindLeg_C_Angles(1) - LeftHindLeg_C_Angles(0)) / Phase2Shift
    Public LeftHindLegPawShift2 As Double = _
    (LeftHindLegPawAngles(1) - LeftHindLegPawAngles(0)) / Phase2Shift

    Public RhtForeLeg_A_Shift2 As Double = _
    (RhtForeLeg_A_Angles(1) - RhtForeLeg_A_Angles(0)) / Phase2Shift
    Public RhtForeLeg_B_Shift2 As Double = _
    (RhtForeLeg_B_Angles(1) - RhtForeLeg_B_Angles(0)) / Phase2Shift
    Public RhtForeLegPawShift2 As Double = _
    Math.Abs(RhtForeLegPawAngles(1) - RhtForeLegPawAngles(0)) / Phase2Shift

    Public LeftForeLeg_A_Shift2 As Double = _
    (LeftForeLeg_A_Angles(1) - LeftForeLeg_A_Angles(0)) / Phase2Shift
    Public LeftForeLeg_B_Shift2 As Double = _
    Math.Abs(LeftForeLeg_B_Angles(1) - LeftForeLeg_B_Angles(0)) / Phase2Shift
    Public LeftForeLeg_C_Shift2 As Double = _
    Math.Abs(LeftForeLeg_C_Angles(1) - LeftForeLeg_C_Angles(0)) / Phase2Shift
    Public LeftForeLegPawShift2 As Double = _
    (LeftForeLegPawAngles(1) - LeftForeLegPawAngles(0)) / Phase2Shift

    ' Phase 3s
    Public Phase3Shift As Double = _
    (RhtHindLeg_A_Angles(2) - RhtHindLeg_A_Angles(1))

    Public RhtHindLeg_B_Shift3 As Double = _
    (RhtHindLeg_B_Angles(2) - RhtHindLeg_B_Angles(1)) / Phase3Shift
    Public RhtHindLeg_C_Shift3 As Double = _
    Math.Abs(RhtHindLeg_C_Angles(2) - RhtHindLeg_C_Angles(1)) / Phase3Shift
    Public RhtHindLegPawShift3 As Double = _
    (RhtHindLegPawAngles(2) - RhtHindLegPawAngles(1)) / Phase3Shift

    Public LeftHindLeg_A_Shift3 As Double = _
    (LeftHindLeg_A_Angles(2) - LeftHindLeg_A_Angles(1)) / Phase3Shift
    Public LeftHindLeg_B_Shift3 As Double = _
    Math.Abs(LeftHindLeg_B_Angles(2) - LeftHindLeg_B_Angles(1)) / Phase3Shift
    Public LeftHindLeg_C_Shift3 As Double = _
    (LeftHindLeg_C_Angles(2) - LeftHindLeg_C_Angles(1)) / Phase3Shift
    Public LeftHindLegPawShift3 As Double = _
    Math.Abs(LeftHindLegPawAngles(2) - LeftHindLegPawAngles(1)) / Phase3Shift

    Public RhtForeLeg_A_Shift3 As Double = _
    (RhtForeLeg_A_Angles(2) - RhtForeLeg_A_Angles(1)) / Phase3Shift
    Public RhtForeLeg_B_Shift3 As Double = _
    (RhtForeLeg_B_Angles(2) - RhtForeLeg_B_Angles(1)) / Phase3Shift
    Public RhtForeLegPawShift3 As Double = _
    Math.Abs(RhtForeLegPawAngles(2) - RhtForeLegPawAngles(1)) / Phase3Shift

    Public LeftForeLeg_A_Shift3 As Double = _
    Math.Abs(LeftForeLeg_A_Angles(2) - LeftForeLeg_A_Angles(1)) / Phase3Shift
    Public LeftForeLeg_B_Shift3 As Double = _
    (LeftForeLeg_B_Angles(2) - LeftForeLeg_B_Angles(1)) / Phase3Shift
    Public LeftForeLeg_C_Shift3 As Double = _
    Math.Abs(LeftForeLeg_C_Angles(2) - LeftForeLeg_C_Angles(1)) / Phase3Shift
    Public LeftForeLegPawShift3 As Double = _
    (LeftForeLegPawAngles(2) - LeftForeLegPawAngles(1)) / Phase3Shift

    ' Phase 4s
    Public Phase4Shift As Double = _
    Math.Abs(RhtHindLeg_A_Angles(3) - RhtHindLeg_A_Angles(2))

    Public RhtHindLeg_B_Shift4 As Double = _
    (RhtHindLeg_B_Angles(3) - RhtHindLeg_B_Angles(2)) / Phase4Shift
    Public RhtHindLeg_C_Shift4 As Double = _
    Math.Abs(RhtHindLeg_C_Angles(3) - RhtHindLeg_C_Angles(2)) / Phase4Shift
    Public RhtHindLegPawShift4 As Double = _
    (RhtHindLegPawAngles(3) - RhtHindLegPawAngles(2)) / Phase4Shift

    Public LeftHindLeg_A_Shift4 As Double = _
    (LeftHindLeg_A_Angles(3) - LeftHindLeg_A_Angles(2)) / Phase4Shift
    Public LeftHindLeg_B_Shift4 As Double = _
    (LeftHindLeg_B_Angles(3) - LeftHindLeg_B_Angles(2)) / Phase4Shift
    Public LeftHindLeg_C_Shift4 As Double = _
    Math.Abs(LeftHindLeg_C_Angles(3) - LeftHindLeg_C_Angles(2)) / Phase4Shift
    Public LeftHindLegPawShift4 As Double = _
    Math.Abs(LeftHindLegPawAngles(3) - LeftHindLegPawAngles(2)) / Phase4Shift

    Public RhtForeLeg_A_Shift4 As Double = _
    (RhtForeLeg_A_Angles(3) - RhtForeLeg_A_Angles(2)) / Phase4Shift
    Public RhtForeLeg_B_Shift4 As Double = _
    (RhtForeLeg_B_Angles(3) - RhtForeLeg_B_Angles(2)) / Phase4Shift
    Public RhtForeLeg_C_Shift4 As Double = _
    (RhtForeLeg_C_Angles(3)) / Phase4Shift
    Public RhtForeLegPawShift4 As Double = _
    Math.Abs(RhtForeLegPawAngles(3) - RhtForeLegPawAngles(2)) / Phase4Shift

    Public LeftForeLeg_A_Shift4 As Double = _
    Math.Abs(LeftForeLeg_A_Angles(3) - LeftForeLeg_A_Angles(2)) / Phase4Shift
    Public LeftForeLeg_B_Shift4 As Double = _
    (LeftForeLeg_B_Angles(3) - LeftForeLeg_B_Angles(2)) / Phase4Shift
    Public LeftForeLeg_C_Shift4 As Double = _
    CDbl((LeftForeLeg_C_Angles(2)) / Phase4Shift)
    Public LeftForeLegPawShift4 As Double = _
    (LeftForeLegPawAngles(3) - LeftForeLegPawAngles(2)) / Phase4Shift

    ' Phase 5s
    Public Phase5Shift As Double = _
    Math.Abs(RhtHindLeg_A_Angles(4) - RhtHindLeg_A_Angles(3))

    Public RhtHindLeg_B_Shift5 As Double = _
    Math.Abs(RhtHindLeg_B_Angles(4) - RhtHindLeg_B_Angles(3)) / Phase5Shift
    Public RhtHindLeg_C_Shift5 As Double = _
    (RhtHindLeg_C_Angles(4) - RhtHindLeg_C_Angles(3)) / Phase5Shift
    Public RhtHindLegPawShift5 As Double = _
    Math.Abs(RhtHindLegPawAngles(4) - RhtHindLegPawAngles(3)) / Phase5Shift

    Public LeftHindLeg_A_Shift5 As Double = _
    (LeftHindLeg_A_Angles(4) - LeftHindLeg_A_Angles(3)) / Phase5Shift
    Public LeftHindLeg_B_Shift5 As Double = _
    (LeftHindLeg_B_Angles(4) - LeftHindLeg_B_Angles(3)) / Phase5Shift
    Public LeftHindLeg_C_Shift5 As Double = _
    Math.Abs(LeftHindLeg_C_Angles(4) - LeftHindLeg_C_Angles(3)) / Phase5Shift
    Public LeftHindLegPawShift5 As Double = _
    Math.Abs(LeftHindLegPawAngles(4) - LeftHindLegPawAngles(3)) / Phase5Shift

    Public RhtForeLeg_A_Shift5 As Double = _
    Math.Abs(RhtForeLeg_A_Angles(4) - RhtForeLeg_A_Angles(3)) / Phase5Shift
    Public RhtForeLeg_B_Shift5 As Double = _
    Math.Abs(RhtForeLeg_B_Angles(4) - RhtForeLeg_B_Angles(3)) / Phase5Shift
    Public RhtForeLeg_C_Shift5 As Double = _
    (RhtForeLeg_C_Angles(4) - RhtForeLeg_C_Angles(3)) / Phase5Shift
    Public RhtForeLegPawShift5 As Double = _
    (RhtForeLegPawAngles(4) - RhtForeLegPawAngles(3)) / Phase5Shift

    Public LeftForeLeg_A_Shift5 As Double = _
    (LeftForeLeg_A_Angles(4) - LeftForeLeg_A_Angles(3)) / Phase5Shift
    Public LeftForeLeg_B_Shift5 As Double = _
    (LeftForeLeg_B_Angles(4) - LeftForeLeg_B_Angles(3)) / Phase5Shift
    Public LeftForeLegPawShift5 As Double = _
    Math.Abs(LeftForeLegPawAngles(4) - LeftForeLegPawAngles(3)) / Phase5Shift
End Module

We check which key has been pressed in the MainWindow KeyDown event handler:

Private Sub MainWindow_KeyDown(ByVal sender As Object, _
            ByVal e As System.Windows.Input.KeyEventArgs) Handles Me.KeyDown
    If e.Key = Key.Right Then
        WalkForward()
    End If
End Sub

The WalkForward method does as its name suggests:

    Private Sub WalkForward()
        If FocusOnRightHind = True Then
            If MoveRhtLegBackwards = True Then
                RightHindBack()
            Else
                RightHindForward()
            End If
        Else
            If MoveLeftLegBackwards = True Then
                LeftHindBack()
            Else
                LeftHindForward()
            End If
        End If

        TreadmillRedTr.Angle -= 5

        RightHindLeg_A.RenderTransform = RhtHindLeg_A_Tr
        RightHindLeg_B.RenderTransform = RhtHindLeg_B_Tr
        RightHindLeg_C.RenderTransform = RhtHindLeg_C_Tr
        RightHindLegPaw.RenderTransform = RhtHindPawTr

        LeftHindLeg_A.RenderTransform = LeftHindLeg_A_Tr
        LeftHindLeg_B.RenderTransform = LeftHindLeg_B_Tr
        LeftHindLeg_C.RenderTransform = LeftHindLeg_C_Tr
        LeftHindLegPaw.RenderTransform = LeftHindPawTr

        RightForeLeg_A.RenderTransform = RhtForeLeg_A_Tr
        RightForeLeg_B.RenderTransform = RhtForeLeg_B_Tr
        RightForeLeg_C.RenderTransform = RhtForeLeg_C_Tr
        RightForeLegPaw.RenderTransform = RhtForePawTr

        LeftForeLeg_A.RenderTransform = LeftForeLeg_A_Tr
        LeftForeLeg_B.RenderTransform = LeftForeLeg_B_Tr
        LeftForeLeg_C.RenderTransform = LeftForeLeg_C_Tr
        LeftForeLegPaw.RenderTransform = LeftForePawTr

        TreadmillRedGroup.RenderTransform = TreadmillRedTr
    End Sub

In the method above, method calls are made based on the values of various variables, of Boolean type. The RightHindBack method rotates the various sections of Avalona's legs from the standing position to Phase 3. It later alternates to rotating elements from Phase 1 to Phase 3.

    Private Sub RightHindBack()
        ' Get to Phase 1. This executes only once.
        If RhtHindLeg_A_Tr.Angle < 4 Then
            RhtHindLeg_A_Tr.Angle += 1 * speed
            RhtHindLeg_B_Tr.Angle += 1 * speed
            RhtHindLeg_C_Tr.Angle -= 1 * speed
            RhtHindPawTr.Angle -= 1 * speed

            LeftHindLeg_A_Tr.Angle -= LeftHindLeg_A_Shift1 * speed
            LeftHindLeg_B_Tr.Angle -= LeftHindLeg_B_Shift1 * speed
            LeftHindLeg_C_Tr.Angle += LeftHindLeg_C_Shift1 * speed
            LeftHindPawTr.Angle += LeftHindLegPawShift1 * speed

            RhtForeLeg_A_Tr.Angle += RhtForeLeg_A_Shift1 * speed
            RhtForeLeg_B_Tr.Angle += RhtForeLeg_B_Shift1 * speed
            RhtForePawTr.Angle -= RhtForeLegPawShift1 * speed

            LeftForeLeg_A_Tr.Angle += LeftForeLeg_A_Shift1 * speed
            LeftForeLeg_B_Tr.Angle -= LeftForeLeg_B_Shift1 * speed
            LeftForeLeg_C_Tr.Angle += LeftForeLeg_C_Shift1 * speed
            LeftForePawTr.Angle -= LeftForeLegPawShift1 * speed
        End If
        ' Get to Phase 2
        If RhtHindLeg_A_Tr.Angle >= 4 And RhtHindLeg_A_Tr.Angle < 8 Then
            RhtHindLeg_A_Tr.Angle += 1 * speed
            RhtHindLeg_B_Tr.Angle += RhtHindLeg_B_Shift2 * speed
            RhtHindLeg_C_Tr.Angle -= RhtHindLeg_C_Shift2 * speed
            RhtHindPawTr.Angle += RhtHindLegPawShift2 * speed

            LeftHindLeg_A_Tr.Angle += LeftHindLeg_A_Shift2 * speed
            LeftHindLeg_B_Tr.Angle -= LeftHindLeg_B_Shift2 * speed
            LeftHindLeg_C_Tr.Angle += LeftHindLeg_C_Shift2 * speed
            LeftHindPawTr.Angle += LeftHindLegPawShift2 * speed

            RhtForeLeg_A_Tr.Angle += RhtForeLeg_A_Shift2 * speed
            RhtForeLeg_B_Tr.Angle += RhtForeLeg_B_Shift2 * speed
            RhtForePawTr.Angle -= RhtForeLegPawShift2 * speed

            LeftForeLeg_A_Tr.Angle += LeftForeLeg_A_Shift2 * speed
            LeftForeLeg_B_Tr.Angle -= LeftForeLeg_B_Shift2 * speed
            LeftForeLeg_C_Tr.Angle -= LeftForeLeg_C_Shift2 * speed
            LeftForePawTr.Angle += LeftForeLegPawShift2 * speed
        End If
        ' Get to Phase 3
        If RhtHindLeg_A_Tr.Angle >= 8 And RhtHindLeg_A_Tr.Angle < 14 Then
            RhtHindLeg_A_Tr.Angle += 1 * speed
            RhtHindLeg_B_Tr.Angle += RhtHindLeg_B_Shift3 * speed
            RhtHindLeg_C_Tr.Angle -= RhtHindLeg_C_Shift3 * speed
            RhtHindPawTr.Angle += RhtHindLegPawShift3 * speed

            LeftHindLeg_A_Tr.Angle += LeftHindLeg_A_Shift3 * speed
            LeftHindLeg_B_Tr.Angle -= LeftHindLeg_B_Shift3 * speed
            LeftHindLeg_C_Tr.Angle += LeftHindLeg_C_Shift3 * speed
            LeftHindPawTr.Angle -= LeftHindLegPawShift3 * speed

            RhtForeLeg_A_Tr.Angle += RhtForeLeg_A_Shift3 * speed
            RhtForeLeg_B_Tr.Angle += RhtForeLeg_B_Shift3 * speed
            RhtForePawTr.Angle -= RhtForeLegPawShift3 * speed

            LeftForeLeg_A_Tr.Angle -= LeftForeLeg_A_Shift3 * speed
            LeftForeLeg_B_Tr.Angle += LeftForeLeg_B_Shift3 * speed
            LeftForeLeg_C_Tr.Angle -= LeftForeLeg_C_Shift3 * speed
            LeftForePawTr.Angle += LeftForeLegPawShift3 * speed
        End If

        If RhtHindLeg_A_Tr.Angle = 14 Then
            MoveRhtLegBackwards = False
        End If
    End Sub

The RightHindForward method rotates the various sections of Avalona's legs from Phase 3 to Phase 5.

    Private Sub RightHindForward()
        ' Get to Phase 4
        If RhtHindLeg_A_Tr.Angle <= 14 And RhtHindLeg_A_Tr.Angle > -4 Then
            RhtHindLeg_A_Tr.Angle -= 1 * speed
            RhtHindLeg_B_Tr.Angle += RhtHindLeg_B_Shift4 * speed
            RhtHindLeg_C_Tr.Angle -= RhtHindLeg_C_Shift4 * speed
            RhtHindPawTr.Angle += RhtHindLegPawShift4 * speed

            LeftHindLeg_A_Tr.Angle += LeftHindLeg_A_Shift4 * speed
            LeftHindLeg_B_Tr.Angle += LeftHindLeg_B_Shift4 * speed
            LeftHindLeg_C_Tr.Angle -= LeftHindLeg_C_Shift4 * speed
            LeftHindPawTr.Angle -= LeftHindLegPawShift4 * speed

            RhtForeLeg_A_Tr.Angle += RhtForeLeg_A_Shift4 * speed
            RhtForeLeg_C_Tr.Angle += RhtForeLeg_C_Shift4 * speed
            RhtForePawTr.Angle -= RhtForeLegPawShift4 * speed

            LeftForeLeg_A_Tr.Angle -= LeftForeLeg_A_Shift4 * speed
            LeftForeLeg_B_Tr.Angle += LeftForeLeg_B_Shift4 * speed
            LeftForeLeg_C_Tr.Angle -= LeftForeLeg_C_Shift4 * speed
            LeftForePawTr.Angle += LeftForeLegPawShift4 * speed

            ShiftAvalonaUp()
        End If
        If RhtHindLeg_A_Tr.Angle = -4 Then
            LeftForeLeg_C_Tr.Angle = 0
        End If
        ' Get to Phase 5
        If RhtHindLeg_A_Tr.Angle <= -4 And RhtHindLeg_A_Tr.Angle > -14 Then
            ' Multiply by 0.5 since Phase 8 in the original sequence  
            ' was jumped when creating the 5 Phase sequence.
            RhtHindLeg_A_Tr.Angle -= 1 * speed * 0.5
            RhtHindLeg_B_Tr.Angle -= RhtHindLeg_B_Shift5 * speed * 0.5
            RhtHindLeg_C_Tr.Angle += RhtHindLeg_C_Shift5 * speed * 0.5
            RhtHindPawTr.Angle -= RhtHindLegPawShift5 * speed * 0.5

            LeftHindLeg_A_Tr.Angle += LeftHindLeg_A_Shift5 * speed * 0.5
            LeftHindLeg_B_Tr.Angle += LeftHindLeg_B_Shift5 * speed * 0.5
            LeftHindLeg_C_Tr.Angle -= LeftHindLeg_C_Shift5 * speed * 0.5
            LeftHindPawTr.Angle -= LeftHindLegPawShift5 * speed * 0.5

            RhtForeLeg_A_Tr.Angle -= RhtForeLeg_A_Shift5 * speed * 0.5
            RhtForeLeg_B_Tr.Angle -= RhtForeLeg_B_Shift5 * speed * 0.5
            RhtForeLeg_C_Tr.Angle += RhtForeLeg_C_Shift5 * speed * 0.5
            RhtForePawTr.Angle += RhtForeLegPawShift5 * speed * 0.5

            LeftForeLeg_A_Tr.Angle += LeftForeLeg_A_Shift5 * speed * 0.5
            LeftForeLeg_B_Tr.Angle += LeftForeLeg_B_Shift5 * speed * 0.5
            LeftForePawTr.Angle -= LeftForeLegPawShift5 * speed * 0.5

            ShiftAvalonaDown()
        End If

        If RhtHindLeg_A_Tr.Angle = -14 Then
            FocusOnRightHind = False
            ' Set angles to Phase 5 stance
            RhtHndFocusPhase5Stance()
        End If
    End Sub

The LeftHindBack method is similar to the RightHindBack method, with the code for shifting from the standing position missing and an interchange of variables. The logic is still the same.

    Private Sub LeftHindBack()
        ' Get to Phase 2
        If LeftHindLeg_A_Tr.Angle >= 4 And LeftHindLeg_A_Tr.Angle < 8 Then
            LeftHindLeg_A_Tr.Angle += 1 * speed
            LeftHindLeg_B_Tr.Angle += RhtHindLeg_B_Shift2 * speed
            LeftHindLeg_C_Tr.Angle -= RhtHindLeg_C_Shift2 * speed
            LeftHindPawTr.Angle += RhtHindLegPawShift2 * speed

            RhtHindLeg_A_Tr.Angle += LeftHindLeg_A_Shift2 * speed
            RhtHindLeg_B_Tr.Angle -= LeftHindLeg_B_Shift2 * speed
            RhtHindLeg_C_Tr.Angle += LeftHindLeg_C_Shift2 * speed
            RhtHindPawTr.Angle += LeftHindLegPawShift2 * speed

            LeftForeLeg_A_Tr.Angle += RhtForeLeg_A_Shift2 * speed
            LeftForeLeg_B_Tr.Angle += RhtForeLeg_B_Shift2 * speed
            LeftForePawTr.Angle -= RhtForeLegPawShift2 * speed

            RhtForeLeg_A_Tr.Angle += LeftForeLeg_A_Shift2 * speed
            RhtForeLeg_B_Tr.Angle -= LeftForeLeg_B_Shift2 * speed
            RhtForeLeg_C_Tr.Angle -= LeftForeLeg_C_Shift2 * speed
            RhtForePawTr.Angle += LeftForeLegPawShift2 * speed
        End If
        ' Get to Phase 3
        If LeftHindLeg_A_Tr.Angle >= 8 And LeftHindLeg_A_Tr.Angle < 14 Then
            LeftHindLeg_A_Tr.Angle += 1 * speed
            LeftHindLeg_B_Tr.Angle += RhtHindLeg_B_Shift3 * speed
            LeftHindLeg_C_Tr.Angle -= RhtHindLeg_C_Shift3 * speed
            LeftHindPawTr.Angle += RhtHindLegPawShift3 * speed

            RhtHindLeg_A_Tr.Angle += LeftHindLeg_A_Shift3 * speed
            RhtHindLeg_B_Tr.Angle -= LeftHindLeg_B_Shift3 * speed
            RhtHindLeg_C_Tr.Angle += LeftHindLeg_C_Shift3 * speed
            RhtHindPawTr.Angle -= LeftHindLegPawShift3 * speed

            LeftForeLeg_A_Tr.Angle += RhtForeLeg_A_Shift3 * speed
            LeftForeLeg_B_Tr.Angle += RhtForeLeg_B_Shift3 * speed
            LeftForePawTr.Angle -= RhtForeLegPawShift3 * speed

            RhtForeLeg_A_Tr.Angle -= LeftForeLeg_A_Shift3 * speed
            RhtForeLeg_B_Tr.Angle += LeftForeLeg_B_Shift3 * speed
            RhtForeLeg_C_Tr.Angle -= LeftForeLeg_C_Shift3 * speed
            RhtForePawTr.Angle += LeftForeLegPawShift3 * speed
        End If

        If LeftHindLeg_A_Tr.Angle = 14 Then
            MoveLeftLegBackwards = False
        End If
    End Sub

The LeftHindForward method is similar to the RightHindForward method with an interchange of variables.

    Private Sub LeftHindForward()
        ' Get to Phase 4
        If LeftHindLeg_A_Tr.Angle <= 14 And LeftHindLeg_A_Tr.Angle > -4 Then
            LeftHindLeg_A_Tr.Angle -= 1 * speed
            LeftHindLeg_B_Tr.Angle += RhtHindLeg_B_Shift4 * speed
            LeftHindLeg_C_Tr.Angle -= RhtHindLeg_C_Shift4 * speed
            LeftHindPawTr.Angle += RhtHindLegPawShift4 * speed

            RhtHindLeg_A_Tr.Angle += LeftHindLeg_A_Shift4 * speed
            RhtHindLeg_B_Tr.Angle += LeftHindLeg_B_Shift4 * speed
            RhtHindLeg_C_Tr.Angle -= LeftHindLeg_C_Shift4 * speed
            RhtHindPawTr.Angle -= LeftHindLegPawShift4 * speed

            LeftForeLeg_A_Tr.Angle += RhtForeLeg_A_Shift4 * speed
            LeftForeLeg_B_Tr.Angle += RhtForeLeg_B_Shift4 * speed
            LeftForeLeg_C_Tr.Angle += RhtForeLeg_C_Shift4 * speed
            LeftForePawTr.Angle -= RhtForeLegPawShift4 * speed

            RhtForeLeg_A_Tr.Angle -= LeftForeLeg_A_Shift4 * speed
            RhtForeLeg_B_Tr.Angle += LeftForeLeg_B_Shift4 * speed
            RhtForeLeg_C_Tr.Angle -= LeftForeLeg_C_Shift4 * speed
            RhtForePawTr.Angle += LeftForeLegPawShift4 * speed

            ShiftAvalonaUp()
        End If
        If LeftHindLeg_A_Tr.Angle = -4 Then
            RhtForeLeg_C_Tr.Angle = 0
        End If
        ' Get to Phase 5
        If LeftHindLeg_A_Tr.Angle <= -4 And LeftHindLeg_A_Tr.Angle > -14 Then
            ' Multiply by 0.5 since Phase 8 in the original sequence
            ' was jumped when creating the 5 Phase sequence.
            LeftHindLeg_A_Tr.Angle -= 1 * speed * 0.5
            LeftHindLeg_B_Tr.Angle -= RhtHindLeg_B_Shift5 * speed * 0.5
            LeftHindLeg_C_Tr.Angle += RhtHindLeg_C_Shift5 * speed * 0.5
            LeftHindPawTr.Angle -= RhtHindLegPawShift5 * speed * 0.5

            RhtHindLeg_A_Tr.Angle += LeftHindLeg_A_Shift5 * speed * 0.5
            RhtHindLeg_B_Tr.Angle += LeftHindLeg_B_Shift5 * speed * 0.5
            RhtHindLeg_C_Tr.Angle -= LeftHindLeg_C_Shift5 * speed * 0.5
            RhtHindPawTr.Angle -= LeftHindLegPawShift5 * speed * 0.5

            LeftForeLeg_A_Tr.Angle -= RhtForeLeg_A_Shift5 * speed * 0.5
            LeftForeLeg_B_Tr.Angle -= RhtForeLeg_B_Shift5 * speed * 0.5
            LeftForeLeg_C_Tr.Angle += RhtForeLeg_C_Shift5 * speed * 0.5
            LeftForePawTr.Angle += RhtForeLegPawShift5 * speed * 0.5

            RhtForeLeg_A_Tr.Angle += LeftForeLeg_A_Shift5 * speed * 0.5
            RhtForeLeg_B_Tr.Angle += LeftForeLeg_B_Shift5 * speed * 0.5
            RhtForePawTr.Angle -= LeftForeLegPawShift5 * speed * 0.5

            ShiftAvalonaDown()
        End If

        If LeftHindLeg_A_Tr.Angle = -14 Then
            FocusOnRightHind = True
            MoveRhtLegBackwards = True
            MoveLeftLegBackwards = True
            LeftHndFocusPhase5Stance()
        End If
    End Sub

Extra Resources

I'm sure that Avalona can do more than just amble. It can run, walk,... maybe even swim. If you are of the same opinion and have the time and interest, the following resources could prove to be useful:

Conclusion

I hope you enjoyed reading the article and taking Avalona for a walk, even if it was only on a treadmill. Stay tuned for the next episode when the Speedster, Xaml Man, and Avalona join forces in an epic battle against Winn Fommz... just kidding. If you want to add some enhancements to Avalona, the doors of the M Labs Animaloid Research Center are wide open once you download the source files and open the solution. Cheers!

History

  • 1st February, 2011: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Meshack Musundi
Software Developer
Kenya Kenya
Meshack is an avid programmer with a bias towards WPF and VB.NET. He has about 5 years of programming experience initially starting off with Java before shifting to .NET, thanks to the allure of WPF. He has developed several applications, and written several articles about them, which can be viewed here on CodeProject. He currently resides in a small town in Kiambu county, Kenya.
 
Awards;
  • CodeProject MVP 2013
  • CodeProject MVP 2012
  • Best VB.NET article of August 2013
  • Best VB.NET article of February 2013
  • Best VB.NET article of October 2012
  • Best VB.NET article of July 2012
  • Best VB.NET article of February 2012
  • Best VB.NET article of January 2012
  • Best VB.NET article of November 2011
  • Best VB.NET article of June 2011
  • Best VB.NET article of May 2011
  • Best VB.NET article of March 2011
  • Best VB.NET article of February 2011
  • Best VB.NET article of January 2011
  • Best VB.NET article of December 2010
  • Best VB.NET article of November 2010

Comments and Discussions

 
GeneralMy vote of 3 Pinmembergopal pradhan1-Oct-12 2:53 
GeneralMy vote of 5 PinmemberComputerJin13-Dec-11 20:30 
GeneralRe: My vote of 5 PinmvpMeshack Musundi6-Feb-12 20:52 
GeneralMy vote of 5 Pinmembermurali.isu9-Aug-11 22:04 
GeneralRe: My vote of 5 PinmvpMeshack Musundi6-Feb-12 20:51 
QuestionMy Vote Of 5 PinmemberJyothikarthk11-Jul-11 21:26 
AnswerRe: My Vote Of 5 PinmemberMeshack Musundi11-Jul-11 22:24 
Generalnice but... Pinmemberabudreas19-Mar-11 2:11 
GeneralRe: nice but... PinmemberMeshack Musundi19-Mar-11 2:47 
GeneralMy vote of 5 PinmemberMinhajul Shaoun14-Mar-11 10:10 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.141015.1 | Last Updated 3 Feb 2011
Article Copyright 2011 by Meshack Musundi
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid