7.18.2017

Wpf 3D - Helix Toolkit - 一個方便的3D展示函式庫

在youtube上看到了一個wpf上的3D控制展示,附source code,下載後發覺Helix toolkit把最麻煩的部份都處理掉了,可以很簡單的控制3d視圖中各部件的作動,看到這個就想到機台控制應該也可以用此方式來模擬,感覺上應該會很有趣XD。

3D

主要的控制程式如下(有稍微整理過):

public partial class MainWindow : Window
    {
        //provides functionality to 3d models
        Model3DGroup RA = new Model3DGroup();
        Model3D link1 = null;
        Model3D link2 = null;
        Model3D link3 = null;
        Model3D link4 = null;
        Model3D link5 = null;

        //provides render to model3d objects
        ModelVisual3D RoboticArm = new ModelVisual3D();

        //directroy of all stl files
        private const string MODEL_PATH1 = "j0_j1_link.stl";
        private const string MODEL_PATH2 = "j1_j2_link.stl";
        private const string MODEL_PATH3 = "j2_j3_link.stl";
        private const string MODEL_PATH4 = "j3_j4_link.stl";
        private const string MODEL_PATH5 = "j4_j5_link.stl";

        RotateTransform3D R = new RotateTransform3D();
        TranslateTransform3D T = new TranslateTransform3D();

        public MainWindow()
        {
            InitializeComponent();
            RoboticArm.Content = Initialize_Environment(MODEL_PATH1, MODEL_PATH2,MODEL_PATH3, MODEL_PATH4, MODEL_PATH5);
            viewPort3d.Children.Add(RoboticArm);
        }

        private Model3DGroup Initialize_Environment(string model1, string model2, string model3, string model4, string model5)
        {
            try
            {
                viewPort3d.RotateGesture = new MouseGesture(MouseAction.LeftClick);
                ModelImporter import = new ModelImporter();
                link1 = import.Load(model1);
                link2 = import.Load(model2);
                link3 = import.Load(model3);
                link4 = import.Load(model4);
                link5 = import.Load(model5);

                execute_fk();

                RA.Children.Add(link1);
                RA.Children.Add(link2);
                RA.Children.Add(link3);
                RA.Children.Add(link4);
                RA.Children.Add(link5);
            }
            catch (Exception e)
            {
                MessageBox.Show("Exception Error:" + e.StackTrace);
            }
            return RA;
        }

        private void joint1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
          execute_fk();
        }        

        private void execute_fk()
        {
            var F1 = new Transform3DGroup();
            var F2 = new Transform3DGroup();
            var F3 = new Transform3DGroup();
            var F4 = new Transform3DGroup();
            var F5 = new Transform3DGroup();

            var p3d = new Point3D(0, 0, 0);
            R = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 0, 1), joint1.Value), p3d);
            // F1為基座,僅能旋轉,目前角度為joint1.Value指定
            F1.Children.Add(R);

            p3d = new Point3D(0, 0, 9.5);
            T = new TranslateTransform3D(p3d.ToVector3D());
            // F2可旋轉,目前角度為joint2.Value
            R = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), joint2.Value), p3d);
            // F2連接至F1,位置在其Z軸方向9.5
            F2.Children.Add(F1);
            F2.Children.Add(T);
            F2.Children.Add(R);

            p3d = new Point3D(15, 0, 0);            
            T = new TranslateTransform3D(p3d.ToVector3D());
            R = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), joint3.Value), p3d);
            F3.Children.Add(T);
            F3.Children.Add(R);
            F3.Children.Add(F2);

            p3d = new Point3D(6.7, 0, 0);
            T = new TranslateTransform3D(p3d.ToVector3D());
            R = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), joint4.Value), p3d);
            F4.Children.Add(T);
            F4.Children.Add(R);
            F4.Children.Add(F3);

            p3d = new Point3D(5.35, 0, 0);
            T = new TranslateTransform3D(p3d.ToVector3D());
            R = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(1, 0, 0), joint5.Value), p3d);
            F5.Children.Add(T);
            F5.Children.Add(R);
            F5.Children.Add(F4);

            link1.Transform = F1;
            link2.Transform = F2;
            link3.Transform = F3;
            link4.Transform = F4;
            link5.Transform = F5;
        }
    }

程式中手臂主要是由五個副檔名為.stl的機構組成,每個.stl檔對映到一個Model3D物件,在每個Model3D物件中設定其旋轉(RotateTransform3D)及位置(TranslateTransform3D),最後所有的Model3D物件再組合成Model3DGroup - RA,再由ModelVisual3D RoboticArm負責Render,最後放到HelixViewport3D中展示。

作者也將此程式另行擴充成一個更完整的可編輯Frame來形成動畫的軟體,如下所示:

Robotic Arm Windows Application

Written with StackEdit.

1 則留言:

  1. 可以提供代码参考一下吗,我正想弄一个其他机器人的

    回覆刪除