Mobile camera recognition to achieve ar ranging (AR ruler)

Posted by deezzer on Fri, 04 Mar 2022 05:55:53 +0100

[example introduction] mobile camera recognition can realize ar ranging. At least three years of development experience can make it through

[example screenshot]


File: 590m.com/f/25127180-490561034-8afed0 (access password: 551685)

[core code]

using UnityEngine;
using UnityEngine.XR.ARFoundation;

///Ar ruler AR function management
public class ARRulerFoundtion: ARObjectSceneBase
{
///Determine whether the plane is recognized
private bool m_IsPlaneChanged = false;

///< summary > sight model < / summary >
private GameObject m_TakeAim;
///< summary > screen center position < / summary >
private Vector2 m_ScreenCenter;


/// <summary>Awake</summary>
public override void OnAwake()
{
    base.OnAwake();

    m_ScreenCenter = new Vector2(Screen.width / 2, Screen.height / 2);
    m_TakeAim = Instantiate(Resources.Load("Prefabs/TakeAim") as GameObject, transform);
    m_TakeAim.name = "TakeAim";
    m_TakeAim.SetActive(false);
}

/// <summary>Update</summary>
public override void OnUpdate()
{
    base.OnUpdate();
    if (isSupportAR) Raycast(m_ScreenCenter, UpdateTakeAimPosition);
}

///< summary > ar initialization completed < / summary >
public override void OnInitARFinish()
{
    base.OnInitARFinish();
    Debug.Log(GetType() "/InitARFinish()/initialization AR Done!");

    ARRulerSceneManager.Instance.uIManager.FindPanelPanelSetActive(true);

    planeEffectManager.SetAllPlanesActive(false);
}

///< summary > plane recognition sending change < / summary >
public override void OnPlanesChanged(ARPlanesChangedEventArgs obj)
{
    base.OnPlanesChanged(obj);
    if (m_IsPlaneChanged) return;
    m_IsPlaneChanged = true;

    ARRulerSceneManager.Instance.uIManager.ButtonsPanelSetActive(true);
    ARRulerSceneManager.Instance.uIManager.FindPanelPanelSetActive(false);
}

///< summary > update the position information of the sight < / summary >
private void UpdateTakeAimPosition(bool hit, ARRaycastHit aRRaycastHit)
{
    m_TakeAim.SetActive(hit);

    ARRulerSceneManager.Instance.uIManager.AddButtonInteractable(hit);
    ARRulerSceneManager.Instance.uIManager.TakePhotosButtonInteractable(hit);

    if (hit)
    {
        m_TakeAim.transform.position = aRRaycastHit.pose.position;
        m_TakeAim.transform.rotation = aRRaycastHit.pose.rotation;

        Vector3 size = Vector3.one;
        float value = 1;
        if (aRRaycastHit.distance < 1) value = 3.3f;
        else if (aRRaycastHit.distance < 2) value = 4;
        else value = aRRaycastHit.distance * 2;
        m_TakeAim.transform.localScale = size * value;
    }
}

The following are irrelevant:

-------------------------------------------Split line---------------------------------------------

Previously, we have a good understanding of the Dummy Cycle setting of IS25WP series Flash. Is IS25LP series Flash the same design? Let's check the IS25LP064A data manual to confirm.

We find the following table corresponding to the maximum operating frequency of read dummy cycles. From the table, we can see that when IS25LP works in Fast Read Quad I/O mode, the maximum operating frequency applicable to the default six dummy cycles is 104MHz (which is consistent with IS25WP Series), However, different from the IS25WP series, the IS25LP series Dummy Cycle has only four gears (2bit setting, corresponding to four values of 4 / 6 / 8 / 10), while the IS25WP series Dummy Cycle has fifteen gears (4bit setting, corresponding to values of 1-15), so the Dummy Cycle design is actually a simplified version on the IS25LP.

2, How to change the Dummy Cycle in Flash?
Aware of the differences between IS25LP and IS25WP in the design of Dummy Cycle, it is easy to change. Let's continue to look at the Flash data manual. IS25LP064A has an 8-bit Read Register inside. Its bit4-bit3 is the Dummy Cycles setting (reduced design I). The register type indicates only one attribute of volatility (reduced Design II).

In the instruction set table of IS25LP064A, you can see the instruction for writing Read Register, that is, SRP instruction. Note that the instruction value is the only 0xC0 (reduced Design III).

From the analysis here, it is impossible to modify the Dummy Cycle with additional small projects. i.MXRT can only change the Dummy Cycle of Flash with the SRP command directly with the help of the settings in the FDCB startup header every time it is started, as shown below:

//Sets the number of dummy cycles
#define FLASH_DUMMY_CYCLES 8
#define FLASH_DUMMY_VALUE 0x2
//Write the index of Read Register timing in LUT (the position can be customized, but do not occupy several timing positions preset by BootROM)
#define CMD_LUT_SEQ_IDX_SET_READ_PARAM 7
//index of LUT command timing preset in BootROM
#define CMD_LUT_SEQ_IDX_READ 0
#define CMD_LUT_SEQ_IDX_READSTATUS 1
#define CMD_LUT_SEQ_IDX_WRITEENABLE 3

const flexspi_nor_config_t qspiflash_config = {
.memConfig =
{
.tag = FLEXSPI_CFG_BLK_TAG,
.version = FLEXSPI_CFG_BLK_VERSION,
.readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad,
.csHoldTime = 3u,
.csSetupTime = 3u,
// Enable Safe configuration
.controllerMiscOption = 0x10,
.deviceType = kFlexSpiDeviceType_SerialNOR,
.sflashPadType = kSerialFlash_4Pads,
.serialClkFreq = kFlexSpiSerialClk_133MHz,
.sflashA1Size = 8u * 1024u * 1024u,
//Enable Flash register configuration operation
.configCmdEnable = 1u,
.configModeType[0] = kDeviceConfigCmdType_Generic,
//Indicates that the Flash register configuration timing is in the LUT
.configCmdSeqs[0] =
{
.seqNum = 1,
.seqId = CMD_LUT_SEQ_IDX_SET_READ_PARAM,
.reserved = 0,
},
//Set the configuration value of Flash register (here is the value written to Read Register)
//Note1: the value of Read Register written here is different between IS25WP series and IS25LP series
.configCmdArgs[0] = FLASH_DUMMY_VALUE << 3,
.lookupTable =
{
// Fast Read Quad I/O
[4CMD_LUT_SEQ_IDX_READ] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),
[4CMD_LUT_SEQ_IDX_READ + 1] = FLEXSPI_LUT_SEQ(MODE8_SDR, FLEXSPI_4PAD, 0x00, DUMMY_SDR, FLEXSPI_4PAD, FLASH_DUMMY_CYCLES-2),
[4*CMD_LUT_SEQ_IDX_READ + 2] = FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0x00),

                // READ STATUS REGISTER
                [4*CMD_LUT_SEQ_IDX_READSTATUS]         = FLEXSPI_LUT_SEQ(CMD_SDR,   FLEXSPI_1PAD, 0x05, READ_SDR,  FLEXSPI_1PAD, 0x01),
                [4*CMD_LUT_SEQ_IDX_READSTATUS + 1]     = FLEXSPI_LUT_SEQ(STOP,      FLEXSPI_1PAD, 0x00, 0, 0, 0),
               
                // WRTIE ENABLE
                [4*CMD_LUT_SEQ_IDX_WRITEENABLE]        = FLEXSPI_LUT_SEQ(CMD_SDR,   FLEXSPI_1PAD, 0x06, STOP,      FLEXSPI_1PAD, 0x00),

                // Flash register configuration timing (this timing needs the cooperation of read status and write enable above)
                // Note2: the instructions written here are different between IS25WP series and IS25LP series
                [4*CMD_LUT_SEQ_IDX_SET_READ_PARAM]     = FLEXSPI_LUT_SEQ(CMD_SDR,   FLEXSPI_1PAD, 0xC0, WRITE_SDR, FLEXSPI_1PAD, 0x01),
                [4*CMD_LUT_SEQ_IDX_SET_READ_PARAM + 1] = FLEXSPI_LUT_SEQ(STOP,      FLEXSPI_1PAD, 0x00, 0, 0, 0),
            },
    },
.pageSize           = 256u,
.sectorSize         = 4u * 1024u,
.blockSize          = 64u * 1024u,
.isUniformBlockSize = false,

};