WPF开发之实现一种三轴机械手控件

一 引入

考虑实现一种三轴机器人控件。

三轴机器人用来将某种工件从一个位置运送到另一个位置。

其X轴为手臂轴,可以正向和反向运动,它处于末端,直接接触工件;

其T轴为旋转轴,可以对手臂进行旋转;

其Z轴为升降轴,可以对手臂和旋转部分进行升降。

二 RobotControl

定义出机器人的轴动作枚举,轴的动作分为回原点,正向运动,反向运动。

public enum WaferRobotZAction
{
    Z_Origin,
    Z_CW,
    Z_CCW
}

public enum WaferRobotXAction
{
    X_Origin,
    X_CW,
    X_CCW
}

public enum WaferRobotTAction
{
    T_Origin,
    T_CW,
    T_CCW
}

声明一个WaferRobotControl的自定义控件,它继承自Control类。

定义一个Wafer属性来表示WaferRobot上的工件。

定义表示X轴动作、T轴动作和Z轴动作的依赖属性,它可以被实际的业务数据源绑定。

当实际的业务数据发生改变时,轴动作属性相应改变,并VisualStateManager来转换控件的状态,以触发样式模板中的动画。

public class WaferRobotControl : Control
{
    static WaferRobotControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(WaferRobotControl), new FrameworkPropertyMetadata(typeof(WaferRobotControl)));
    }

    public static readonly DependencyProperty WaferProperty = DependencyProperty.Register("Wafer", typeof(int), typeof(WaferRobotControl));
    public int Wafer { get => (int)GetValue(WaferProperty); set => SetValue(WaferProperty, value); }

    public static readonly DependencyProperty RobotZActionProperty = DependencyProperty.Register(
       "RobotZAction",
       typeof(WaferRobotZAction),
       typeof(WaferRobotControl),
       new PropertyMetadata(WaferRobotZAction.Z_Origin, RobotZActionPropertyChangedCallback));

    public WaferRobotZAction RobotZAction
    {
        get => (WaferRobotZAction)GetValue(RobotZActionProperty);
        set => SetValue(RobotZActionProperty, value);
    }

    private static void RobotZActionPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var control = d as WaferRobotControl;
        var oldAct = (WaferRobotZAction)e.OldValue;
        var newAct = (WaferRobotZAction)e.NewValue;
        switch (newAct)
        {
            case WaferRobotZAction.Z_Origin:
                VisualStateManager.GoToState(control, newAct.ToString(), true);
                break;
            case WaferRobotZAction.Z_CW:
                if (newAct != oldAct)
                {
                    VisualStateManager.GoToState(control, newAct.ToString(), true);
                }
                break;
            case WaferRobotZAction.Z_CCW:
                if (newAct != oldAct)
                {
                    VisualStateManager.GoToState(control, newAct.ToString(), true);
                }
                break;
            default:
                break;
        }
    }

    public static readonly DependencyProperty RobotXActionProperty = DependencyProperty.Register(
        "RobotXAction",
        typeof(WaferRobotXAction),
        typeof(WaferRobotControl),
        new PropertyMetadata(WaferRobotXAction.X_Origin, RobotXActionPropertyChangedCallback));
    public WaferRobotXAction RobotXAction
    {
        get => (WaferRobotXAction)GetValue(RobotXActionProperty);
        set => SetValue(RobotXActionProperty, value);
    }

    private static void RobotXActionPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var control = d as WaferRobotControl;
        var oldAct = (WaferRobotXAction)e.OldValue;
        var newAct = (WaferRobotXAction)e.NewValue;
        switch (newAct)
        {
            case WaferRobotXAction.X_Origin:
                VisualStateManager.GoToState(control, newAct.ToString(), true);
                break;
            case WaferRobotXAction.X_CW:
                if (newAct != oldAct)
                {
                    VisualStateManager.GoToState(control, newAct.ToString(), true);
                }
                break;
            case WaferRobotXAction.X_CCW:
                if (newAct != oldAct)
                {
                    VisualStateManager.GoToState(control, newAct.ToString(), true);
                }
                break;
            default:
                break;
        }
    }

    public static readonly DependencyProperty RobotTActionProperty = DependencyProperty.Register(
        "RobotTAction",
        typeof(WaferRobotTAction),
        typeof(WaferRobotControl),
        new PropertyMetadata(WaferRobotTAction.T_Origin, RobotTActionPropertyChangedCallback));

    public WaferRobotTAction RobotTAction
    {
        get => (WaferRobotTAction)GetValue(RobotTActionProperty);
        set => SetValue(RobotTActionProperty, value);
    }

    private static void RobotTActionPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var control = d as WaferRobotControl;
        var oldAct = (WaferRobotTAction)e.OldValue;
        var newAct = (WaferRobotTAction)e.NewValue;
        switch (newAct)
        {
            case WaferRobotTAction.T_Origin:
                VisualStateManager.GoToState(control, newAct.ToString(), true);
                break;
            case WaferRobotTAction.T_CW:
                if (newAct != oldAct)
                {
                    VisualStateManager.GoToState(control, newAct.ToString(), true);
                }
                break;
            case WaferRobotTAction.T_CCW:
                if (newAct != oldAct)
                {
                    VisualStateManager.GoToState(control, newAct.ToString(), true);
                }
                break;
            default:
                break;
        }
    }

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        VisualStateManager.GoToState(this, WaferRobotZAction.Z_Origin.ToString(), true);
        VisualStateManager.GoToState(this, WaferRobotXAction.X_Origin.ToString(), true);
        VisualStateManager.GoToState(this, WaferRobotTAction.T_Origin.ToString(), true);
    }
}

三 Style

控件模板的实现思路。

将机器人的样式分为三部分,不动的底座部分,Z轴部分,包含T轴和X轴的手臂部分。

VisualStateGroup中定义出轴动作的VisualState,编写转换动画。


四 效果演示

界面代码如下:


    
        
        

后台代码如下:

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void ZCWButton_Click(object sender, RoutedEventArgs e)
        {
            robot.RobotZAction = WaferRobotZAction.Z_CW;
        }

        private void ZCCWButton_Click(object sender, RoutedEventArgs e)
        {
            robot.RobotZAction = WaferRobotZAction.Z_CCW;
        }

        private void XCWButton_Click(object sender, RoutedEventArgs e)
        {
            robot.RobotXAction = WaferRobotXAction.X_CW;
        }

        private void XCCWButton_Click(object sender, RoutedEventArgs e)
        {
            robot.RobotXAction = WaferRobotXAction.X_CCW;
        }

        private void TCWButton_Click(object sender, RoutedEventArgs e)
        {
            robot.RobotTAction = WaferRobotTAction.T_CW;
        }

        private void TCCWButton_Click(object sender, RoutedEventArgs e)
        {
            robot.RobotTAction = WaferRobotTAction.T_CCW;
        }

        private void AutoButton_Click(object sender, RoutedEventArgs e)
        {
            Task.Run(async () =>
            {
                Application.Current.Dispatcher?.Invoke
                (
                   () => { this.robot.RobotTAction = WaferRobotTAction.T_CCW; }
                );
                await Task.Delay(1000);

                Application.Current.Dispatcher?.Invoke
                (
                   () => { this.robot.RobotXAction = WaferRobotXAction.X_CW; }
                );
                await Task.Delay(2000);

                Application.Current.Dispatcher?.Invoke(
                    () => { this.robot.Wafer = 1; }
                    );
                await Task.Delay(200);

                Application.Current.Dispatcher?.Invoke(
                   () => { this.robot.RobotXAction = WaferRobotXAction.X_CCW; }
                   );
                await Task.Delay(2000);

                Application.Current.Dispatcher?.Invoke(
                 () => { this.robot.RobotZAction = WaferRobotZAction.Z_CW; }
                 );
                await Task.Delay(1000);

                Application.Current.Dispatcher?.Invoke
                (
                   () => { this.robot.RobotTAction = WaferRobotTAction.T_CW; }
                );
                await Task.Delay(1000);

                Application.Current.Dispatcher?.Invoke
                (
                 () => { this.robot.RobotXAction = WaferRobotXAction.X_CW; }
                );
                await Task.Delay(2000);

                Application.Current.Dispatcher?.Invoke(
                    () => { this.robot.Wafer = 0; }
                    );
                await Task.Delay(200);

                Application.Current.Dispatcher?.Invoke(
                 () => { this.robot.RobotXAction = WaferRobotXAction.X_CCW; }
                 );
                await Task.Delay(2000);
                Application.Current.Dispatcher?.Invoke
                (
                  () => { this.robot.RobotTAction = WaferRobotTAction.T_Origin; }
                );
                await Task.Delay(1000);
                Application.Current.Dispatcher?.Invoke
                (
                  () => { this.robot.RobotZAction = WaferRobotZAction.Z_CCW; }
                );
                await Task.Delay(1000);
            });
        }
    }

以上就是WPF开发之实现一种三轴机械手控件的详细内容,更多关于WPF三轴机械手控件的资料请关注脚本之家其它相关文章!

你可能感兴趣的:(WPF开发之实现一种三轴机械手控件)