コード例 #1
0
 public static Matrix3 rotation_df(ATT ATT)
 {
     //return the current DCM rotation matrix''' 
     var r = new Matrix3();
     r.from_euler(radians(ATT.Roll), radians(ATT.Pitch), radians(ATT.Yaw));
     return r;
 }
コード例 #2
0
        public static double mag_heading_df(MAG_t MAG, ATT_t ATT, double declination = 0, Vector3 ofs = null,
            Vector3 diagonals = null, Vector3 offdiagonals = null)
        {
            if (diagonals == null)
                diagonals = Vector3.One;
            if (offdiagonals == null)
                offdiagonals = Vector3.Zero;
            //'''calculate heading from raw magnetometer'''
            //if (declination == 0)
            //declination = degrees(mavutil.mavfile_global.param('COMPASS_DEC', 0));
            var mag = new Vector3(MAG.MagX, MAG.MagY, MAG.MagZ);
            if (ofs != null)
            {
                mag += new Vector3(ofs[0], ofs[1], ofs[2]) - new Vector3(MAG.OfsX, MAG.OfsY, MAG.OfsZ);
                diagonals = new Vector3(diagonals[0], diagonals[1], diagonals[2]);
                offdiagonals = new Vector3(offdiagonals[0], offdiagonals[1], offdiagonals[2]);
                var rot = new Matrix3(new Vector3(diagonals.x, offdiagonals.x, offdiagonals.y),
                    new Vector3(offdiagonals.x, diagonals.y, offdiagonals.z),
                    new Vector3(offdiagonals.y, offdiagonals.z, diagonals.z));
                mag = rot*mag;
            }
//# go via a DCM matrix to match the APM calculation
            var dcm_matrix = rotation_df(ATT);
            var cos_pitch_sq = 1.0 - (dcm_matrix.c.x*dcm_matrix.c.x);
            var headY = mag.y*dcm_matrix.c.z - mag.z*dcm_matrix.c.y;
            var headX = mag.x*cos_pitch_sq - dcm_matrix.c.x*(mag.y*dcm_matrix.c.y + mag.z*dcm_matrix.c.z);

            var heading = degrees(atan2(-headY, headX)) + declination;
            if (heading < 0)
                heading += 360;
            return heading;
        }
コード例 #3
0
ファイル: Matrix3.cs プロジェクト: ECain/MissionPlanner
        public Matrix3(Vector3 a, Vector3 b, Vector3 c)
        {
            self = this;

            this.a = a;
            this.b = b;
            this.c = c;
        }
コード例 #4
0
        /// <summary>
        /// Recevied UDP packet, process and send required data to serial port.
        /// </summary>
        /// <param name="data">Packet</param>
        /// <param name="receviedbytes">Length</param>
        /// <param name="comPort">Com Port</param>
        private void RECVprocess(byte[] data, int receviedbytes, MAVLinkInterface comPort)
        {
            sitl_fdm sitldata = new sitl_fdm();

            if (data[0] == 'D' && data[1] == 'A')
            {
                // Xplanes sends
                // 5 byte header
                // 1 int for the index - numbers on left of output
                // 8 floats - might be useful. or 0 if not
                int count = 5;
                while (count < receviedbytes)
                {
                    int index = BitConverter.ToInt32(data, count);

                    DATA[index] = new float[8];

                    DATA[index][0] = BitConverter.ToSingle(data, count + 1 * 4); ;
                    DATA[index][1] = BitConverter.ToSingle(data, count + 2 * 4); ;
                    DATA[index][2] = BitConverter.ToSingle(data, count + 3 * 4); ;
                    DATA[index][3] = BitConverter.ToSingle(data, count + 4 * 4); ;
                    DATA[index][4] = BitConverter.ToSingle(data, count + 5 * 4); ;
                    DATA[index][5] = BitConverter.ToSingle(data, count + 6 * 4); ;
                    DATA[index][6] = BitConverter.ToSingle(data, count + 7 * 4); ;
                    DATA[index][7] = BitConverter.ToSingle(data, count + 8 * 4); ;

                    count += 36; // 8 * float
                }

                bool xplane9 = !CHK_xplane10.Checked;

               

                if (xplane9)
                {
                    sitldata.pitchDeg = (DATA[18][0]);
                    sitldata.rollDeg = (DATA[18][1]);
                    sitldata.yawDeg = (DATA[18][2]);
                    sitldata.pitchRate = (DATA[17][0] * rad2deg);
                    sitldata.rollRate = (DATA[17][1] * rad2deg);
                    sitldata.yawRate = (DATA[17][2] * rad2deg);

                    sitldata.heading = ((float)DATA[19][2]);

                    sitldata.speedN =-DATA[21][5];// (DATA[3][7] * 0.44704 * Math.Sin(sitldata.heading * deg2rad));
                    sitldata.speedE = DATA[21][3];// (DATA[3][7] * 0.44704 * Math.Cos(sitldata.heading * deg2rad));
                    sitldata.speedD = -DATA[21][4];
                }
                else
                {
                    sitldata.pitchDeg = (DATA[17][0]);
                    sitldata.rollDeg = (DATA[17][1]);
                    sitldata.yawDeg = (DATA[17][2]);
                    sitldata.pitchRate = (DATA[16][0] * rad2deg);
                    sitldata.rollRate = (DATA[16][1] * rad2deg);
                    sitldata.yawRate = (DATA[16][2] * rad2deg);

                    sitldata.heading = (DATA[18][2]); // 18-2


                    sitldata.speedN = -DATA[21][5];// (DATA[3][7] * 0.44704 * Math.Sin(sitldata.heading * deg2rad));
                    sitldata.speedE = DATA[21][3];// (DATA[3][7] * 0.44704 * Math.Cos(sitldata.heading * deg2rad));
                    sitldata.speedD = -DATA[21][4];
                }

                sitldata.airspeed = ((DATA[3][5] * .44704));

                sitldata.latitude = (DATA[20][0]);
                sitldata.longitude = (DATA[20][1]);
                sitldata.altitude = (DATA[20][2] * ft2m);

           

                Matrix3 dcm = new Matrix3();
                dcm.from_euler(sitldata.rollDeg * deg2rad, sitldata.pitchDeg * deg2rad, sitldata.heading * deg2rad);

                // rad = tas^2 / (tan(angle) * G)
                float turnrad = (float)(((DATA[3][7] * 0.44704) * (DATA[3][7] * 0.44704)) / (float)(9.808f * Math.Tan(sitldata.rollDeg * deg2rad)));

                float gload = (float)(1 / Math.Cos(sitldata.rollDeg * deg2rad)); // calculated Gs

                // a = v^2/r
                float centripaccel = (float)((DATA[3][7] * 0.44704) * (DATA[3][7] * 0.44704)) / turnrad;

                Vector3 accel_body = dcm.transposed() * (new Vector3(0, 0, -9.808));

                Vector3 centrip_accel = new Vector3(0, centripaccel * Math.Cos(sitldata.rollDeg * deg2rad), centripaccel * Math.Sin(sitldata.rollDeg * deg2rad));

              //  accel_body += centrip_accel;

                Vector3 velocitydelta = dcm.transposed() * (new Vector3((sitldata_old.speedN - sitldata.speedN), (sitldata_old.speedE - sitldata.speedE), (sitldata_old.speedD - sitldata.speedD)));

                Vector3 velocity = dcm.transposed() * (new Vector3((sitldata.speedN), (sitldata.speedE), (sitldata.speedD)));

                //Console.WriteLine("vel " + velocity.ToString());
                //Console.WriteLine("ved " + velocitydelta.ToString());

                // a = dv / dt

                // 50 hz = 0.02sec
                Vector3 accel_mine_body = dcm.transposed() * (new Vector3((sitldata_old.speedN - sitldata.speedN) / 0.02, (sitldata_old.speedE - sitldata.speedE) / 0.02, (sitldata_old.speedD - sitldata.speedD) / 0.02));

             //   Console.WriteLine("G"+accel_body.ToString());
                //Console.WriteLine("M"+accel_mine_body.ToString());

             //   sitldata.pitchRate = 0;
              //  sitldata.rollRate = 0;
              //  sitldata.yawRate = 0;

                //accel_mine_body.x =0;// *= -1;
                //accel_mine_body.y =0;//*= -1;

               // accel_body -= accel_mine_body;

                sitldata.xAccel = accel_body.x;// DATA[4][5] * 1;
                sitldata.yAccel = accel_body.y;//  DATA[4][6] * 1;
                sitldata.zAccel = accel_body.z;//  (0 - DATA[4][4]) * 9.808;

                sitldata.xAccel = DATA[4][5] *9.808;
                sitldata.yAccel = DATA[4][6] *9.808;
                sitldata.zAccel = -DATA[4][4] *9.808;

             //   Console.WriteLine(accel_body.ToString());
              //  Console.WriteLine("        {0} {1} {2}",sitldata.xAccel, sitldata.yAccel, sitldata.zAccel);

            }
            else if (receviedbytes == 0x64) // FG binary udp
            {
                //FlightGear
                /*

                fgIMUData imudata2 = data.ByteArrayToStructureBigEndian<fgIMUData>(0);

                if (imudata2.magic != 0x4c56414d)
                    return;

                if (imudata2.latitude == 0)
                    return;

                chkSensor.Checked = true;

                imu.time_usec = ((ulong)DateTime.Now.ToBinary());

                imu.xacc = ((Int16)(imudata2.accelX * 9808 / 32.2));
                imu.xgyro = ((Int16)(imudata2.rateRoll * 17.453293));
                imu.xmag = 0;
                imu.yacc = ((Int16)(imudata2.accelY * 9808 / 32.2));
                imu.ygyro = ((Int16)(imudata2.ratePitch * 17.453293));
                imu.ymag = 0;
                imu.zacc = ((Int16)(imudata2.accelZ * 9808 / 32.2)); // + 1000
                imu.zgyro = ((Int16)(imudata2.rateYaw * 17.453293));
                imu.zmag = 0;

                gps.alt = ((int)(imudata2.altitude * ft2m * 1000));
                gps.fix_type = 3;
                gps.cog = (ushort)(Math.Atan2(imudata2.velocityE, imudata2.velocityN) * rad2deg * 100);
                gps.lat = (int)(imudata2.latitude * 1.0e7);
                gps.lon = (int)(imudata2.longitude * 1.0e7);
                gps.time_usec = ((ulong)DateTime.Now.Ticks);
                gps.vel = (ushort)(Math.Sqrt((imudata2.velocityN * imudata2.velocityN) + (imudata2.velocityE * imudata2.velocityE)) * ft2m * 100);

                //FileStream stream = File.OpenWrite("fgdata.txt");
                //stream.Write(data, 0, receviedbytes);
                //stream.Close();
                 */
            }
            else if (receviedbytes == 662 || receviedbytes == 658) // 658 = 3.83   662 = 3.91
            {
                /*
            // Model data in body frame coordinates (X=Right, Y=Front, Z=Up)
            public float Model_fVel_Body_X; public float Model_fVel_Body_Y; public float Model_fVel_Body_Z;    // m/s    Model velocity in body coordinates
            public float Model_fAngVel_Body_X; public float Model_fAngVel_Body_Y; public float Model_fAngVel_Body_Z; // rad/s  Model angular velocity in body coordinates
            public float Model_fAccel_Body_X; public float Model_fAccel_Body_Y; public float Model_fAccel_Body_Z;  // m/s/s  Model acceleration in body coordinates
                 */
                TDataFromAeroSimRC aeroin_last = aeroin;

                aeroin = data.ByteArrayToStructure<TDataFromAeroSimRC>(0);

                sitldata.pitchDeg = (aeroin.Model_fPitch * rad2deg);
                sitldata.rollDeg = (aeroin.Model_fRoll * -1 * rad2deg);
                sitldata.yawDeg = ((aeroin.Model_fHeading * rad2deg));

                sitldata.pitchRate =aeroin.Model_fAngVel_Body_X * rad2deg;
                sitldata.rollRate = aeroin.Model_fAngVel_Body_Y * rad2deg;
                sitldata.yawRate = -aeroin.Model_fAngVel_Body_Z * rad2deg;

                // calc gravity
                Matrix3 dcm = new Matrix3();
                dcm.from_euler(sitldata.rollDeg * deg2rad, sitldata.pitchDeg * deg2rad, sitldata.yawDeg * deg2rad);

                Vector3 accel_body = dcm.transposed() * (new Vector3(0, 0, -9.8)); // -9.8

                sitldata.xAccel = aeroin.Model_fAccel_Body_Y / 9.808 + accel_body.x;// pitch - back forward-
                sitldata.yAccel = aeroin.Model_fAccel_Body_X / 9.808 + accel_body.y; // roll - left right-
                sitldata.zAccel = -aeroin.Model_fAccel_Body_Z /9.808 + accel_body.z;

              //  Console.WriteLine("2 {0,20} {1,20} {2,20}", aeroin.Model_fAccel_Body_X.ToString("0.000"), aeroin.Model_fAccel_Body_Y.ToString("0.000"), aeroin.Model_fAccel_Body_Z.ToString("0.000"));

                sitldata.altitude = aeroin.Model_fPosZ;
                sitldata.latitude = aeroin.Model_fLatitude;
                sitldata.longitude = aeroin.Model_fLongitude;

                sitldata.speedN = aeroin.Model_fVelY;
                sitldata.speedE = aeroin.Model_fVelX;
                sitldata.speedD = aeroin.Model_fVelZ;

                float xvec = aeroin.Model_fVelY - aeroin.Model_fWindVelY;
                float yvec = aeroin.Model_fVelX - aeroin.Model_fWindVelX;

                sitldata.airspeed = ((float)Math.Sqrt((yvec * yvec) + (xvec * xvec)));
            }
            else if (receviedbytes == 408)
            {
                
                FGNetFDM fdm = data.ByteArrayToStructureBigEndian<FGNetFDM>(0);

                lastfdmdata = fdm;

                sitldata.altitude = (fdm.altitude);
                sitldata.latitude = (fdm.latitude * rad2deg);
                sitldata.longitude = (fdm.longitude * rad2deg);

                sitldata.rollDeg = fdm.phi * rad2deg;
                sitldata.pitchDeg = fdm.theta * rad2deg;
                sitldata.yawDeg = fdm.psi * rad2deg;

                sitldata.rollRate = fdm.phidot * rad2deg;
                sitldata.pitchRate = fdm.thetadot * rad2deg;
                sitldata.yawRate = fdm.psidot * rad2deg;

                sitldata.speedN = fdm.v_north * ft2m;
                sitldata.speedE = fdm.v_east * ft2m;
                sitldata.speedD = fdm.v_down * ft2m;

                sitldata.xAccel = (fdm.A_X_pilot * 9.808 / 32.2); // pitch
                sitldata.yAccel = (fdm.A_Y_pilot * 9.808 / 32.2); // roll
                sitldata.zAccel = (fdm.A_Z_pilot / 32.2 * 9.808);

                sitldata.airspeed = fdm.vcas * 0.5144444f;//  knots to m/s

               // Console.WriteLine("1 {0} {1} {2} {3}",(float)sitldata.rollDeg,MainV2.comPort.MAV.cs.roll,sitldata.pitchDeg,MainV2.comPort.MAV.cs.pitch);

                if (RAD_JSBSim.Checked)
                    sitldata.airspeed = fdm.vcas * ft2m;//  fps to m/s
                 
            }
            else
            {
                log.Info("Bad Udp Packet " + receviedbytes);
                return;
            }

            if (sitldata.altitude < 0)
                sitldata.altitude = 0.00001;

            sitldata_old = sitldata;

            // write arduimu to ardupilot
            if (CHK_quad.Checked && !RAD_aerosimrc.Checked) // quad does its own
            {
                return;
            }

            if (RAD_JSBSim.Checked && chkSITL.Checked)
            {
                byte[] buffer = new byte[1500];
                while (JSBSimSEND.Client.Available > 5)
                {
                    int read = JSBSimSEND.Client.Receive(buffer);
                   // Console.WriteLine(ASCIIEncoding.ASCII.GetString(buffer,0,read));
                }

                sitldata.magic = (int)0x4c56414f;

                byte[] sendme = StructureToByteArray(sitldata);

                SITLSEND.Send(sendme, sendme.Length);

                return;
            }

            if (chkSITL.Checked)
            {
                sitldata.magic = (int)0x4c56414f;

                byte[] sendme = StructureToByteArray(sitldata);

                SITLSEND.Send(sendme, sendme.Length);
                
                return;
            }


            TimeSpan gpsspan = DateTime.Now - lastgpsupdate;

            // add gps delay
            if (gpsspan.TotalMilliseconds >= GPS_rate)
            {
                lastgpsupdate = DateTime.Now;

                // save current fix = 3
                sitl_fdmbuffer[gpsbufferindex % sitl_fdmbuffer.Length] = sitldata;

                //                Console.WriteLine((gpsbufferindex % gpsbuffer.Length) + " " + ((gpsbufferindex + (gpsbuffer.Length - 1)) % gpsbuffer.Length));

                // return buffer index + 5 = (3 + 5) = 8 % 6 = 2
                oldgps = sitl_fdmbuffer[(gpsbufferindex + (sitl_fdmbuffer.Length - 1)) % sitl_fdmbuffer.Length];

                //comPort.sendPacket(oldgps);

                gpsbufferindex++;
            }


            MAVLink.mavlink_hil_state_t hilstate = new MAVLink.mavlink_hil_state_t();

            DateTime epochBegin = new DateTime(1980, 1, 6, 0, 0, 0, DateTimeKind.Utc);
            hilstate.time_usec = (UInt64)((DateTime.Now.Ticks - epochBegin.Ticks) / 10); // microsec
            
            hilstate.lat = (int)(oldgps.latitude * 1e7); // * 1E7
            hilstate.lon = (int)(oldgps.longitude * 1e7); // * 1E7
            hilstate.alt = (int)(oldgps.altitude * 1000); // mm

         //   Console.WriteLine(hilstate.alt);

           // Console.WriteLine("{0} {1} {2}", sitldata.rollDeg.ToString("0.0"), sitldata.pitchDeg.ToString("0.0"), sitldata.yawDeg.ToString("0.0"));
            

            hilstate.pitch = (float)sitldata.pitchDeg * deg2rad; // (rad)
            hilstate.pitchspeed = (float)sitldata.pitchRate * deg2rad; // (rad/s)
            hilstate.roll = (float)sitldata.rollDeg * deg2rad; // (rad)
            hilstate.rollspeed = (float)sitldata.rollRate * deg2rad; // (rad/s)
            hilstate.yaw = (float)sitldata.yawDeg * deg2rad; // (rad)
            hilstate.yawspeed = (float)sitldata.yawRate * deg2rad; // (rad/s)
            
            hilstate.vx = (short)(sitldata.speedN * 100); // m/s * 100 - lat
            hilstate.vy = (short)(sitldata.speedE * 100); // m/s * 100 - long
            hilstate.vz = (short)(sitldata.speedD * 100); // m/s * 100 - + speed down

            hilstate.xacc = (short)(sitldata.xAccel * 101.957); // (mg)
            hilstate.yacc = (short)(sitldata.yAccel * 101.957); // (mg)
            hilstate.zacc = (short)(sitldata.zAccel * 101.957); // (mg)


            packetcount++;

            if (!comPort.BaseStream.IsOpen)
                return;

            if (comPort.BaseStream.BytesToWrite > 100)
                return;

          //  if (packetcount % 2 == 0) 
          //      return;

            comPort.sendPacket(hilstate);


            //            comPort.sendPacket(oldgps);

            //comPort.sendPacket(new MAVLink.mavlink_vfr_hud_t() { airspeed = (float)sitldata.airspeed } );

            MAVLink.mavlink_raw_pressure_t pres = new MAVLink.mavlink_raw_pressure_t();
            double calc = (101325 * Math.Pow(1 - 2.25577 * Math.Pow(10, -5) * sitldata.altitude, 5.25588)); // updated from valid gps
            pres.press_diff1 = (short)(int)(calc - 101325); // 0 alt is 0 pa

           // comPort.sendPacket(pres);
        }
コード例 #5
0
ファイル: XPlane.cs プロジェクト: RobertCL/MissionPlanner
        public override void GetFromSim(ref sitl_fdm sitldata)
        {
            if (SimulatorRECV.Available > 0)
            {
                byte[] udpdata = new byte[1500];
                int receviedbytes = 0;
                try
                {
                    while (SimulatorRECV.Available > 0)
                    {
                        receviedbytes = SimulatorRECV.ReceiveFrom(udpdata, ref Remote);
                    }
                }
                catch { }

                if (udpdata[0] == 'D' && udpdata[1] == 'A')
                {
                    // Xplanes sends
                    // 5 byte header
                    // 1 int for the index - numbers on left of output
                    // 8 floats - might be useful. or 0 if not
                    int count = 5;
                    while (count < receviedbytes)
                    {
                        int index = BitConverter.ToInt32(udpdata, count);

                        DATA[index] = new float[8];

                        DATA[index][0] = BitConverter.ToSingle(udpdata, count + 1 * 4); ;
                        DATA[index][1] = BitConverter.ToSingle(udpdata, count + 2 * 4); ;
                        DATA[index][2] = BitConverter.ToSingle(udpdata, count + 3 * 4); ;
                        DATA[index][3] = BitConverter.ToSingle(udpdata, count + 4 * 4); ;
                        DATA[index][4] = BitConverter.ToSingle(udpdata, count + 5 * 4); ;
                        DATA[index][5] = BitConverter.ToSingle(udpdata, count + 6 * 4); ;
                        DATA[index][6] = BitConverter.ToSingle(udpdata, count + 7 * 4); ;
                        DATA[index][7] = BitConverter.ToSingle(udpdata, count + 8 * 4); ;

                        count += 36; // 8 * float
                    }

                    bool xplane9 = !xplane10;

                    if (xplane9)
                    {
                        sitldata.pitchDeg = (DATA[18][0]);
                        sitldata.rollDeg = (DATA[18][1]);
                        sitldata.yawDeg = (DATA[18][2]);
                        sitldata.pitchRate = (DATA[17][0] * rad2deg);
                        sitldata.rollRate = (DATA[17][1] * rad2deg);
                        sitldata.yawRate = (DATA[17][2] * rad2deg);

                        sitldata.heading = ((float)DATA[19][2]);
                    }
                    else
                    {
                        sitldata.pitchDeg = (DATA[17][0]);
                        sitldata.rollDeg = (DATA[17][1]);
                        sitldata.yawDeg = (DATA[17][2]);
                        sitldata.pitchRate = (DATA[16][0] * rad2deg);
                        sitldata.rollRate = (DATA[16][1] * rad2deg);
                        sitldata.yawRate = (DATA[16][2] * rad2deg);

                        sitldata.heading = (DATA[18][2]);
                    }

                    sitldata.airspeed = ((DATA[3][5] * .44704));

                    sitldata.latitude = (DATA[20][0]);
                    sitldata.longitude = (DATA[20][1]);
                    sitldata.altitude = (DATA[20][2] * ft2m);

                    sitldata.speedN = DATA[21][3];// (DATA[3][7] * 0.44704 * Math.Sin(sitldata.heading * deg2rad));
                    sitldata.speedE = -DATA[21][5];// (DATA[3][7] * 0.44704 * Math.Cos(sitldata.heading * deg2rad));

                    Matrix3 dcm = new Matrix3();
                    dcm.from_euler(sitldata.rollDeg * deg2rad, sitldata.pitchDeg * deg2rad, sitldata.yawDeg * deg2rad);

                    // rad = tas^2 / (tan(angle) * G)
                    float turnrad = (float)(((DATA[3][7] * 0.44704) * (DATA[3][7] * 0.44704)) / (float)(9.8f * Math.Tan(sitldata.rollDeg * deg2rad)));

                    float gload = (float)(1 / Math.Cos(sitldata.rollDeg * deg2rad)); // calculated Gs

                    // a = v^2/r
                    float centripaccel = (float)((DATA[3][7] * 0.44704) * (DATA[3][7] * 0.44704)) / turnrad;

                    Vector3 accel_body = dcm.transposed() * (new Vector3(0, 0, -9.8));

                    Vector3 centrip_accel = new Vector3(0, centripaccel * Math.Cos(sitldata.rollDeg * deg2rad), centripaccel * Math.Sin(sitldata.rollDeg * deg2rad));

                    accel_body -= centrip_accel;

                    sitldata.xAccel = DATA[4][5] * 9.8;
                    sitldata.yAccel = DATA[4][6] * 9.8;
                    sitldata.zAccel = (0 - DATA[4][4]) * 9.8;

                    //      Console.WriteLine(accel_body.ToString());
                    //      Console.WriteLine("        {0} {1} {2}",sitldata.xAccel, sitldata.yAccel, sitldata.zAccel);

                }
            }
        }
コード例 #6
0
ファイル: Wind.cs プロジェクト: tinashanica/MissionPlanner
 //# Converts a magnitude and angle (radians) to a vector in the xy plane.
 public Vector3 toVec(double magnitude, double angle)
 {
     Vector3 v = new Vector3(magnitude, 0, 0);
     Matrix3 m = new Matrix3();
     m.from_euler(0, 0, angle);
     return m.transposed() * v;
 }
コード例 #7
0
ファイル: Matrix3.cs プロジェクト: ECain/MissionPlanner
 public Matrix3()
 {
     self = this;
     self.identity();
 }
コード例 #8
0
ファイル: Matrix3.cs プロジェクト: ECain/MissionPlanner
        public void rotate(Vector3 g)
        {
            //   '''rotate the matrix by a given amount on 3 axes'''
            Matrix3 temp_matrix = new Matrix3(self.a.copy(), self.b.copy(), self.c.copy());

            temp_matrix.a.x = a.y * g.z - a.z * g.y;
            temp_matrix.a.y = a.z * g.x - a.x * g.z;
            temp_matrix.a.z = a.x * g.y - a.y * g.x;
            temp_matrix.b.x = b.y * g.z - b.z * g.y;
            temp_matrix.b.y = b.z * g.x - b.x * g.z;
            temp_matrix.b.z = b.x * g.y - b.y * g.x;
            temp_matrix.c.x = c.y * g.z - c.z * g.y;
            temp_matrix.c.y = c.z * g.x - c.x * g.z;
            temp_matrix.c.z = c.x * g.y - c.y * g.x;
            self.a += temp_matrix.a;
            self.b += temp_matrix.b;
            self.c += temp_matrix.c;
        }
コード例 #9
0
        //http://www.chrobotics.com/library/understanding-euler-angles

        // x = north / roll
        // y = pitch / east
        // z = yaw / down

        public static List<PointLatLngAlt> calc(PointLatLngAlt plla, double R, double P, double Y, double hfov, double vfov)
        {
            // alt should be asl
            // P pitch where the center os pointing ie -80
            // R roll 

            GMapPolygon poly = new GMapPolygon(new List<PointLatLng>(), "rect");

            double frontangle = (P*0) + vfov/2;
            double backangle = (P*0) - vfov/2;
            double leftangle = (R*0) + hfov/2;
            double rightangle = (R*0) - hfov/2;

            var fovh = Math.Tan(hfov/2.0 * deg2rad)*2.0;
            var fovv = Math.Tan(vfov/2.0 * deg2rad)*2.0;

            //DoDebug();

            addtomap(plla, "plane");

            Matrix3 dcm = new Matrix3();

            dcm.from_euler(R * deg2rad, P * deg2rad, Y * deg2rad);
            dcm.normalize();

            Vector3 center1 = new Vector3(0, 0, 10000);

            var test = dcm * center1;

            var bearing2 = Math.Atan2(test.y, test.x) * rad2deg;

            var newpos2 = plla.newpos(bearing2, Math.Sqrt(test.x * test.x + test.y * test.y));

            newpos2.Alt -= test.z;

            var cen = calcIntersection(plla, newpos2);

            var dist = plla.GetDistance(cen);

            addtomap(cen, "center "+ dist.ToString("0"));

            //
            dcm.from_euler(R * deg2rad, P * deg2rad, Y * deg2rad);
            dcm.rotate(new Vector3(rightangle * deg2rad, 0, 0));
            dcm.normalize();
            dcm.rotate(new Vector3(0, frontangle * deg2rad, 0));
            dcm.normalize();

            test = dcm * center1;

            bearing2 = (Math.Atan2(test.y, test.x) * rad2deg);

            newpos2 = plla.newpos(bearing2, Math.Sqrt(test.x * test.x + test.y * test.y));

            newpos2.Alt -= test.z;

            //addtomap(newpos2, "tr2");

            var groundpointtr = calcIntersection(plla, newpos2);

            poly.Points.Add(groundpointtr);

            addtomap(groundpointtr, "tr");

            //
            dcm.from_euler(R * deg2rad, P * deg2rad, Y * deg2rad);
            dcm.rotate(new Vector3(leftangle * deg2rad, 0, 0));
            dcm.normalize();
            dcm.rotate(new Vector3(0, frontangle * deg2rad, 0));
            dcm.normalize();

            test = dcm * center1;

            bearing2 = Math.Atan2(test.y, test.x)*rad2deg;

            newpos2 = plla.newpos(bearing2, Math.Sqrt(test.x * test.x + test.y * test.y));

            newpos2.Alt -= test.z;

            var groundpointtl = calcIntersection(plla, newpos2);

            poly.Points.Add(groundpointtl);

            addtomap(groundpointtl, "tl");

            //
            dcm.from_euler(R * deg2rad, P * deg2rad, Y * deg2rad);
            dcm.rotate(new Vector3(leftangle * deg2rad, 0, 0));
            dcm.normalize();
            dcm.rotate(new Vector3(0, backangle * deg2rad, 0));
            dcm.normalize();

            test = dcm * center1;

            bearing2 = Math.Atan2(test.y, test.x) * rad2deg;

            newpos2 = plla.newpos(bearing2, Math.Sqrt(test.x * test.x + test.y * test.y));

            newpos2.Alt -= test.z;

            var groundpointbl = calcIntersection(plla, newpos2);

            poly.Points.Add(groundpointbl);

            addtomap(groundpointbl, "bl");

            //
            dcm.from_euler(R * deg2rad, P * deg2rad, Y * deg2rad);
            dcm.rotate(new Vector3(rightangle * deg2rad, 0, 0));
            dcm.normalize();
            dcm.rotate(new Vector3(0, backangle * deg2rad, 0));
            dcm.normalize();

            test = dcm * center1;

            bearing2 = Math.Atan2(test.y, test.x) * rad2deg;

            newpos2 = plla.newpos(bearing2, Math.Sqrt(test.x * test.x + test.y * test.y));

            newpos2.Alt -= test.z;

            var groundpointbr = calcIntersection(plla, newpos2);

            poly.Points.Add(groundpointbr);

            addtomap(groundpointbr, "br");

            //

            polygons.Polygons.Clear();
            polygons.Polygons.Add(poly);

            var ans = new List<PointLatLngAlt>();
            ans.Add(groundpointtl);
            ans.Add(groundpointtr);
            ans.Add(groundpointbr);
            ans.Add(groundpointbl);

            return ans;
        }
コード例 #10
0
 static void add_errors(Vector3 mag, Vector3 gyr, Vector3 last_mag, double deltat, double[] total_error,
     Rotation[] rotations)
 {
     foreach (var i in range(len(rotations)))
     {
         // if (!rotations[i].is_90_degrees())
         //    continue;
         Matrix3 r = rotations[i].r;
         Matrix3 m = new Matrix3();
         m.rotate(gyr*deltat);
         Vector3 rmag1 = r*last_mag;
         Vector3 rmag2 = r*mag;
         Vector3 rmag3 = m.transposed()*rmag1;
         Vector3 err = rmag3 - rmag2;
         total_error[i] += err.length();
     }
 }
コード例 #11
0
        //http://www.chrobotics.com/library/understanding-euler-angles

        // x = north / roll
        // y = pitch / east
        // z = yaw / down

        public static List<PointLatLngAlt> calc(PointLatLngAlt plla, double R, double P, double Y, double hfov, double vfov)
        {
            // alt should be asl
            // P pitch where the center os pointing ie -80
            // R roll 

            // if roll and pitch is 0, use the quick method.
            if (R == 0 && P == 0)
            {
                // calc fov in m on the ground at 0 alt
                var fovh = Math.Tan(hfov / 2.0 * deg2rad) * plla.Alt;
                var fovv = Math.Tan(vfov / 2.0 * deg2rad) * plla.Alt;
                var fovd = Math.Sqrt(fovh * fovh + fovv * fovv);

                // where we put our footprint
                var ans2 = new List<PointLatLngAlt>();

                // calc bearing from center to corner
                var bearing1 = Math.Atan2(fovh, fovv) * rad2deg;

                // calc first corner point
                var newpos1 = plla.newpos(bearing1 + Y, Math.Sqrt(fovh * fovh + fovv * fovv));
                // set alt to 0, as we used the hypot for distance and fov is based on 0 alt
                newpos1.Alt = 0;
                // calc intersection from center to new point and return ground hit point
                var cen1 = calcIntersection(plla, newpos1);
                // add to our footprint poly
                ans2.Add(cen1);
                addtomap(cen1, "cen1");

                //repeat

                newpos1 = plla.newpos(Y - bearing1, Math.Sqrt(fovh * fovh + fovv * fovv));
                newpos1.Alt = 0;
                cen1 = calcIntersection(plla, newpos1);
                ans2.Add(cen1);
                addtomap(cen1, "cen2");

                newpos1 = plla.newpos(bearing1 + Y - 180, Math.Sqrt(fovh * fovh + fovv * fovv));
                newpos1.Alt = 0;
                cen1 = calcIntersection(plla, newpos1);
                ans2.Add(cen1);
                addtomap(cen1, "cen3");

                newpos1 = plla.newpos(Y - bearing1 - 180, Math.Sqrt(fovh * fovh + fovv * fovv));
                newpos1.Alt = 0;
                cen1 = calcIntersection(plla, newpos1);
                ans2.Add(cen1);
                addtomap(cen1, "cen4");


                addtomap(plla, "plane");

                return ans2;
            }

            
            GMapPolygon poly = new GMapPolygon(new List<PointLatLng>(), "rect");

            double frontangle = (P*0) + vfov/2;
            double backangle = (P*0) - vfov/2;
            double leftangle = (R*0) + hfov/2;
            double rightangle = (R*0) - hfov/2;


            addtomap(plla, "plane");

            Matrix3 dcm = new Matrix3();

            dcm.from_euler(R * deg2rad, P * deg2rad, Y * deg2rad);
            dcm.normalize();

            Vector3 center1 = new Vector3(0, 0, 10000);

            var test = dcm * center1;

            var bearing2 = Math.Atan2(test.y, test.x) * rad2deg;

            var newpos2 = plla.newpos(bearing2, Math.Sqrt(test.x * test.x + test.y * test.y));

            newpos2.Alt -= test.z;

            var cen = calcIntersection(plla, newpos2);

            var dist = plla.GetDistance(cen);

            addtomap(cen, "center "+ dist.ToString("0"));

            //
            dcm.from_euler(R * deg2rad, P * deg2rad, Y * deg2rad);
            dcm.rotate(new Vector3(rightangle * deg2rad, 0, 0));
            dcm.normalize();
            dcm.rotate(new Vector3(0, frontangle * deg2rad, 0));
            dcm.normalize();
            /*
            var mx = new Matrix3();
            var my = new Matrix3();
            var mz = new Matrix3();

            mx.from_euler((rightangle + R) * deg2rad, 0, 0);
            my.from_euler(0, (frontangle + P) * deg2rad, 0);
            mz.from_euler(0, 0, Y * deg2rad);

            printdcm(mx);
            printdcm(my);
            printdcm(mz);
            printdcm(my * mx);
            printdcm(mz * my * mx);

            test = mz * my * mx * center1;
            */
            test = dcm * center1;  
              
            bearing2 = (Math.Atan2(test.y, test.x) * rad2deg);

            newpos2 = plla.newpos(bearing2, Math.Sqrt(test.x * test.x + test.y * test.y));

            newpos2.Alt -= test.z;

            //addtomap(newpos2, "tr2");

            var groundpointtr = calcIntersection(plla, newpos2);

            poly.Points.Add(groundpointtr);

            addtomap(groundpointtr, "tr");

            //
            dcm.from_euler(R * deg2rad, P * deg2rad, Y * deg2rad);
            dcm.rotate(new Vector3(leftangle * deg2rad, 0, 0));
            dcm.normalize();
            dcm.rotate(new Vector3(0, frontangle * deg2rad, 0));
            dcm.normalize();

            test = dcm * center1;

            bearing2 = Math.Atan2(test.y, test.x)*rad2deg;

            newpos2 = plla.newpos(bearing2, Math.Sqrt(test.x * test.x + test.y * test.y));

            newpos2.Alt -= test.z;

            var groundpointtl = calcIntersection(plla, newpos2);

            poly.Points.Add(groundpointtl);

            addtomap(groundpointtl, "tl");

            //
            dcm.from_euler(R * deg2rad, P * deg2rad, Y * deg2rad);
            dcm.rotate(new Vector3(leftangle * deg2rad, 0, 0));
            dcm.normalize();
            dcm.rotate(new Vector3(0, backangle * deg2rad, 0));
            dcm.normalize();

            test = dcm * center1;

            bearing2 = Math.Atan2(test.y, test.x) * rad2deg;

            newpos2 = plla.newpos(bearing2, Math.Sqrt(test.x * test.x + test.y * test.y));

            newpos2.Alt -= test.z;

            var groundpointbl = calcIntersection(plla, newpos2);

            poly.Points.Add(groundpointbl);

            addtomap(groundpointbl, "bl");

            //
            dcm.from_euler(R * deg2rad, P * deg2rad, Y * deg2rad);
            dcm.rotate(new Vector3(rightangle * deg2rad, 0, 0));
            dcm.normalize();
            dcm.rotate(new Vector3(0, backangle * deg2rad, 0));
            dcm.normalize(); 

            test = dcm * center1;

            bearing2 = Math.Atan2(test.y, test.x) * rad2deg;

            newpos2 = plla.newpos(bearing2, Math.Sqrt(test.x * test.x + test.y * test.y));

            newpos2.Alt -= test.z;

            var groundpointbr = calcIntersection(plla, newpos2);

            poly.Points.Add(groundpointbr);

            addtomap(groundpointbr, "br");

            //

            polygons.Polygons.Clear();
            polygons.Polygons.Add(poly);

            var ans = new List<PointLatLngAlt>();
            ans.Add(groundpointtl);
            ans.Add(groundpointtr);
            ans.Add(groundpointbr);
            ans.Add(groundpointbl);

            return ans;
        }
コード例 #12
0
        private static void printdcm(Matrix3 dcm)
        {
            double R = 0;
            double P = 0;
            double Y = 0;

            dcm.to_euler(ref R, ref P, ref Y);

            Console.WriteLine("{0} {1} {2}", R * rad2deg, P * rad2deg, Y * rad2deg);
        }
コード例 #13
0
ファイル: MagCalib.cs プロジェクト: ArduPilot/MissionPlanner
 static double radius(Vector3 mag, Vector3 offsets, Vector3 diagonals, Vector3 offdiagonals)
 {
     //'''return radius give data point and offsets'''
     Vector3 mag2 = mag + offsets;
     var rot = new Matrix3(new Vector3(diagonals.x, offdiagonals.x, offdiagonals.y),
         new Vector3(offdiagonals.x, diagonals.y, offdiagonals.z),
         new Vector3(offdiagonals.y, offdiagonals.z, diagonals.z));
     mag2 = rot*mag2;
     return mag2.length();
 }
コード例 #14
0
        public override void GetFromSim(ref sitl_fdm sitldata)
        {
            if (SimulatorRECV.Available > 0)
            {
                byte[] udpdata       = new byte[1500];
                int    receviedbytes = 0;
                try
                {
                    while (SimulatorRECV.Available > 0)
                    {
                        receviedbytes = SimulatorRECV.ReceiveFrom(udpdata, ref Remote);
                    }
                }
                catch
                {
                }

                if (udpdata[0] == 'D' && udpdata[1] == 'A')
                {
                    // Xplanes sends
                    // 5 byte header
                    // 1 int for the index - numbers on left of output
                    // 8 floats - might be useful. or 0 if not
                    int count = 5;
                    while (count < receviedbytes)
                    {
                        int index = BitConverter.ToInt32(udpdata, count);

                        DATA[index] = new float[8];

                        DATA[index][0] = BitConverter.ToSingle(udpdata, count + 1 * 4);
                        ;
                        DATA[index][1] = BitConverter.ToSingle(udpdata, count + 2 * 4);
                        ;
                        DATA[index][2] = BitConverter.ToSingle(udpdata, count + 3 * 4);
                        ;
                        DATA[index][3] = BitConverter.ToSingle(udpdata, count + 4 * 4);
                        ;
                        DATA[index][4] = BitConverter.ToSingle(udpdata, count + 5 * 4);
                        ;
                        DATA[index][5] = BitConverter.ToSingle(udpdata, count + 6 * 4);
                        ;
                        DATA[index][6] = BitConverter.ToSingle(udpdata, count + 7 * 4);
                        ;
                        DATA[index][7] = BitConverter.ToSingle(udpdata, count + 8 * 4);
                        ;

                        count += 36; // 8 * float
                    }

                    bool xplane9 = !xplane10;

                    if (xplane9)
                    {
                        sitldata.pitchDeg  = (DATA[18][0]);
                        sitldata.rollDeg   = (DATA[18][1]);
                        sitldata.yawDeg    = (DATA[18][2]);
                        sitldata.pitchRate = (DATA[17][0] * MathHelper.rad2deg);
                        sitldata.rollRate  = (DATA[17][1] * MathHelper.rad2deg);
                        sitldata.yawRate   = (DATA[17][2] * MathHelper.rad2deg);

                        sitldata.heading = ((float)DATA[19][2]);
                    }
                    else
                    {
                        sitldata.pitchDeg  = (DATA[17][0]);
                        sitldata.rollDeg   = (DATA[17][1]);
                        sitldata.yawDeg    = (DATA[17][2]);
                        sitldata.pitchRate = (DATA[16][0] * MathHelper.rad2deg);
                        sitldata.rollRate  = (DATA[16][1] * MathHelper.rad2deg);
                        sitldata.yawRate   = (DATA[16][2] * MathHelper.rad2deg);

                        sitldata.heading = (DATA[18][2]);
                    }

                    sitldata.airspeed = ((DATA[3][5] * .44704));

                    sitldata.latitude  = (DATA[20][0]);
                    sitldata.longitude = (DATA[20][1]);
                    sitldata.altitude  = (DATA[20][2] * ft2m);

                    sitldata.speedN = DATA[21][3];  // (DATA[3][7] * 0.44704 * Math.Sin(sitldata.heading * MathHelper.deg2rad));
                    sitldata.speedE = -DATA[21][5]; // (DATA[3][7] * 0.44704 * Math.Cos(sitldata.heading * MathHelper.deg2rad));

                    Matrix3 dcm = new Matrix3();
                    dcm.from_euler(sitldata.rollDeg * MathHelper.deg2rad, sitldata.pitchDeg * MathHelper.deg2rad, sitldata.yawDeg * MathHelper.deg2rad);

                    // rad = tas^2 / (tan(angle) * G)
                    float turnrad =
                        (float)
                        (((DATA[3][7] * 0.44704) * (DATA[3][7] * 0.44704)) /
                         (float)(9.8f * Math.Tan(sitldata.rollDeg * MathHelper.deg2rad)));

                    float gload = (float)(1 / Math.Cos(sitldata.rollDeg * MathHelper.deg2rad)); // calculated Gs

                    // a = v^2/r
                    float centripaccel = (float)((DATA[3][7] * 0.44704) * (DATA[3][7] * 0.44704)) / turnrad;

                    Vector3 accel_body = dcm.transposed() * (new Vector3(0, 0, -9.8));

                    Vector3 centrip_accel = new Vector3(0, centripaccel * Math.Cos(sitldata.rollDeg * MathHelper.deg2rad),
                                                        centripaccel * Math.Sin(sitldata.rollDeg * MathHelper.deg2rad));

                    accel_body -= centrip_accel;

                    sitldata.xAccel = DATA[4][5] * 9.8;
                    sitldata.yAccel = DATA[4][6] * 9.8;
                    sitldata.zAccel = (0 - DATA[4][4]) * 9.8;

                    //      Console.WriteLine(accel_body.ToString());
                    //      Console.WriteLine("        {0} {1} {2}",sitldata.xAccel, sitldata.yAccel, sitldata.zAccel);
                }
            }
        }
コード例 #15
0
ファイル: Matrix3.cs プロジェクト: OOP-03376400/DF_GCS_W
 public Matrix3()
 {
     self = this;
     self.identity();
 }