일반적인 컬러 렌더링 방법 일반적인 Room 렌더링 방법은 아래와 같이 setThemingColor 사용하는 것이다. let color = new THREE.Vector4(0, 1, 0, 1); NOP_VIEWER.setThemingColor(roomSolidId, color, NOP_VIEWER.model);
참고로, 버전마다 API사용법이 변경되므로, 사용전 이를 체크할 필요가 있다. 이 함수는 6.5버전에서 차일드 객체로 함께 색상을 변경할 수 있도록 수정되었다.
여기서, NOP_VIEWER는 다음과 같이 포지 뷰어를 정의한 것이다. viewer = new Autodesk.Viewing.GuiViewer3D(htmlElement);
roomSolidId는 방 객체가 포함하는 솔리드(solid) 형상 ID이다. 참고로, 포지 모델 객체 계층 구조는 다음과 같다.
Model - Container - Element - Solid
여기서 Container는 건축 객체 요소 그룹, 공간 그룹일 수 있다. 공간 그룹은 Storey 같은 것이다. 각 객체 계층 요소들은 고유의 ID와 속성(properties)를 가진다. 각 정보를 얻는 방법은 포지 API를 통하며, 몇몇 함수들을 비동기 콜백함수(callback function)을 사용해야 한다. 대표적으로 getProperties 와 같은 객체 속성 얻는 함수들이 비동기 함수이다.
포지는 웹 기반 뷰어에서 성능 개선을 위해, 솔리드 재질을 직접 설정하는 함수를 제공하지 않는다. 다만, 포지는 수정된 쓰리(Three.js)를 사용하여 다음과 같이 그래픽 처리한다. 그래픽 렌더링 파이프라인은 쉐이더 확장 기능을 제공하여, 사용자화할 수 있다.
객체 모델 > 솔리드 형상 > 프래그먼트 형상 정보 > THREE.js > WebGL > 그래픽 렌더링
이런 이유로, 별도로 투명, 재질 등 처리를 위해서는 솔리드 모델을 직접 해킹해서 솔리드를 구성하는 페이스를 직접 THREE.js 로 WebGL을 렌더링해야 한다. 렌더링 코드는 포지 뷰어에 확장 모듈로 등록이 가능하다. 이는 아래 링크에 그 내용이 설명되어 있다. 다만, 3년전 버전이라 현재 버전에서는 제대로 동작하려면 수정이 필요하다.
이 글은 IoT(Internet Of Things), NoSQL MongoDB, BIM(Building Information Modeling)과 Autodesk Forge 상호연결 방법에 대한 간단한 설명이다. 개발 환경은 node.js, express, bootstrap을 사용해 앱 서버로서 실행된다.
이 글에서 소개하는 기술은 디지털 트윈 개념 구현에 참고할 수 있으며, 손쉽고 저렴한 기술 개발을 위해, 오픈소스를 적극 사용한다. 동기 부여를 위해, 이 글에서 개발될 시스템명은 DTB-BMS(가칭 Digital Twin and BIM based Building Management System)으로 한다. 디지털 트윈 개념적 이야기는 아래 글을 참고한다.
쉬운 개발을 위해, IoT 센서 데이터 취득 및 DB 연결은 node-red를 사용한다, 굳이 성능 최적화가 중요하다면, 파이썬 등 다른 언어를 사용해 코딩한다. 참고로, 이 글은 간단히 메이크하는 것을 지향하므로, 굳이 어려운 방법을 사용하지는 않는다.
이 글의 개발 파일 및 소스 코드는 블로그에 싣기에는 많고 복잡할 수 있다. 그러므로, 주요 개발 컨셉과 코드를 중심으로 설명한다. 관련 코드들을 이 github링크의 해당 폴더들을 참고하길 바란다. git을 설치하면, 간편하게 개발된 코드를 다운로드할 수 있다. 참고로, 개발 결과 화면은 다음과 같다. 이와 관련된 Mongo DB, node.js, IoT 장치 개발 등 다른 내용들이 궁금하다면, 이 블로그의 관련 글들을 참고한다.
DTB-BMS(Digital Twin and BIM based Building Management System) APP server screen and database REST API(Application Program Interface)
상호연결을 위한 통신 프로토콜이 필요하다. 노드래드 그래프에서 첫번째 함수는 아두이노와 연결된 COM 포트에서 콤마 형식으로 구분된 IoT 데이터들(예. "608.02, 910.13, 7203.23, ...")을 개별 토큰(token)으로 분리한다. 두번째 함수는 토큰으로 분리된 값들을 각각 mongo DB 노드로 전송한다. 여기에, 필요하다면 IoT가 설치된 Room, Element 등 ID를 추가한다.
첫번째 함수 노드 스크립트는 다음과 같다.
var output = msg.payload.split(",");
var msgList = [];
output.forEach(function(v, index)
{
var msgIoT = {payload: parseFloat(v)};
msgList.push(msgIoT);
});
return msgList;
두번째 함수 노드 스크립크를 다음과 같이 코딩한다. area는 센서가 설치된 공간을 구분하기 위한 분류체계로 사용될 것이다.
var d = new Date();
var date = d.getFullYear() + '-' + d.getMonth() + '-'
파일을 열어 다음과 같이 Ip를 0.0.0.0으로 수정한다. 그리고 몽고디비를 재시작한다.
# network interfaces
net:
port: 27017
bindIp: 0.0.0.0
2. 데이터베이스 모델 용량 계산
현재는 온도만 저장하고 있으나, 센서 유형별로 다양한 데이터 값을 저장하기 위해 sensor 컬럼을 추가하였다. 테스트에서는 온도 센서값만 저장하고 있다. 1년동안 서비스한다는 가정하에 어느 정도 저장 용량 장치가 필요하지 확인하기 위해, 다음과 같이 저장 용량을 계산한다.
데이터베이스 향후 저장 용량 계산
1년을 저장한다면, 7,388.94 Mb 저장 용량이 필요하다. 센서 유형을 온도 이외에 습도, 조도, 사운드 마이크로폰 추가시 약 30 Gb 저장 용량이면 된다. 1년 간 데이터 백업을 고려하면 60 Gb이다. 저장소가 부족하 경우, 압축이나 데이터 취득 간격 조정을 고려한다. 참고로, IoT장치에서 1초에 2번씩 데이터를 샘플링하므로, 1초로 줄일 경우, 계산된 저장용량의 절반 정도면 충분할 것이다. 참고로, 신호처리이론(Nyquist–Shannon sampling theorem, Sampling and sampling density)에 의해 데이터 처리 간격이 1/1초라면, 데이터 손상 없는 재현을 위해, 최소 두배(2.56) 간격으로 샘플링하는 것이 좋다. 아울러, 샘플링은 센서 스펙도 함께 고려한다(예. Arduino Nano BLE sense 33. Sensor output rate = 104 Hz).
3. BIM 모델 LoD 경량화
BIM 모델링은 Autodesk Revit을 이용한다. 모델 LoD(Level of Detail) 경량화 과정은 모델 용량에 따라 매우 많은 노가다가 필요할 수 있다. 사용된 BIM 모델은 UNF 건물 일부이다. 중앙 저장소 파일 모델 하나의 크기만 110Mb가 넘어간다. 연결된 파일들을 모두 합치면 500Mb가 넘어간다. 이 상태로는 웹에 모델을 띄울 수도 없을 뿐더러, 뛰운다고 하더라도 불필요한 정보가 너무 많아 모델 정보 사용이 매우 불편해진다.
Revit으로 해당 모델을 띄우고, 평면 뷰에서 세션을 만들어 요구사항과 관련없는 층들은 모두 삭제한다. 패밀리에서 가구, MEP 등 불필요한 유형은 모두 삭제한다. 실수로 삭제된 요소는 해당 부분만 다시 모델링해준다. 기타, 사용안되는 도면 등 요소들도 삭제한 후 Purge로 정리한다. 모델이 복잡하거나 요구사항이 불명확하면, 이런 경량화 작업이 몇시간에서 몇일 걸릴 수도 있다.
UNF 대학 Skinner 건물 일부
이러한 경량화 작업으로 모델을 다음과 같이 20Mb로 줄였다.
LoD 경량화된 BIM 결과
LOD 경량화된 BIM 모델 WEB 렌더링 결과
단, 업로드 시 사용하는 Axios 기본 설정은 5Mb이므로, 이를 다음과 같이 적절히 수정해야, 대용량 BIM 모델을 업로드할 수 있다.
Axios({
method: 'PUT',
maxContentLength: 100000000, // 최대 BIM 모델 크기 정의
maxBodyLength: 1000000000,
})
참고로, 업로드된 래빗 파일은 SVG형태로 변환되어 버킷에 저장된다. 변환 시 입력 모델이 잘못되어 있다면, SVG로 파싱되지 않으며, 모델이 제대로 렌더링되지 않는다.
4. 모델-데이터베이스 Connection
BIM 모델 경량화 후 IoT 데이터 연결 과정을 작업한다. 각 레코드는 IoT 데이터와 연결을 위해서는 모델 객체 별로 연결 데이터 처리 작업이 필요하다. BIM 객체에 센서 데이터 연결을 위한 ID같은 연결점을 모델링한다(마법은 없다. 눈으로 객체를 확인하며 손으로 직접 입력 수정한다. 참고로, 분류체계가 잘 되어있다고 하더라도, 분류체계 자체가 유일ID가 아니면 어차피 눈으로 보고 손으로 직접 입력해야 함. 래빗 애드인이나 스크립트를 통해 이 과정을 좀 간소화시킬 수는 있을 것이다). 상호 연결을 위해 객체 속성 GUID, 분류체계, 태그 ID 등을 생성하고 이를 이용해 DB, 비지니스 로직과 연결한다. 연결할 ID가 상호 잘못되면 제대로 처리가 안된다.
데쉬보드 그래픽은 Bootstrap을 사용하며, 뷰어 우측과 아래에 차트 그래프(forgeViewer div 요소 뒤에 추가됨), 테이블(sensorDataTable)로 동적 구성된다. 동적 구성될 요소는 viewer.html의 body에서 다음과 같이 정의되어 있다(Ex. table event).
<body>
<!-- Custom script -->
<h4>Digital Twin based Building Monitoring and Data Analysis</h4>
그래프 동적 구성을 위한 주요 코드는 다음과 같다. 데쉬보드 div 요소가 추가되고, 데쉬보드 div 요소 안에 바차트, 파이차트 div 요소가 추가된다.
// dashboard.js
$(document).ready(function () {
$(document).on('DOMNodeInserted', function (e) {
if ($(e.target).hasClass('orbit-gizmo')) {
new Dashboard(NOP_VIEWER, [new BarChart('Light'), new PieChart('Temp')]); // HTML DOM ready 이벤트 발생 시 데쉬보드 추가.
}
});
})
class Dashboard {
adjustLayout() {
var row = $(".row").children();
if(row.length > 0)
$(row[0]).removeClass('col-sm-7').addClass('col-sm-9 transition-width').after('<div class="col-sm-3 transition-width" id="dashboard"></div>'); // Forge viewer div 아래에 차트 그래프 요소 추가
}
}
// Dashboard panel base
class DashboardPanel {
load(parentDivId, divId, viewer) {
this.divId = divId;
this.viewer = viewer;
$('#' + parentDivId).append('<div id="' + divId + '" class="dashboardPanel"></div>'); // 데쉬보드 요소 추가
}
}
// Dashboard panels for charts
class DashboardPanelChart extends DashboardPanel {
load(parentDivId, divId, viewer) {
divId = this.propertyToUse.replace(/[^A-Za-z0-9]/gi, '') + divId; // div name = property + chart type
super.load(parentDivId, divId, viewer);
this.canvasId = divId + 'Canvas';
$('#' + divId).append('<canvas id="' + this.canvasId + '" width="400" height="400"></canvas>'); // 차트 그래프 요소 추가
이제 BIM 공간 선택 시 해당 데이터를 차트 그래프와 연결하고, IoT 센서 장치를 각 공간에 설치하면, 현실과 디지털 공간과 연결한 소위 디지털 트윈이란 개념을 구현한 것이다. 개발해 본 결과를 보면, 기존 센서 데이터를 디지털 모델과 연계하거나 시뮬레이션했던 시스템들과 큰 차이가 없다. 이런 접근이 브랜드로 발전하고 대중화된 것이다. 디지털 트윈을 구현하는 방법은 다양할 수 있다. 구현 방법은 요구사항과 개발 전략에 따라 달라질 수 있다. 만약, GIS map을 사용한다면, Leaflet(리플릿), mapbox(맵박스), 3D Cesuim(세슘) 등 다양한 오픈소스 도구를 사용할 수 있다. 도면만 필요하다면, DWG/DXF 캐드 뷰어만 사용해도 된다. 데이터 모니터링만 필요하다면, 테이블 및 차트만 지원되는 데쉬보드 형태의 HCI(Human Communication Interface)도 충분하다.
오픈소스 기반 GIS 공간정보 뷰어 예시
굳이, 3D 모델이 필요없이 효율적인 업무가 가능하다면, 디지털 트윈 타이틀이 붙은 과제라도 3D 모델 뷰어를 구현할 필요가 없다. 앞서 개발하는 과정을 보면 알겠지만, 디지털 트윈 개념을 서비스하기 위해서는 많은 비용과 노력이 필요하다. DATABASE, REST API, 보안, VIEWER, DASHBOARD, BUSINESS LOGIC, IoT, 서버, 데이터 모델링 등 욕심을 내다 보면 끝도 없다.
보통, 사용자는 유지보수 비용을 크게 간과하는 경향이 있다. 실제 서비스 중인 소프트웨어는 유지보수 비용이 80~90%를 상회한다.
소프트웨어 공학 관점에서 보았을 때 불필요한 모델, 데이터의 구현은 유저의 시스템 사용을 매우 불편하게 할 뿐아니라 유지보수, 성능에 나쁜 영향을 준다. 이 시점에서 모든 것을 막연한 짐작으로 디지털 트윈이나 BIM으로 구현하면 편리하다는 주장은 근거가 매우 빈약하며, 쉽게 납득하기도 어렵다(발주자가 진정 돈을 아끼고 싶다면, 화려하고 복잡한 PPT는 조심해야 한다). 물리적 데이터를 디지털 공간에 맵핑하는 것이 문제라면, 그 요구사항과 구현이 유저 입장인지가 중요하다.
추신 - 이 정도까지 진행하는 데 Full M/M로 대략 1개월(Not including holiday) 걸린 것 같다. 이 정도로도 물리적 공간에 붙착된 데이터를 가상으로 모니터링하고 분석용 데이터를 획득할 수 있다. 이제 좀 더 편리한 인터페이스 구현을 위해, 다음과 같은 부분을 처리한다.
BIM 공간과 그래프 연결. 이벤트 처리
IoT 센서 장치를 인터넷에 연결
IoT 센서 장치를 각 공간에 설치
모니터링된 데이터에서 이상 패턴 감지를 위한 딥러닝 학습 모듈 개발
여기서, 다른 일을 하며 진행하므로, 개발 효율이 30~50% 정도... 그럼 앞으로 약 두달 정도해야 정리될 듯하다. 시간이 빡빡하기는 하지만, 센서 데이터와 글은 병행해 정리하기로 한다. - 2/25
추신 - 오토데스크 포지 제공 API가 원하는 모든 기능을 제공하지는 않는다(직접 해봐야 안다). 제공되지 않는 기능은 직접 구현해야 하며, 가끔은 DOM 해킹, 3차원 기하 계산 등을 코딩해야 할 수 있다. 참고로, 이런 노가다 코딩이 인공지능으로 자동화될 수 있다고 착각하지 말자(한참 멀었다).
추신 - UNF에서 DT 웹서버 설정하고 실행함. 이제 자잘한 기술 개발 및 네트워크 설정만 남은 듯. - 3/10
추신 - ELO Twilight 들으며 작정하고 편안하게 코딩 중. 지금까지 너무나 주변 요구, 환경과 시선에 신경을 쓰고 살았음을 느낌. 아무도 터치하지 않으니 생각 정리되어 편하고, 일 잘 됨. 의미없는 생명력이라고는 1도 없는 공허한 수많은 R&D과제 무생물 포장들 신경 쓸 필요 없이, 내가 생각한 개념 데로 연구개발하니 속편하고 무언가 채워지는 느낌(인생이 아깝지 않다). 불과 두달전까지 잡다한 일에 치여 코딩은 커녕, 과제 업체 관리 보고 논문 특허 증빙자료 정량지표 채우기도 바빳던, 막연히 의미있을 거란 위안을 갖고 있을 때와는 너무 차이 남(안보고 안해도 되는 건데 술쳐먹고 노는 체질 아니니 스스로 힘들게 하는 거지). 예전에 Universe 를 만들겠다고 상상하며 개발했던 적이 있었음. 그땐 누가 시키지 않아도, 밤새고 프로그래밍한 후 실행되는 어플리케이션이 애완동물처럼 좋았던 때가 있었다.
프로그래밍은 여행전 시동 걸어 출발한 후, 오랫동안 고통의 계곡을 넘은 후, 주변의 아름다운 경치가 한 눈에 들어오는 어드밴처와 비슷하다. 오래간에 그 느낌 맛보네. - 3/14
추신 - 드디어, 개발 끝남. 개발 기간은 1.5M/M. BIM 모델 연계, 차트 개발, 테이블 이벤트 처리, 센서 오작동 문제 처리, 웹 화면 스타일 처리, IoT 데이터 동적 업데이트 등 자잘한 것 개발 완료. 아직 완전히 마음에 드는 것은 아니지만, 대학교 내부에서 서비스 및 연구 분석 데이터 얻을 정도는 됨. 성능 최적화, 코드 리팩토링은 시간 나면 하기로. 이제 스캔, 딥러닝, 비전 작업을 시작. 다음주에는 이 내용을 글로 정리해야겠음. 이젠 여기 생활이 일상이 되어 간다. 점점 가족중심이 되어가는 듯... - 4/2
추신 - 측정해 보니, 각 공간별 온습도차이, 조도차이를 알 수 있음. 더불어, 조도차이로 사람 거주 유무도 예측 가능. 몇몇 센서는 서로 간섭되는 현상도 발견해 수정함. - 6/12/2021
추신 - 24/365 서버 실행 테스트 중. 5월부터 지금까지 운영해 모아보니, 전원이 공급되는 한 서버가 다운되거나 센서 동작 코드가 에러나는 경우는 없었음. - 8/10/2021
추신 - 데이터 취득 중 특정 센서 취득 시 무결성 문제 발견. 지금까지 모아둔 1기가 바이트 이상 데이터베이스 모두 리셋하고 코드 수정해 재취득 시작함 - 9/20/2021
추신 - 얼마전 부터 여기 학생, 다른 여러 교수들과 협업 중. 개발 기술을 브랜드화하기 위해, IoT 센서 패키징, 디자인 등을 브레인스토밍하였고, 그때 나온 의견을 바탕으로 작업을 진행하고 있다. 아울러, 데이터 무결성 등을 오랫동안 실행해보며 확인했고 몇몇 문제점을 수정하였다. 무결성이 확보되었으니, 딥러닝 학습용 데이터 다운로드받아 이상패턴 검출할 모델 만들면 될 듯. - 10/20/2021