예제 #1
0
        /// <summary>
        /// Partial initialisation function
        /// Calculates the state vector  \vct{y}_{pi}  and Jacobians for a new
        /// partially-initialised feature from an initial observation.
        /// @param hi The initial measurement  \vct{h}_i , in this case the (x,y)
        ///  image location of the feature.
        /// </summary>
        /// <param name="hi"></param>
        /// <param name="xp">The robot position state  \vct{x}_p  from which the initial observation was made.</param>
        public override void func_ypi_and_dypi_by_dxp_and_dypi_by_dhi_and_Ri(Vector hi, Vector xp)
        {
            // Representation of a line here:
            // ypi = (rWi    )
            //       (hLhatWi)

            // Form the ray (in camera co-ordinates by unprojecting this image location
            Vector3D hLRi = new Vector3D(((Wide_Camera_Point_Feature_Measurement_Model)wide_model).m_camera.Unproject(hi));
  
            //if (Camera_Constants.DEBUGDUMP) Debug.WriteLine("debug hLRi");

            // Form hLhatRi from hLRi
            // Normalise
            Vector3D hLhatRi = hLRi;
            hLhatRi.Normalise();

            MatrixFixed dhLhatRi_by_dhLRi = MatrixFixed.dvnorm_by_dv(hLRi); 

            //if (Camera_Constants.DEBUGDUMP) Debug.WriteLine("debug hLhatRi" + hLhatRi);

            // Now convert this into a direction in world co-ordinates by rotating
            // Form hLhatWi from hLhatRi
            // Rotate
            ((Wide_Camera_Point_Feature_Measurement_Model)wide_model).threed_motion_model.func_q(xp);
            RotationMatrix RWR = ((Wide_Camera_Point_Feature_Measurement_Model)wide_model).threed_motion_model.get_qRES().RotationMatrix();
            Vector3D hLhatWi = new Vector3D(RWR * hLhatRi);

            //if (Camera_Constants.DEBUGDUMP) Debug.WriteLine("debug hLhatWi" + hLhatWi);

            // Extract rW from xp
            ((Wide_Camera_Point_Feature_Measurement_Model)wide_model).threed_motion_model.func_r(xp);
 
            // And form ypiRES
            ypiRES.Update(((Wide_Camera_Point_Feature_Measurement_Model)wide_model).threed_motion_model.get_rRES().GetVNL3(), 0);
            ypiRES.Update(hLhatWi.GetVNL3(), 3);

            //if (Camera_Constants.DEBUGDUMP) Debug.WriteLine("debug ypiRES" + ypiRES);

            // Form Jacobians dypi_by_dxp and dypi_by_dhi

            // dypi_by_dxp = (drWi_by_dr     drWi_by_dq    )
            //               (dhLhatWi_by_dr dhLhatWi_by_dq)
            //             = (I              0             )
            //               (0              dhLhatWi_by_dq)

            // hLhatWi = RWR * hLhatRi
            // => dhLhatWi_by_dq = d/dq ( R(qWR) * hLhatRi)

            MatrixFixed dhLhatWi_by_dq = MatrixFixed.dRq_times_a_by_dq(((Wide_Camera_Point_Feature_Measurement_Model)wide_model).threed_motion_model.get_qRES(), hLhatRi);

            // Put dypi_by_dxp together
            dypi_by_dxpRES.Fill(0.0f);
            dypi_by_dxpRES.Put(0, 0, 1.0f);
            dypi_by_dxpRES.Put(1, 1, 1.0f);
            dypi_by_dxpRES.Put(2, 2, 1.0f);
            dypi_by_dxpRES.Update(dhLhatWi_by_dq, 3, 3);

            //  cout << "dypi_by_dxpRES" <<  dypi_by_dxpRES;


            // dypi_by_dhi = (drWi_by_dhi    )
            //               (dhLhatWi_by_dhi)
            //             = (0              )
            //               (dhLhatWi_by_dhi)

            // hLhatWi = RWR * hLhatRi
            // Need to work out derivative for this
            // dhLhatWi_by_dhi = RWR * dhLhatRi_by_dhLRi * dhLRi_by_dhi

            MatrixFixed dhLhatWi_by_dhi = RWR * dhLhatRi_by_dhLRi * ((Wide_Camera_Point_Feature_Measurement_Model)wide_model).m_camera.UnprojectionJacobian();
  
            dypi_by_dhiRES.Fill(0.0f);
            dypi_by_dhiRES.Update(dhLhatWi_by_dhi, 3, 0);

            //  cout << "dypi_by_dhiRES" <<  dypi_by_dhiRES;

            // And construct Ri
            func_Ri(hi);

            /*
            if (Camera_Constants.DEBUGDUMP) Debug.WriteLine("func_ypi: hi = " + hi + "," +
                                           "xp = " + xp + "," +
                                           "ypiRES = " + ypiRES);
             */
        }
예제 #2
0
        public override void func_zeroedyi_and_dzeroedyi_by_dxp_and_dzeroedyi_by_dyi(Vector yi, Vector xp)
        {
            Wide_Camera_Point_Feature_Measurement_Model wm = (Wide_Camera_Point_Feature_Measurement_Model)wide_model;

            // Extract cartesian and quaternion components of xp
            wm.threed_motion_model.func_r(xp);
            wm.threed_motion_model.func_q(xp);

            // Extract ri and hhati components of yi = ypi
            func_ri(yi);
            func_hhati(yi);

            // ri part: transformation is just the same as in the normal point case
            // zeroedri = RRW(rWi - rW)  //commented out in original code

            // ri - r
            Vector3D yWiminusrW = new Vector3D(riRES - wm.threed_motion_model.get_rRES());

            Quaternion qRW = wm.threed_motion_model.get_qRES().Inverse();
            MatrixFixed dqRW_by_dq = MatrixFixed.dqbar_by_dq();

            // Rotation RRW
            RotationMatrix RRW = qRW.RotationMatrix();

            // RRW(rWi - rW)
            Vector3D zeroedri = new Vector3D(RRW * yWiminusrW);

            // Now calculate Jacobians
            // dzeroedri_by_dri is RRW
            // dzeroedri_by_dhhati = 0
            MatrixFixed dzeroedri_by_dri = new MatrixFixed(RRW);

            // dzeroedyi_by_dxp:
            // dzeroedri_by_dr = -RRW
            // dzeroedri_by_dq = d_dq(RRW (ri - r))
            MatrixFixed dzeroedri_by_dr = RRW * -1.0f;

            MatrixFixed dzeroedri_by_dqRW = MatrixFixed.dRq_times_a_by_dq(qRW, yWiminusrW);
            MatrixFixed dzeroedri_by_dq = dzeroedri_by_dqRW * dqRW_by_dq;

            // Now for the hhati part (easier...)
            // zeroedhhati = RRW hhati
            Vector3D zeroedhhati = new Vector3D(RRW * hhatiRES);

            // Jacobians
            // dzeroedhhati_by_dr = 0
            // dzeroedhhati_by_dq = d_dq(RRW hhati)
            // dzeroedhhati_by_dhhati = RRW
            // dzeroedhhati_by_dri = 0
            MatrixFixed dzeroedhhati_by_dqRW = MatrixFixed.dRq_times_a_by_dq(qRW, hhatiRES);
            MatrixFixed dzeroedhhati_by_dq = dzeroedhhati_by_dqRW * dqRW_by_dq;
            MatrixFixed dzeroedhhati_by_dhhati = new MatrixFixed(RRW);

            // And put it all together
            zeroedyiRES.Update(zeroedri.GetVNL3(), 0);
            zeroedyiRES.Update(zeroedhhati.GetVNL3(), 3);

            //cout << "Line: zeroedri = " << zeroedri << "zeroedhhati = " << zeroedhhati;

            dzeroedyi_by_dxpRES.Fill(0.0f);
            dzeroedyi_by_dxpRES.Update(dzeroedri_by_dr, 0, 0);
            dzeroedyi_by_dxpRES.Update(dzeroedri_by_dq, 0, 3);
            dzeroedyi_by_dxpRES.Update(dzeroedhhati_by_dq, 3, 3);

            dzeroedyi_by_dyiRES.Fill(0.0f);
            dzeroedyi_by_dyiRES.Update(dzeroedri_by_dri, 0, 0);
            dzeroedyi_by_dyiRES.Update(dzeroedhhati_by_dhhati, 3, 3);
              
            
        }
예제 #3
0
        public override void func_zeroedyi_and_dzeroedyi_by_dxp_and_dzeroedyi_by_dyi(Vector yi, Vector xp)
        {
            ThreeD_Motion_Model mm = ((Wide_Camera_Point_Feature_Measurement_Model)wide_model).threed_motion_model;

            // Extract cartesian and quaternion components of xp
            mm.func_r(xp);
            mm.func_q(xp);

            Vector3D yWiminusrW = new Vector3D((new Vector3D(yi)) -(mm.get_rRES()));

            Quaternion qRES = mm.get_qRES();
            Quaternion qRW = qRES.Inverse();
            MatrixFixed dqRW_by_dq = MatrixFixed.dqbar_by_dq();

            // Rotation RRW
            RotationMatrix RRW = qRW.RotationMatrix();

            // Position of feature relative to robot in robot frame
            Vector3D zeroedyi = new Vector3D(RRW * yWiminusrW);
            zeroedyiRES.Update(zeroedyi.GetVNL3());

            // Now calculate Jacobians
            // dzeroedyi_by_dyi is RRW
            dzeroedyi_by_dyiRES.Update(RRW);

            // dzeroedyi_by_dxp has 2 partitions:
            // dzeroedyi_by_dr (3 * 3)
            // dzeroedyi_by_dq (3 * 4)
            MatrixFixed dzeroedyi_by_dr = (MatrixFixed)(RRW);
            dzeroedyi_by_dr *= -1.0f;

            //These should be 3x4 dimension
            MatrixFixed dzeroedyi_by_dqRW = MatrixFixed.dRq_times_a_by_dq(qRW, yWiminusrW);
            MatrixFixed dzeroedyi_by_dq = dzeroedyi_by_dqRW * dqRW_by_dq;

            dzeroedyi_by_dxpRES.Update(dzeroedyi_by_dr, 0, 0);
            dzeroedyi_by_dxpRES.Update(dzeroedyi_by_dq, 0, 3);
        }
예제 #4
0
        /// <summary>
        /// Create a state vector x_v from its component parts. Puts the matrices r, q, v, omega into their right places.
        /// </summary>
        /// <param name="r"></param>
        /// <param name="q"></param>
        /// <param name="v"></param>
        /// <param name="omega"></param>
        /// <param name="xv"></param>
        public void compose_xv(ref Vector3D r, ref Quaternion q, ref Vector3D v, ref Vector3D omega, ref Vector xv)
        {  
            xv.Update(r.GetVNL3(), 0);

            xv.Update(q.GetRXYZ(), 3);

            xv.Update(v.GetVNL3(), 7);
   
            xv.Update(omega.GetVNL3(), 10);
        }
예제 #5
0
        // Function to find a region in an image guided by current motion prediction
        // which doesn't overlap existing features
        public static bool FindNonOverlappingRegion(Scene_Single scene,
                  Vector local_u,
                  float delta_t,
                  Partially_Initialised_Feature_Measurement_Model default_feature_type_for_initialisation,
                  uint camera_width,
                  uint camera_height,
                  uint BOXSIZE,
                  ref int init_feature_search_ustart,
                  ref int init_feature_search_vstart,
                  ref int init_feature_search_ufinish,
                  ref int init_feature_search_vfinish,
                  uint FEATURE_INIT_STEPS_TO_PREDICT,
                  float FEATURE_INIT_DEPTH_HYPOTHESIS,
                  Random rnd)
        {
            
            ThreeD_Motion_Model threed_motion_model = (ThreeD_Motion_Model)scene.get_motion_model();

            Vector local_xv = new Vector(scene.get_xv());
            
            for (uint i = 0; i < FEATURE_INIT_STEPS_TO_PREDICT; i++)
            {
                scene.get_motion_model().func_fv_and_dfv_by_dxv(local_xv, local_u, delta_t);
                local_xv.Update(scene.get_motion_model().get_fvRES());
            }
            
            threed_motion_model.func_xp(local_xv);
            Vector local_xp = new Vector(threed_motion_model.get_xpRES());

            threed_motion_model.func_r(local_xp);
            Vector3D rW = threed_motion_model.get_rRES();
            threed_motion_model.func_q(local_xp);
            Quaternion qWR = threed_motion_model.get_qRES();

            // yW =  rW + RWR hR
            Vector3D hR = new Vector3D(0.0f, 0.0f, FEATURE_INIT_DEPTH_HYPOTHESIS);

            // Used Inverse + transpose because this was't compiling the normal way
            Vector3D yW = new Vector3D(rW + qWR.RotationMatrix() * hR);

            // Then project that point into the current camera position
            scene.get_motion_model().func_xp(scene.get_xv());

            Fully_Initialised_Feature_Measurement_Model fully_init_fmm =
                (Fully_Initialised_Feature_Measurement_Model)(default_feature_type_for_initialisation.more_initialised_feature_measurement_model);


            Vector yWVNL = yW.GetVNL3();
            fully_init_fmm.func_hi_and_dhi_by_dxp_and_dhi_by_dyi(yWVNL, scene.get_motion_model().get_xpRES());

            // Now, this defines roughly how much we expect a feature initialised to move
            float suggested_u = fully_init_fmm.get_hiRES()[0];
            float suggested_v = fully_init_fmm.get_hiRES()[1];
            float predicted_motion_u = camera_width / 2.0f - suggested_u;
            float predicted_motion_v = camera_height / 2.0f - suggested_v;

            // So, the limits of a "safe" region within which we can initialise
            // features so that they end up staying within the screen
            // (Making the approximation that the whole screen moves like the 
            // centre point)
            int safe_feature_search_ustart = (int)(-predicted_motion_u);
            int safe_feature_search_vstart = (int)(-predicted_motion_v);
            int safe_feature_search_ufinish = (int)(camera_width - predicted_motion_u);
            int safe_feature_search_vfinish = (int)(camera_height - predicted_motion_v);

            if (safe_feature_search_ustart < ((int)((BOXSIZE - 1) / 2) + 1))
                safe_feature_search_ustart = (int)((BOXSIZE - 1) / 2 + 1);
            if (safe_feature_search_ufinish > (int)camera_width - ((int)((BOXSIZE - 1) / 2) + 1))
                safe_feature_search_ufinish = (int)(camera_width - (BOXSIZE - 1) / 2 - 1);
            if (safe_feature_search_vstart < ((int)((BOXSIZE - 1) / 2) + 1))
                safe_feature_search_vstart = (int)((BOXSIZE - 1) / 2 + 1);
            if (safe_feature_search_vfinish > (int)camera_height - ((int)((BOXSIZE - 1) / 2) + 1))
                safe_feature_search_vfinish = (int)(camera_height - (BOXSIZE - 1) / 2 - 1);

            return FindNonOverlappingRegionNoPredict(safe_feature_search_ustart,
                       safe_feature_search_vstart,
                       safe_feature_search_ufinish,
                       safe_feature_search_vfinish,
                       scene,
                       ref init_feature_search_ustart,
                       ref init_feature_search_vstart,
                       ref init_feature_search_ufinish,
                       ref init_feature_search_vfinish, rnd);
        }
예제 #6
0
        public override void func_xpredef_and_dxpredef_by_dxp_and_dxpredef_by_dxpdef  
                    (Vector xp, Vector xpdef)
        {
            // Split position state into cartesian and quaternion

            // r0, q0: position in original frame
            func_r(xp);
            func_q(xp);
            Vector3D r0 = rRES;
            Quaternion q0 = qRES;

            // rn, qn: definition of new frame
            func_r(xpdef);
            func_q(xpdef);
            Vector3D rn = rRES;
            Quaternion qn = qRES;

            Quaternion qnbar = qn.Conjugate();

            // Calculate new cartesian part of xp
            Vector3D Temp31a = new Vector3D(r0 - rn); // Temp31a is r0 - rn
            RotationMatrix Temp33a = qnbar.RotationMatrix();
            Vector3D Temp31b = new Vector3D(Temp33a * Temp31a);

            // Copy into xpredefRES
            xpredefRES[0] = Temp31b.GetX();
            xpredefRES[1] = Temp31b.GetY();
            xpredefRES[2] = Temp31b.GetZ();

            // Calculate new quaternion part of xp
            Quaternion Tempqa = qnbar.Multiply(q0);

            // Copy into xpredefRES
            Vector vecTempqa = Tempqa.GetRXYZ();
            xpredefRES.Update(vecTempqa, 3);

            // Form Jacobian dxpredef_by_dxpRES
            dxpredef_by_dxpRES.Fill(0.0f);
            dxpredef_by_dxpRES.Update(Temp33a, 0, 0);

            MatrixFixed Temp44a = MatrixFixed.dq3_by_dq1(qnbar);
            dxpredef_by_dxpRES.Update(Temp44a, 3, 3);

            // Form Jacobian dxpredef_by_dxpdefRES
            dxpredef_by_dxpdefRES.Fill(0.0f);
            //Temp33a *= -1.0f;
            Temp33a = (RotationMatrix)(Temp33a  * - 1.0f);
            dxpredef_by_dxpdefRES.Update(Temp33a, 0, 0);

            Temp44a = MatrixFixed.dq3_by_dq2(q0);

            MatrixFixed Temp44b = MatrixFixed.dqbar_by_dq();
            MatrixFixed Temp44c = Temp44a * Temp44b;
            dxpredef_by_dxpdefRES.Update(Temp44c, 3, 3);

            // Top right corner of this Jacobian is tricky because we have to
            // differentiate a rotation matrix
            // Uses function that does this in bits.cc
            // Build this corner in Temp34a
            //MatrixFixed temp = new MatrixFixed(3,4);
            MatrixFixed Temp34a = MatrixFixed.dRq_times_a_by_dq(qnbar, Temp31a.GetVNL3());

            // So far we have drN_by_dqnbar; want _by_dqn
            MatrixFixed Temp34b = Temp34a * Temp44b;

            // Finally copy into result matrix
            dxpredef_by_dxpdefRES.Update(Temp34b, 0, 3);

            // cout << "dxpredef_by_dxpdefRES" << dxpredef_by_dxpdefRES;
        }