(寫在前面,談談物聯網展會)上次深圳會展中心舉行物聯網展會,到了展會一看,80%以上的物聯網應用都是在搞RFID,室内定位,我一度懷疑物聯網落地方案的方向局限性與市場導向,後來多方面了解才明白,展會上看到的不能展現目前物聯網最前沿最廣泛的應用,很多大的企業與技術前沿企業沒有參與這樣的展會,一是不屑于參加,二是展會帶來的市場價值實在太少太少,展會最大的價值就是讓同行之間再抄一抄(國内大部分企業基本這樣,互相山寨),看看各家都做了啥,是以,展會上我們所看到的往往不是企業最核心最好的東西,不能展現目前國内物聯網最前沿的技術與發展狀況。
前言:GPS、北鬥系統将全球地圖導航定位發展到了極緻的程度,但精确精度還不能達到兩米以内, 如何解決解決室内這最後幾米的定位問題,國内外各大廠家各出奇招。因為有市場需求是以有資本驅動,室内精确定位在倉庫,檔案館,監獄,醫院,辦公,人員,以及各種高價值重要資産等定位場景中都要這樣的需求。室内定位設想應用于人員的管理、機器人仿生、被标簽物的定位追蹤等等。如果室内定位能夠解決精度,延遲,容量三方面瓶頸,其市場應用價值不可限量
技術目标:将非可視内容的可視化呈現,更直覺的掌控資料情況。
一、市場背景與領域:
1、資訊采集定位:打卡、簽注、活動範圍圈定、電子圍欄、工作中日常監控等等。
2、安防監控定位:安防領域比較廣泛,包括了消防、監控、維保安保等等,這些具體行業劃分方面對精準定位可視化需求都比較強烈。保護人民生命财産、監控消防英雄實時位置這些都是有待解決的問題。
3、工業4.0:這是最新的工業訴求,真正落地的,目前還沒有幾家,其主要目标就是通過室内定位技術讓整個生産流程實作可視化,可追蹤化。
4、監獄、醫院、機場領域、商場。定位可視化需求也比較強烈
監獄:防止越獄,防止自殺等。每個犯人手上上一個不可拆卸的手環,隻要系統檢查到有人某處停留時間過長,系統就會報警。
醫院:為患者提供快捷的尋址巡診服務。
機場、商場:為客人,旅客提供友善快捷的定位導航服務,為機場提供可疑物品貼标簽定位方案。
5、倉庫資産定位
6、無人機、物流、快遞派送定位
7、APP應用服務,适當位置推送适當服務。
8、遊戲場景,VR應用
等等,随便想想就這麼多,看來市場還是比較有前景的。
二、技術方案分析:
目前市面上室内定位技術主要分為下列幾種:
1、wifi探針+錄影機智能分析技術:這種技術利用wifi探針撤出大體位置在用錄影機智能分析,分析出精确位置,優點是精确度高,缺點是成本高,錄影機死角多。
2、無源RFID+讀卡器技術:這種技術是目前市面上用的比較多的技術,比如超市,倉儲,優點是成本低,缺點是沒什麼精度要求 ,精度範圍 是房間内
3、低功耗有源RFID+讀卡器基地器+智能分析:這種利用有源發射信号的方式定位,精确多雖然高 但是讀卡器多的情況下會出現誤報,亂報情況,這就需要智能分析,資料清洗。目前比較看好的方案,成本低,精确度一米以内。
4、藍牙信号強度探測分析:精確的高,但是藍牙信號受阻擋,受幹擾比較嚴重。這也是展會中看到的方案。
5、定位地毯+有源信号卡(手環):這是精确度非常高的方案,但是成本也很高。要在室内鋪上一層定位弱電地毯。
6、紅外探測技術、超寬帶技術、超音波技術:和藍牙的方案差不多。
技術交流郵箱: [email protected]
三、三維可視化顯示
我們還是和前面的課程一樣選擇webgl無插件解決方案,直覺展現定位可視化。
3.1、首先是場景搭建,搭建需要定位的三維場景。這裡我們随便做了一棟大樓,作為需要定位的場景。

模型代碼:
3.2、顯示單個樓層實時定位效果。這裡我們動态添加定位标簽。标注标簽。在右下角顯示标簽資訊,規避場景内淩亂。
邏輯代碼:
if (_this.build1CurrentShowFlow == 8&&_this.currentShowLocationState == 1) {
_this.closeLocation(doshowAnimiation);
} else {
doshowAnimiation();
}
function doshowAnimiation(){
WT3DObj.commonFunc.changeCameraPosition(
{ x: -3160 + (8 - floornub) * 300, y: 5645 - (8 - floornub) * 300, z: -3292 + (8 - floornub) * 300 },
{ x: 80, y: 23, z: 155 },
500,
function () {
if (_this.build1CurrentShowFlow > floornub)
{
var start = _this.build1CurrentShowFlow;
_this.build1CurrentShowFlow = floornub;
for (var i = start; i >= floornub + 1; i--) {
(function (floorindex) {
setTimeout(function () {
var movemodesname = "cM_dingweifloor_" + floorindex;
var movemodel = _this.outFloorModels[movemodesname];
if (!movemodel.oldposition) {
movemodel.oldposition = {
x: movemodel.position.x,
y: movemodel.position.y,
z: movemodel.position.z
};
}
var moveToPositon = movemodel.position.y + 5000;
new TWEEN.Tween(movemodel.position).to({
y: moveToPositon
}, 1000).onComplete(function () {
movemodel.visible = false;
if (floorindex == floornub + 1) {
if (_this.currentShowLocationState == 1) {
if (floornub < 8) {
var showTxt = "";
showTxt += _this.addFloorMarks(floornub);
$("#showText").html(showTxt);
} else {
_this.showLocation();
}
}
}
}).start();
}, 500 * (start+1 - floorindex));
})(i);
}
}
else if (_this.build1CurrentShowFlow < floornub)
{
var start = _this.build1CurrentShowFlow+1;
_this.build1CurrentShowFlow = floornub;
for (var i = start; i <= floornub ; i++) {
(function (floorindex) {
setTimeout(function () {
var movemodesname = "cM_dingweifloor_" + floorindex;
var movemodel = _this.outFloorModels[movemodesname];
var moveToPositon = movemodel.oldposition.y;
movemodel.visible = true;
new TWEEN.Tween(movemodel.position).to({
y: moveToPositon
}, 1000).onComplete(function () {
if (floorindex == floornub) {
setTimeout(function () {
if (_this.currentShowLocationState == 1) {
if (floornub < 8) {
var showTxt = "";
showTxt += _this.addFloorMarks(floornub);
$("#showText").html(showTxt);
} else {
_this.showLocation();
}
}
}, 150 * floornub - start);
}
}).start();
}, 500 * (floorindex-start + 1));
})(i);
}
}
});
}
單樓層顯示定位效果
‘’
動态标簽模型代碼:
[{ "show": true, "uuid": "", "name": "dmark_" + name, "objType": "GroupObj", "scale": { "x": 1, "y": 1, "z": 1 }, "position": position, "rotation": [{ "direction": "x", "degree": 0 }], "childrens": [{ "name": "dmark_" + name + "OBJCREN0", "objType": "picIdentification", "size": { "x": size.width, "y": size.height }, "position": { "x": 0, "y": 0, "z": 0 }, "imgurl": picurl, "showSortNub": 3480, "animation": null, "dbclickEvents": null, "BindDevId": null, "BindDevName": null, "devInfo": null, "BindMeteId": null, "BindMeteName": null }, { "name": "dmark_" + name + "OBJCREN1", "objType": "makeTextSprite", "textColor": { "r": Txtcolor.r, "g": Txtcolor.g, "b": Txtcolor.b, "a": 1 }, "message": "" + showNub, "fontsize": 300, "canvasWidth": 400, "canvasHeight": 350, "position": { "x": 0, "y": 64.901, "z": 0 }, "showSortNub": 3481, "animation": null, "dbclickEvents": null, "BindDevId": null, "BindDevName": null, "devInfo": null, "BindMeteId": null, "BindMeteName": null }], "showSortNub": 3480 }];
單樓層顯示定位代碼:
ModelBusiness.prototype.marks = [];
ModelBusiness.prototype.addMark = function (name, position, size, picurl,showNub,Txtcolor) {
if (this.marks.indexOf("dmark_" + name) >= 0) {
modelBusiness.moveMark("dmark_" + name, position, 1000);
return;
}
this.marks.push("dmark_" + name);
var timestrik = new Date().getTime();
var showHtml = "hello";
var local = [{ "show": true, "uuid": "", "name": "dmark_" + name, "objType": "GroupObj", "scale": { "x": 1, "y": 1, "z": 1 }, "position": position, "rotation": [{ "direction": "x", "degree": 0 }], "childrens": [{ "name": "dmark_" + name + "OBJCREN0", "objType": "picIdentification", "size": { "x": size.width, "y": size.height }, "position": { "x": 0, "y": 0, "z": 0 }, "imgurl": picurl, "showSortNub": 3480, "animation": null, "dbclickEvents": null, "BindDevId": null, "BindDevName": null, "devInfo": null, "BindMeteId": null, "BindMeteName": null }, { "name": "dmark_" + name + "OBJCREN1", "objType": "makeTextSprite", "textColor": { "r": Txtcolor.r, "g": Txtcolor.g, "b": Txtcolor.b, "a": 1 }, "message": "" + showNub, "fontsize": 300, "canvasWidth": 400, "canvasHeight": 350, "position": { "x": 0, "y": 64.901, "z": 0 }, "showSortNub": 3481, "animation": null, "dbclickEvents": null, "BindDevId": null, "BindDevName": null, "devInfo": null, "BindMeteId": null, "BindMeteName": null }], "showSortNub": 3480 }];
//[{ "name": "dmark_" + name, "objType": "picIdentification", "size": { "x": size.width, "y": size.height }, "position": position, "imgurl": picurl, "showSortNub": 3480, "show": true, "customType1": "", "customType2": "", "animation": null, "dbclickEvents": null, "BindDevId": null, "BindDevName": null, "devInfo": null, "BindMeteId": null, "BindMeteName": null },
// { "name": "dmark_TxtNub_" + name, "objType": "makeTextSprite", "textColor": { "r": 255, "g": 255, "b": 0, "a": 1 }, "message": "001", "fontsize": 100, "canvasWidth": 100, "canvasHeight": 120, "position": { "x": position.x, "y": position.y + 53.904, "z": position.z}, "showSortNub": 5, "animation": null, "dbclickEvents": null, "BindDevId": null, "BindDevName": null, "devInfo": null, "BindMeteId": null, "BindMeteName": null }];
WT3DObj.commonFunc.loadModelsByJsons(local, { x: 0, y: 0, z: 0 }, { x: 0, y: 0, z: 0 }, true);
}
ModelBusiness.prototype.addMarkTxt = function (showHtml, _obj, buildNub, position, closeFunc) {
var timestrik = new Date().getTime();
var _obj = {
uuid: 'daf4',
name: "showMark",
showSortNub: 1,
objType: "DivTagging",
tagType: 'sprite',//plane/sprite
elementParam: {
cssid: "style_divtest",
css: "",
marginValue: {
x: 0,
y: 0,
z: 0
},
divid: 'divtest',
html: "<div id='divtest'><div style='width:300px;height:200px;background-color:rgba(0,0,0,1);padding:10px;border:1px solid #00ffff;'>" + showHtml + "</div > </div >",
},
position: { x: position.x, y: position.y + 500, z: position.z },
scale: { x: 8, y: 8, z: 1 },
rotation: [],
}
var ccd = WT3DObj.addDivTagging(WT3DObj, _obj);
ccd.renderOrder = 1;
WT3DObj.addObject(ccd);
3.3、顯示整體樓層實時定位效果。
gif錄屏圖
實作代碼:
if (_this.build1CurrentShowFlow == 8&&_this.currentShowLocationState == 1) {
_this.closeLocation(doshowAnimiation);
} else {
doshowAnimiation();
}
function doshowAnimiation(){
WT3DObj.commonFunc.changeCameraPosition(
{ x: -3160 + (8 - floornub) * 300, y: 5645 - (8 - floornub) * 300, z: -3292 + (8 - floornub) * 300 },
{ x: 80, y: 23, z: 155 },
500,
function () {
if (_this.build1CurrentShowFlow > floornub)
{
var start = _this.build1CurrentShowFlow;
_this.build1CurrentShowFlow = floornub;
for (var i = start; i >= floornub + 1; i--) {
(function (floorindex) {
setTimeout(function () {
var movemodesname = "cM_dingweifloor_" + floorindex;
var movemodel = _this.outFloorModels[movemodesname];
if (!movemodel.oldposition) {
movemodel.oldposition = {
x: movemodel.position.x,
y: movemodel.position.y,
z: movemodel.position.z
};
}
var moveToPositon = movemodel.position.y + 5000;
new TWEEN.Tween(movemodel.position).to({
y: moveToPositon
}, 1000).onComplete(function () {
movemodel.visible = false;
if (floorindex == floornub + 1) {
if (_this.currentShowLocationState == 1) {
if (floornub < 8) {
var showTxt = "";
showTxt += _this.addFloorMarks(floornub);
$("#showText").html(showTxt);
} else {
_this.showLocation();
}
}
}
}).start();
}, 500 * (start+1 - floorindex));
})(i);
}
}
else if (_this.build1CurrentShowFlow < floornub)
{
var start = _this.build1CurrentShowFlow+1;
_this.build1CurrentShowFlow = floornub;
for (var i = start; i <= floornub ; i++) {
(function (floorindex) {
setTimeout(function () {
var movemodesname = "cM_dingweifloor_" + floorindex;
var movemodel = _this.outFloorModels[movemodesname];
var moveToPositon = movemodel.oldposition.y;
movemodel.visible = true;
new TWEEN.Tween(movemodel.position).to({
y: moveToPositon
}, 1000).onComplete(function () {
if (floorindex == floornub) {
setTimeout(function () {
if (_this.currentShowLocationState == 1) {
if (floornub < 8) {
var showTxt = "";
showTxt += _this.addFloorMarks(floornub);
$("#showText").html(showTxt);
} else {
_this.showLocation();
}
}
}, 150 * floornub - start);
}
}).start();
}, 500 * (floorindex-start + 1));
})(i);
}
}
});
}
由于篇幅原因,這一課先介紹到這裡
後面我将繼續講解用webgl 建立 3D園區 3D智慧小區 、室内定位、橋梁隧道三維應用炫酷效果等等
技術交流 [email protected]
交流微信:
如果你有什麼要交流的心得 可郵件我