65.9K
CodeProject 正在变化。 阅读更多。
Home

Amble Avalona

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.89/5 (50投票s)

2011年2月1日

CPOL

4分钟阅读

viewsIcon

72129

downloadIcon

1821

一个 WPF 动物形态

Screenshot1.png

引言

继我上一篇文章的脚步,不给四足动物Xaml化任务添砖加瓦就太不应该了。简而言之,我决定做一个WPF项目来模拟一只四足动物行走。

要求

要运行从上面的下载链接提供的项目,你需要以下之一

  • Visual Studio 2010
  • Expression Blend

如果您正在使用VS 2008,可以从这里下载源代码文件。

注意:如果您使用的是Visual Studio的Express版本,请确保使用Visual Basic Express打开解决方案。

Avalona

工作原理

要让Avalona行走,只需按右箭头键。Avalona将在跑步机上缓步前行,这次的场景发生在M Labs Animaloid Research Centre

缓步

缓步是一种轻松的步态(行走方式),在马匹中最为常见,在运动的各个阶段至少有一条腿/蹄子接触地面。没有悬空阶段,也就是说,所有腿都完全离开地面的阶段。这是我决定模拟缓步的主要原因。在此步态下,最多可以有两条腿支撑动物的体重。以下一系列照片展示了在此步态下遵循的各个阶段。

Screenshot2.png

上面照片中展示的运动阶段的简短而详细的解释可以在这里找到。

上面的照片中有11个阶段,有点太多了,所以我将其缩减到5个阶段,这也能提供同样合适的结果。

Screenshot3.png

从初始的照片序列中,我选择了第4、5、6、7和9个阶段。

如果您愿意,可以在这里观看一匹马缓步行走的视频。

设计和布局

我在Expression Design中设计了AvalonaTreadmillLab_Screen。其余的元素则是在Expression Blend中添加的。下图显示了相关元素的布局及其名称(左腿也同样适用),

Screenshot4.png

注意:Avalona每个部分的关节中心充当着中心点。

腿部运动

Avalona的站立姿势与马匹的站立姿势略有不同。Avalona的四肢角度更小,特别是后腿。

Screenshot5.png

这给我尝试模拟缓步带来了一些挑战。由于这种差异,Avalona的步态是马匹缓步的略微修改版本。

为了更清晰地了解如何进行,我画了缓步马的火柴人图,然后画了缓步Avalona的火柴人图,同时考虑了它们站立姿势的差异。然后,我在Expression Blend中调整了相关元素,使其处于与火柴人图相似的位置,并记下了我认为能提供合适结果的角度。这些就是结果。

Screenshot6.png

Screenshot7.png

代码

提供我们所需魔力的计算在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

我们在MainWindow KeyDown事件处理程序中检查按下了哪个键。

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

WalkForward方法的作用正如其名。

    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

在上述方法中,根据各种布尔型变量的值调用方法。RightHindBack方法将Avalona腿部的各个部分从站立位置旋转到阶段3。之后,它会交替地将元素从阶段1旋转到阶段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

RightHindForward方法将Avalona腿部的各个部分从阶段3旋转到阶段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

LeftHindBack方法与RightHindBack方法相似,只是缺少了从站立位置转移的代码,并且变量进行了交换。逻辑仍然相同。

    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

LeftHindForward方法与RightHindForward方法相似,只是变量进行了交换。

    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

额外资源

我相信Avalona能做的不仅仅是缓步。它可以奔跑、行走……甚至可能游泳。如果您也这么认为,并且有时间和兴趣,以下资源可能会有所帮助。

结论

希望您喜欢阅读这篇文章,并带着Avalona走了一段路,即使它只是一台跑步机。请继续关注下一集,届时SpeedsterXaml ManAvalona将联手对抗Winn Fommz……开玩笑的。如果您想为Avalona添加一些增强功能,只要下载源代码并打开解决方案,M Labs Animaloid Research Center的大门就为您敞开。祝您一切顺利!

历史

  • 2011 年 2 月 1 日:初始发布
© . All rights reserved.