← Unity APP 实例
← Xvisio SDK 文档主页
SLAM(Simultaneous Localization and Mapping),同步定位与地图构建,最早在机器人领域提出,它指的是:机器人从未知环境的未知地点出发,在运动过程中通过重复观测到的环境特征定位自身位置和姿态,再根据自身位置构建周围环境的增量式地图,从而达到同时定位和地图构建的目的。
CSLAM是包含回环检测和地图优化的SLAM模式,建议在要求高精度定位的使用场景中使用CSLAM模式
要建立一个好的地图,你必须首先考虑如何使用地图。地图必须包含应用程序所需的视点。如果最终应用程序在另一个房间,则没有理由在当前房间中记录地图。类似地,如果最终应用程序将显示地面上的一些虚拟对象,则没有理由将地图记录到使用摄像头向上看的房间中。应用程序要移动的路径应该是记录地图的最终路径。为了保证一个好的循环闭合,在同一条路径上走两次:例如,从一个起点开始,走开,回到起点,然后再次在同一条路径上走开,然后回到起点结束。在记录过程中,在同一条路径上行走两次,可以保证在循环闭合检测的不同记录视点之间有很好的重叠。在做这个地图记录时,重要的是避免快速移动或面对没有特征的区域。
场景:Gesture.unity
在此场景中我们将展示基于诠视AR眼镜开发的CSLAM地图识别功能,通过开启CSLAM模式、创建CSLAM地图、加载CSLAM地图等功能来完成一个地图创建、地图保存和地图加载的过程。
我们以之前制作的手势Demo场景为例开发一个CSLAM的应用。此场景为CslamDemo.unity
Step 1:
如下图所示,我们在场景中创建相应的按钮和文本框用来调用CSLAM地图接口和状态显示。
Step 2:
以下代码中我们对将用到的CSLAM接口以及回调函数进行声明。具体接口内容请参见CSLAM接口介绍。
/// <summary>
/// 保存slam特征点数据
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct SlamMap
{
public Vector3 vertices;
};
#region Cslam加载和保存功能
/// <summary>
/// 开启slam接口
/// </summary>
/// <returns></returns>
[DllImport("xslam-unity-wrapper")]
public static extern bool xslam_start_map();
/// <summary>
/// 关闭slam接口
/// </summary>
/// <returns></returns>
[DllImport("xslam-unity-wrapper")]
public static extern bool xslam_stop_map();
/// <summary>
/// 保存地图接口
/// </summary>
/// <param name="mapStream"></param> 保存地图到本地设备的存储地址
/// <param name="cslamSavedCallback"></param> 保存地图成功后的回调函数
/// <param name="cslamLocalizedCallBack"></param> 获取地图匹配度的回调函数
/// <returns></returns>
[DllImport("xslam-unity-wrapper")]
public static extern bool xslam_save_map_and_switch_to_cslam(string mapStream, detectCslamSaved_callback cslamSavedCallback, detectLocalized_callback cslamLocalizedCallBack);//size 0.16 rate 4
/// <summary>
/// 加载地图接口
/// </summary>
/// <param name="mapStream"></param> 加载地图的路径地址
/// <param name="cslamSwitchedCallback"></param> 加载地图的地图地址路径
/// <param name="cslamLocalizedCallBack"></param> 获取地图匹配度的回调函数
/// <returns></returns>
[DllImport("xslam-unity-wrapper")]
public static extern bool xslam_load_map_and_switch_to_cslam(string mapStream, detectSwitched_callback cslamSwitchedCallback, detectLocalized_callback cslamLocalizedCallBack);//size 0.16 rate 4
/// <summary>
/// 加载地图的回调函数
/// </summary>
/// <param name="map_quality"></param>
public delegate void detectSwitched_callback(int map_quality);
/// <summary>
/// 保存地图的回调函数
/// </summary>
/// <param name="status_of_saved_map"></param>
/// <param name="map_quality"></param>
public delegate void detectCslamSaved_callback(int status_of_saved_map, int map_quality);
/// <summary>
/// 获取地图匹配度的回调函数
/// </summary>
/// <param name="percent"></param>
public delegate void detectLocalized_callback(float percent);
/// <summary>
/// 获取场景特征点的接口
/// </summary>
/// <param name="count"></param>
/// <returns></returns>
[DllImport("xslam-unity-wrapper")]
public static extern IntPtr xslam_get_slam_map(ref int count);
/// <summary>
/// 加载地图的回调函数实现
/// </summary>
/// <param name="map_quality"></param>
[MonoPInvokeCallback(typeof(detectSwitched_callback))]
static void OnCslamSwitched(int map_quality)
{
switch_map_quality = map_quality;
}
/// <summary>
/// 保存地图匹配度的回调实现
/// </summary>
/// <param name="percentc"></param>
[MonoPInvokeCallback(typeof(detectLocalized_callback))]
static void OnSaveLocalized(float percentc)
{
percentcD = percentc;
}
/// <summary>
/// 加载地图的匹配度的回调实现
/// </summary>
/// <param name="percentc"></param>
[MonoPInvokeCallback(typeof(detectLocalized_callback))]
static void OnLoadLocalized(float percentc)
{
percentcD = percentc;
}
/// <summary>
/// 保存地图的回调实现
/// </summary>
/// <param name="status_of_saved_map"></param>
/// <param name="map_quality"></param>
[MonoPInvokeCallback(typeof(detectCslamSaved_callback))]
static void OnCslamSaved(int status_of_saved_map, int map_quality)
{
status_of_saved_mapq = status_of_saved_map;
save_map_qualityq = map_quality;
}
Step 3:
我们点击场景中的“开启CSLAM按钮”开始进入CSLAM模式,我们通过眼镜对周围场景进行扫描 ,扫描后点击“保存地图”按钮,此时在地图路径文本框下我们将得到一个命名为map.bin的CSLAM地图文件,同时如下图所示也会将当前的地图匹配度显示在对应的文本框中。
Step 4:
我们点击“保存位置”按钮,将会把奶酪物体的位置保存在app缓存里。
Step 5:
我们重新打开apk,点击“开启CSLAM按钮”开始和“加载地图按钮”将会重新加载我们上一步创建的地图,同时我们点击“加载位置按钮”之后我们便可以看到奶酪物体出现在我们上一步保存的位置上。