示例#1
0
        public static void DoGUIMagCalib(bool dointro = true)
        {
            ans = null;
            filtercompass1.Clear();
            datacompass1.Clear();
            datacompass2.Clear();
            filtercompass2.Clear();
            error  = 99;
            error2 = 99;

            if (dointro)
            {
                MessageBox.Show("该功能目前正在测试中!");
            }

            using (ProgressReporterSphere prd = new ProgressReporterSphere())
            {
                prd.DoWork += prd_DoWork;

                prd.RunBackgroundOperationAsync();
            }

            if (ans != null)
            {
                MagCalib.SaveOffsets(ans);
            }

            if (ans2 != null)
            {
                MagCalib.SaveOffsets2(ans2);
            }
        }
示例#2
0
        static void prd_DoWork(object sender, ProgressWorkerEventArgs e, object passdata = null)
        {
            bool havecompass2 = false;

            havecompass2 = true;

            int hittarget = 14;


            // old method
            float minx = 0;
            float maxx = 0;
            float miny = 0;
            float maxy = 0;
            float minz = 0;
            float maxz = 0;

            MavLinkInterface mavLinkInterface = new MavLinkInterface();

            MavLink.mavlink_request_data_stream_t req = new MavLink.mavlink_request_data_stream_t();

            mavLinkInterface = new MavLinkInterface();
            req = new MavLink.mavlink_request_data_stream_t();
            req.target_system    = Global.sysID;
            req.target_component = Global.compID;
            req.req_message_rate = 30;      //50
            req.start_stop       = 1;       // start
            req.req_stream_id    = (byte)1; // id 1
            // send each one twice.
            mavLinkInterface.AssembleAndSendFrame((byte)MavLink.MAVLINK_MSG_ID.REQUEST_DATA_STREAM, req);
            mavLinkInterface.AssembleAndSendFrame((byte)MavLink.MAVLINK_MSG_ID.REQUEST_DATA_STREAM, req);


            string extramsg = "";

            // clear any old data
            ((ProgressReporterSphere)sender).sphere1.Clear();
            ((ProgressReporterSphere)sender).sphere2.Clear();

            // keep track of data count and last lsq run
            int      lastcount = 0;
            DateTime lastlsq   = DateTime.MinValue;
            DateTime lastlsq2  = DateTime.MinValue;
            DateTime lastlsq3  = DateTime.MinValue;

            HI.Vector3 centre = new HI.Vector3();

            int pointshitnum = 0;

            while (true)
            {
                // slow down execution
                System.Threading.Thread.Sleep(10);

                string str = "  共有 " + datacompass1.Count + " 份数据\n\n" +
                             "  罗盘 1 误差:" + error + "\n" +
                             "  罗盘 2 误差:" + error2 + "\n" +
                             "  结束条件,罗盘 1 误差不大于0.2";
                str += "\n  " + extramsg;

                ((ProgressReporterDialogue)sender).UpdateProgressAndStatus(-1, str);

                addcompass1list();
                addcompass2list();


                if (e.CancelRequested)
                {
                    e.CancelAcknowledged = false;
                    e.CancelRequested    = false;
                    break;
                }

                if (datacompass1.Count == 0)
                {
                    continue;
                }

                float rawmx = datacompass1[datacompass1.Count - 1].Item1;
                float rawmy = datacompass1[datacompass1.Count - 1].Item2;
                float rawmz = datacompass1[datacompass1.Count - 1].Item3;

                // for old method
                setMinorMax(rawmx, ref minx, ref maxx);
                setMinorMax(rawmy, ref miny, ref maxy);
                setMinorMax(rawmz, ref minz, ref maxz);


                if (datacompass1.Count > 100 && lastlsq.Second != DateTime.Now.Second)   //w
                {
                    //req = new MavLink.mavlink_request_data_stream_t();
                    //req.target_system = Global.sysID;
                    //req.target_component = Global.compID;
                    //req.req_message_rate = 30; //50
                    //req.start_stop = 1; // start
                    //req.req_stream_id = (byte)1; // id 1
                    //// send each one twice.
                    //mavLinkInterface.AssembleAndSendFrame((byte)MavLink.MAVLINK_MSG_ID.REQUEST_DATA_STREAM, req);
                    //mavLinkInterface.AssembleAndSendFrame((byte)MavLink.MAVLINK_MSG_ID.REQUEST_DATA_STREAM, req);


                    lastlsq = DateTime.Now;
                    lock (datacompass1)
                    {
                        var lsq = MagCalib.LeastSq(datacompass1, false);
                        // simple validation
                        if (Math.Abs(lsq[0]) < 999)
                        {
                            centre = new HI.Vector3(lsq[0], lsq[1], lsq[2]);

                            ((ProgressReporterSphere)sender).sphere1.CenterPoint = new OpenTK.Vector3(
                                (float)centre.x, (float)centre.y, (float)centre.z);
                        }
                    }
                }

                // run lsq every second when more than 100 datapoints
                if (datacompass2.Count > 100 && lastlsq2.Second != DateTime.Now.Second)//w
                {
                    lastlsq2 = DateTime.Now;
                    lock (datacompass2)
                    {
                        var lsq = MagCalib.LeastSq(datacompass2, false);
                        // simple validation
                        if (Math.Abs(lsq[0]) < 999)
                        {
                            HI.Vector3 centre2 = new HI.Vector3(lsq[0], lsq[1], lsq[2]);

                            ((ProgressReporterSphere)sender).sphere2.CenterPoint = new OpenTK.Vector3(
                                (float)centre2.x, (float)centre2.y, (float)centre2.z);
                        }
                    }
                }

                if (lastcount == datacompass1.Count)
                {
                    continue;
                }

                lastcount = datacompass1.Count;

                // add to sphere with center correction
                ((ProgressReporterSphere)sender).sphere1.AddPoint(new OpenTK.Vector3(rawmx, rawmy, rawmz));
                ((ProgressReporterSphere)sender).sphere1.AimClear();

                if (datacompass2.Count > 30)//w
                {
                    float raw2mx = datacompass2[datacompass2.Count - 1].Item1;
                    float raw2my = datacompass2[datacompass2.Count - 1].Item2;
                    float raw2mz = datacompass2[datacompass2.Count - 1].Item3;

                    ((ProgressReporterSphere)sender).sphere2.AddPoint(new OpenTK.Vector3(raw2mx, raw2my, raw2mz));
                    ((ProgressReporterSphere)sender).sphere2.AimClear();
                }

                HI.Vector3 point;

                point = new HI.Vector3(rawmx, rawmy, rawmz) + centre;

                //find the mean radius
                float radius = 0;
                for (int i = 0; i < datacompass1.Count; i++)
                {
                    point   = new HI.Vector3(datacompass1[i].Item1, datacompass1[i].Item2, datacompass1[i].Item3);
                    radius += (float)(point + centre).length();
                }
                radius /= datacompass1.Count;

                //test that we can find one point near a set of points all around the sphere surface
                int    pointshit     = 0;
                string displayresult = "";
                int    factor        = 3;          // pitch
                int    factor2       = 4;          // yaw
                float  max_distance  = radius / 3; //pretty generouse
                for (int j = 0; j <= factor; j++)
                {
                    double theta = (Math.PI * (j + 0.5)) / factor;

                    for (int i = 0; i <= factor2; i++)
                    {
                        double phi = (2 * Math.PI * i) / factor2;

                        HI.Vector3 point_sphere = new HI.Vector3(
                            (float)(Math.Sin(theta) * Math.Cos(phi) * radius),
                            (float)(Math.Sin(theta) * Math.Sin(phi) * radius),
                            (float)(Math.Cos(theta) * radius)) - centre;

                        //log.InfoFormat("magcalib check - {0} {1} dist {2}", theta * rad2deg, phi * rad2deg, max_distance);

                        bool found = false;
                        for (int k = 0; k < datacompass1.Count; k++)
                        {
                            point = new HI.Vector3(datacompass1[k].Item1, datacompass1[k].Item2, datacompass1[k].Item3);
                            double d = (point_sphere - point).length();
                            if (d < max_distance)
                            {
                                pointshit++;
                                found = true;
                                break;
                            }
                        }


                        // draw them all
                        //((ProgressReporterSphere)sender).sphere1.AimFor(new OpenTK.Vector3((float)point_sphere.x, (float)point_sphere.y, (float)point_sphere.z));
                        //if (!found)
                        //{
                        //    displayresult = "需要更多的数据 " +
                        //                    GetColour((int)(theta * rad2deg), (int)(phi * rad2deg));
                        //    ((ProgressReporterSphere)sender).sphere1.AimFor(new OpenTK.Vector3((float)point_sphere.x,
                        //        (float)point_sphere.y, (float)point_sphere.z));
                        //    //j = factor;
                        //    //break;
                        //}
                    }
                }

                extramsg = displayresult;



                if (error < 0.2 && pointshit > hittarget && ((ProgressReporterSphere)sender).autoaccept)
                {
                    extramsg = "";
                    MessageBox.Show("旋转完成\r\n请自行关闭罗盘校准窗口");
                    break;
                }
            }

            req = new MavLink.mavlink_request_data_stream_t();
            req.target_system    = Global.sysID;
            req.target_component = Global.compID;
            req.req_message_rate = 2;       //50
            req.start_stop       = 1;       // start
            req.req_stream_id    = (byte)1; // id 1
            // send each one twice.
            mavLinkInterface.AssembleAndSendFrame((byte)MavLink.MAVLINK_MSG_ID.REQUEST_DATA_STREAM, req);
            mavLinkInterface.AssembleAndSendFrame((byte)MavLink.MAVLINK_MSG_ID.REQUEST_DATA_STREAM, req);

            ans  = MagCalib.LeastSq(datacompass1, false);
            ans2 = MagCalib.LeastSq(datacompass2, false);
        }