Trend(차트) 객체와 히스토리 Popup Trend(팝업 차트) 사용방법


본 강좌에서는 Trend(이하 차트)객체의 속성 및 사용방법에 대하여 설명합니다. 주의사항은 사용방법에 대해 설명하면서 알려드리고 본문 마지막에 표로 정리해 놓겠습니다.

enuSpace 학생용 버젼 다운로드 http://enuspace.tistory.com/entry/enuSpace-for-Mars-2017


Lesson6 project sample: lesson6.zip


enuspace for mars에서 차트의 사용법은 크게 3가지가 있습니다. 본 튜토리얼에서는 3가지와 팝업 차트까지 설명하도록 하겠습니다. 

1. 정적 데이터를 이용한 차트 객체 표현

2. 동적 데이터를 이용한 차트 객체 표현

3. 차트 객체를 Logic객체로 만들어서 사용하기

enuspace for mars에서 차트는 기본적으로 실시간 차트입니다. 이를 라인 차트로 변경하려면 몇가지 설정을 해줘야 합니다.

설정법은 정적 차트 설명 하는 부분에서 알려드리도록 하겠습니다.


우선 차트를 그리기 위한 프로젝트를 하나 생성합니다.

프로젝트 생성은 프로젝트 만들기 튜토리얼을 참조하시길 바랍니다.

프로젝트 생성이 완료 되었다면 Project Explorer에서 Picture폴더에 trend라는 svg파일을 하나 생성합니다.


그리고 리본메뉴에서 차트(Home->Chart)를 선택하고 에디트화면에 생성합니다.


위 화면이 차트를 처음 생성했을 때 나타나는 화면입니다.

여기까지 하셨으면 차트를 사용하기 위한 기본작업이 완료되었습니다.

차트와 차트의 컴포넌트 속성은 다음과 같습니다.


1. 정적으로 차트 사용하기

정적 차트(라인 차트)로 사용하기 위해서 몇가지 속성을 변경해야 합니다. 우선 위에서 생성한 차트를 선택하고 오른쪽에 속성창을 살펴봅니다.

클릭하시면 원본크기로 볼 수 있습니다.

위의 속성창에서 아래 세가지 속성을 변경해줍니다.

trend-flow = off

xview-max = 300

auto-scale = off

속성을 변경 했다면 아래와 같은 그림이 나옵니다.

이제 마우스로 차트를 선택 합니다. 선택하면 상단에 리본메뉴가 아래와 같이 바뀌어 있는것을 볼 수 있습니다. 

리본메뉴에 대해 잠깐 설명 하자면 Add Chart Element는 차트안에 있는 컴포넌트들(범례, 제목, 그래프, x축, y축)의 visible 속성을 뜻합니다.
Drawing 카테고리에 있는 메뉴들은 모두 차트 배경에 관한 속성입니다. 
Add Data항목은 차트의 series를 설정 하는 곳으로 series를 추가, 삭제, 속성 변경 등을 할 수 있습니다.

우리는 series를 추가해야 하니  Add Data를 선택 합니다.

Add Data항목을 선택 했을 때 나오는 창입니다.

위 창에서 Add 버튼을 클릭하여 series를 하나 추가합니다. 그리고 추가된 series를 선택하여 오른쪽에 series에 대한 속성을 띄웁니다.

series에 관한 속성은 다음과 같습니다.


정적 데이터의 데이터 포맷은 x,y x,y 입니다. 예) 50,300 100,250 150,400 200,150 250,500

위의 예를 series2의 data속성에 넣으면 다음과 같은 화면이 나옵니다.

현재 정적 차트에서 사용할 수 있는 타입은 line(선)과 scatter(점) 차트입니다. 그리고 두가지 타입은 하나의 차트에 나타낼 수 있습니다.

2. 동적 차트 사용하기

동적 차트를 사용하기 위해서 우선 값이 변하는 지역변수를 만들어 보겠습니다.

Project Explorer에서 picture폴더에 파일을 하나 더 생성합니다.

생성된 picture파일 화면에서 배경을 클릭하시고 오른쪽 속성창을 확인합니다. 속성창의 윗 부분에 4개의 아이콘이 있는 것을 확인할 수 있습니다. 이 중에서 V모양의 아이콘을 클릭합니다.

그러면 아래와 같은 창이 나옵니다.

여기서 picture파일의 지역변수를 생성할 수 있습니다. 생성 방법은 다음과 같습니다.

1) New라고 표시된 속성에서 드롭다운 메뉴의 <Add Variable>항목을 선택한다.

2) 변수 생성창에서 변수의 타입(필수), 이름(필수), 시작 값(필수), 설명(선택)을 입력하고 Accept버튼을 클릭합니다.


생성 완료된 화면

변수가 생성 되었다면 변수 값을 속성창의 4개 아이콘중 번개 모양의 아이콘을 선택하여 아래와 같은 창을 띄웁니다.

 위의 창에서 Script Type의 type속성을 text/javascript로 변경하고, ontaskview항목을 추가해줍니다.

스크립트 편집 창이 뜨면 다음과 같이 입력합니다.

(생성했던 변수이름) = Math.floor(Math.random() * 500);

입력을 완료하고 Compile 버튼이나 Accept버튼을 클릭하여 스크립트를 등록 하여 줍니다.

여기까지 완료하셨으면 값이 변화 하는지 확인해봅니다.

이제 picture화면에 차트를 새로 생성합니다. 차트가 생성되면 상단 리본메뉴의 Add Data항목을 열어 줍니다.

series1의 속성에서 variable 속성에 위에서 생성한 변수의 이름을 넣어 줍니다. (※주의 : 변수의 이름이 틀리면 값이 들어오지 않거나 원하는 변수의 값이 들어오지 않을 수 있습니다.)

여기까지 완료하면 상단 리본메뉴에서 Home->Run을 클릭하여 스크립트를 실행하여 줍니다. 차트의 그래프가 그려지는지 확인합니다.

그래프가 너무 촘촘히 나온다면 차트의 duration값을 60 또는 120으로 설정하시면 됩니다.

3. 차트 객체를 Logic객체로 만들어서 사용하기

Logic 파일 생성과 Logic객체 이용방법은 LOGIC 프로그래밍, HMI라이브러리 인터페이스 방법에서 확인 하시기 바랍니다.

우선 Project Explorer에서 Logic라이브러리 파일을 생성하고, Logic Node를 생성합니다.

시작과정을 모두 완료한 상태

먼저 리본메뉴의 Home->Connection Pin을 생성합니다. Pin의 속성을 다음과 같이 설정합니다.

name = input
var-type = double

설정이 완료되면 차트를 생성하여 속성을 변경해 줍니다.

title-visible = hidden
legend-visible = hidden
xaxis-visible = hidden
yaxis-visible = hidden
fill-opacity = 0
duration = 30
auto-scale = off

위와 같이 모두 변경 하였다면 차트의 크기를 줄여줍니다(줄이지 않으셔도 무방합니다.). 대략 밑의 그림 정도로 줄여 주시면 됩니다.

이제 차트를 선택클릭하고 리본메뉴의 Add Data항목을 클릭하여 series속성변경 창을 열고 속성을 다음과같이 변경합니다.

variable = pin의 이름(name속성)

위 과정을 모두 완료 한뒤 라이브러리를 저장해 줍니다.

2번에서 만들었던 picture를 열어줍니다.

여기에 방금 만든 Logic차트를 생성하여 줍니다.

생성이 완료되면 Logic차트에 ID값을 입력하여 줍니다. 입력이 완료 되면 배경을 클릭하고 스크립트를 편집합니다.

위 과정이 모두 완료 되면 리본 메뉴의 Run을 눌러 동작하는지 확인합니다.


■ 팝업 차트 사용하기

팝업 차트를 사용하기 위해서는 두가지 방법이 있습니다.

1. DB에 등록된 변수를 이용하여 팝업 차트로 보기

2. 현재 생성되어 있는 Logic객체의 데이터를 이용하여 팝업차트 이용하기

3. Logic객체의 데이터를 모아서 팝업차트 만들기

주의 할 점은 2번 방법의 경우 Logic객체에 Pin객체나 지역변수가 생성되어 있어야 합니다.

3번 방법은 여러개의 데이터를 한데 묶어서 볼 수 있다는 장점이 있습니다.


1. DB에 등록된 변수를 이용하기

우선 DB에 변수를 등록 해야합니다. 위에서 우리가 만들어놓은 지역변수를 등록하여 팝업차트를 만들어 봅시다.

먼저 리본메뉴의 Data/Communcation탭으로 이동합니다. 그리고 DB Show라는 버튼을 클릭합니다.

DB TABLE 다이얼로그가 나타나면 상단의 DB그림에 G가 써져있는 버튼을 클릭합니다. 그 뒤 나타나는 창의 내용은
"해당 버튼을 누르고 계속 진행하면 기존에 생성되어 있던 데이터들이 모두 지워집니다. 그리고 글로벌 변수와 로직 객체의 변수들을 데이터 베이스에 재생성합니다. 계속하시겠습니까?" 라는 내용입니다.


여러분은 처음 생성하는 것일테니 아마도 전부 비어있을 겁니다. 그러므로 걱정하지 마시고 예를 눌러주시면 됩니다.

지금까지 제대로 따라오셨다면 아래와 같은 화면이 나타납니다. DB TABLE창을 닫지 않고, 리본메뉴에서 Run버튼을 눌러 변수의 값을 변화 시켜 줍니다.

DB TABLE창에서 팝업차트에서 보고 싶은 변수를 오른쪽 클릭하거나 'Ctrl+클릭' 또는 'Shift+클릭' 또는 '드래그'로 다중선택 하여 오른쪽위의 버튼을 클릭합니다.

생성된 팝업 차트를 확인합니다.


2. 현재 생성되어 있는 Logic객체의 데이터를 이용하여 팝업차트 이용하기

다시 picture 화면으로 돌아가서 Logic차트를 더블 클릭합니다.


아래와 같은 창이 나타나면 


팝업 차트로 보고싶은 변수를 마우스 오른클릭하여 팝업 차트를 실행합니다.

3. Logic객체의 데이터를 모아서 팝업차트 만들기

데이터를 한데 모아 사용하기 위해서 테이블 기능을 이용합니다. 리본메뉴의 Presentation->New Table버튼을 클릭합니다.

위와 같은 창이 나오면 Logic차트를 더블 클릭하여 아래와 같은 창을 다시 엽니다.

Table 창과 Logic변수 창이 모두 띄워져 있으면 Logic변수 창의 변수를 마우스 오른쪽 클릭하여 Add Monitor Paramiter를 선택합니다.

그리고 Table 창에 해당 변수가 추가되었는지 확인합니다.
※변수는 하나의 객체에서 여러 개를 추가할 수 있고, 다른 Logic객체에서도 추가할 수 있습니다.

여기서 팝업 차트를 띄우기 위해서 변수의 왼쪽에 체크박스를 체크 해줍니다.
※선택해야할 변수가 여러개라면 모두 체크해줍니다.

이후 Show Trend 버튼을 클릭합니다. (그리고 Run상태가 아닐경우 Run버튼을 클릭해줍니다.)

팝업 차트가 정상적으로 돌아가는지 확인합니다.


Tensorflow 라이브러리를 이용하여 Windows Third party 응용프로그램 빌드를 위한 환경 설정

enuSpace for jupiter - work note


Tensorflow 소스 빌드 : http://enuspace.tistory.com/entry/Tensorflowwindow10build



Tensorflow를 이용하여 윈도우환경에서 64bit release용 라이브러리 및 obj 파일이 생성되었다면, 라이브러리를 이용하여 응용 프로그램 개발 환경에 설정을 위한 셋업과정이다.


본장에서는 Tensorflow의 라이브러리를 새로운 dll프로젝트에 추가하여 외부 응용프로그램과 연동하기 위한 플로그인 프로젝트를 목적으로 한다.



dll 프로젝트 생성 및 호출


- Visual Studio를 이용하여 dll 프로젝트를 생성 : Win32 Console Application -> Application type : dll 선택 및 생성


- 기본적으로 dll의 예시코드가 생성된다.


BOOL APIENTRY DllMain( HMODULE hModule,

                       DWORD  ul_reason_for_call,

                       LPVOID lpReserved

)

{

switch (ul_reason_for_call)

{

case DLL_PROCESS_ATTACH:

case DLL_THREAD_ATTACH:

case DLL_THREAD_DETACH:

case DLL_PROCESS_DETACH:

break;

}

return TRUE;

}


- dll은 외부와 연동할 함수를 추가


extern "C" __declspec(dllexport) bool OnInit();

extern "C" __declspec(dllexport) bool OnLoad();

extern "C" __declspec(dllexport) bool OnUnload();

extern "C" __declspec(dllexport) bool OnTask();


- dll의 프로젝트의 작업 환경은 64bit, relese, multibyte옵션 설정을 수행한다. 


- Tensorflow r1.1 윈도우10에서 C++ 컴파일 방법 (x64)에 따라서 생성된 환경을 이용 : http://enuspace.tistory.com/entry/Tensorflowwindow10build


- DLL project 환경에 include 디렉토리 내용을 추가


D:\Workspace\tensorflow

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\external\zlib_archive

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\external\gif_archive\giflib-5.1.4

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\external\png_archive

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\external\jpeg_archive

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\external\eigen_archive

D:\Workspace\tensorflow\third_party\eigen3

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\gemmlowp\src\gemmlowp

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\jsoncpp\src\jsoncpp

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\external\farmhash_archive

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\external\farmhash_archive\util

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\external\highwayhash

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\protobuf\src\protobuf\src

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\grpc\src\grpc\include


- DLL project 환경에 라이브러리 내용 추가.


D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\tf_cc_framework.dir\Release\tf_cc_framework.lib

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\tf_cc_ops.dir\Release\tf_cc_ops.lib

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\tf_core_cpu.dir\Release\tf_core_cpu.lib

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\tf_core_direct_session.dir\Release\tf_core_direct_session.lib

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\tf_core_framework.dir\Release\tf_core_framework.lib

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\tf_core_kernels.dir\Release\tf_core_kernels.lib

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\tf_core_lib.dir\Release\tf_core_lib.lib

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\tf_core_ops.dir\Release\tf_core_ops.lib

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\Release\tf_protos_cc.lib

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\protobuf\src\protobuf\Release\libprotobuf.lib

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\protobuf\src\protobuf\Release\libprotoc.lib

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\tf_cc.dir\Release\tf_cc.lib

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\zlib\install\lib\zlibstatic.lib

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\gif\install\lib\giflib.lib

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\png\install\lib\libpng12_static.lib

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\jpeg\install\lib\libjpeg.lib

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\jsoncpp\src\jsoncpp\src\lib_json\Release\jsoncpp.lib

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\farmhash\install\lib\farmhash.lib

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\highwayhash\install\lib\highwayhash.lib

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\grpc\src\grpc\Release\grpc++_unsecure.lib

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\grpc\src\grpc\Release\grpc_unsecure.lib

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\grpc\src\grpc\Release\gpr.lib


- Tensorflow 프로젝트 라이브러리를 빌드하다보면, 매번 전체 컴파일을 수행한다. 본 dll프로젝트는 reference 항목에 관련 라이브러리를 추가하지 않고 참조 라이브러에 추가를 수행한다. 


- Preprocessor Definitions 항목에 다음 내용을 추가.


NDEBUG

_WINDOWS

_USRDLL

ENUTENSORFLOW_EXPORTS

EIGEN_AVOID_STL_ARRAY

NOMINMAX

_WIN32_WINNT=0x0A00

LANG_CXX11

COMPILER_MSVC

OS_WIN

_MBCS

WIN64

WIN32_LEAN_AND_MEAN

NOGDI

PLATFORM_WINDOWS

TENSORFLOW_USE_EIGEN_THREADPOOL

EIGEN_HAS_C99_MATH

_ITERATOR_DEBUG_LEVEL=0

TF_COMPILE_LIBRARY

CMAKE_INTDIR="Release"

_CRT_SECURE_NO_WARNINGS


위와같이 환경설정을 하고 난후 샘플 tutorial 샘플 코드를(tf_tutorials_example_trainer)참조하여 빌드를 수행한다.


#include "tensorflow/cc/ops/standard_ops.h"

#include "tensorflow/core/framework/graph.pb.h"

#include "tensorflow/core/framework/tensor.h"

#include "tensorflow/core/graph/default_device.h"

#include "tensorflow/core/graph/graph_def_builder.h"

#include "tensorflow/core/lib/core/threadpool.h"

#include "tensorflow/core/lib/strings/stringprintf.h"

#include "tensorflow/core/platform/init_main.h"

#include "tensorflow/core/platform/logging.h"

#include "tensorflow/core/platform/types.h"

#include "tensorflow/core/public/session.h"


extern "C" __declspec(dllexport) bool OnLoad()

{

tensorflow::example::Options opts;

tensorflow::example::ConcurrentSessions(opts);


return true;

}


빌드가 정상적으로 처리된 후 생성된 dll의 OnLoad()함수를 호출하고 나면 다음과 같은 메세지가 나타나며 비정상 종료된다. 
No session factory registered for the given session option: .....

빌드된 dll의 사이즈와 tf_tutorials_example_trainer의 실행 프로그램의 사이즈에 상당한 차이가 있음을 확인할 수 있다.
dll의 프로젝트와 tf_tutorials_example_trainer 플로젝트의 솔루션을 비교해보면 Object Libraries 항목에 obj 파일이 포함되어 있지 않음을 확인할 수 있다. 

워크스페이스에 Object Libraries 항목에 관련 obj 파일을 추가하고, 다시 빌드를 수행한다. 수행결과 dll의 사이즈가 tutorial의 실행프로그램 사이즈와 비슷해졌음을 확인할 수 있다.

다시 호출을 수행하면, 정상적으로 Tensorflow의 응용 프로그램(dll)이 호출됨을 확인할 수 있다. 


---------

참고로 Tensorflow 홈페이지에서 제공하는 basic 코드를 삽입하였을 경우 추가적인 라이브러리 생성 및 추가를 수행한다.


tensorflow 솔루션 오픈, tf_cc 프로젝트 컴파일 수행.

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\tf_cc.dir\Release 디렉토리 tf_cc.lib 생성.

D:\Workspace\tensorflow\tensorflow\contrib\cmake\build\tf_cc.dir\Release\tf_cc.lib 라이브러리 추가.


Download from enuSpace 


https://expnuni.github.io/enuspace_doc/docs/enuspace_download/

Tensorflow r1.1 윈도우10에서 C++ 컴파일 수행기 (x64)

enuSpace for jupiter - work note


Tensorflow r1.1을 이용한 Third party 프로그램 개발에 있어 소스 빌드과정에 대한 수행 내용이다.



준비사항


Known-good configurations (가장 좋은 조합)


컴파일 환경 : Microsoft Windows 10


- Microsoft Visual Studio 2015 with Visual C++ 2015


- Anaconda 4.1.1 (Python 3.5 64-bit) : https://www.continuum.io/downloads


- Git for Windows version 2.9.2.windows.1


- swigwin-3.0.10 : http://www.swig.org/download.html


- [NVidia CUDA Toolkit 8.0] (https://developer.nvidia.com/cuda-downloads)

- [NVidia CUDNN 5.1] (https://developer.nvidia.com/cudnn)


- CMake 3.6 : https://cmake.org/download/


* 가장 좋은 조합을 따라서 컴파일을 수행하여야 한번에 적용이 용이함.


Step by Step (절차)


Run cmd (컴파일 환경 설정)


- D:\Workspace>"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\vcvars64.bat"


CMake and git Path 추가 (Cmd 창에서 명령  수행이 가능하도록 패스추가)


- D:\Workspace>set PATH=%PATH%;C:\Program Files\Git\bin\


Tensorflow r1.1 clone (텐서플로우 1.1 다운로드)


- D:\Workspace>git clone -b r1.1 https://github.com/tensorflow/tensorflow.git


- D:\Workspace>cd tensorflow\tensorflow\contrib\cmake
- D:\Workspace\tensorflow\tensorflow\contrib\cmake> mkdir build
- D:\Workspace\tensorflow\tensorflow\contrib\cmake> cd build
- D:\Workspace
\tensorflow\tensorflow\contrib\cmake\build>
D:\...\build> cmake .. -A x64 -DCMAKE_BUILD_TYPE=Release ^
More? -DSWIG_EXECUTABLE=D:/Workspace/swigwin-3.0.10/swigwin-3.0.10/swig.exe ^
More? -DPYTHON_EXECUTABLE=C:/Anaconda3/python.exe ^
More? -DPYTHON_LIBRARIES=C:/Anaconda3/libs/python35.lib 


튜터리얼 샘플 빌드 수행


MSBuild


- D:\...\build>MSBuild /p:Configuration=Release tf_tutorials_example_trainer.vcxproj


위 절차에서 따라서 새성된 옵션은 release 버젼용으로 컴파일이 된다. 정상적으로 동작을 수행하는지 샘플프로그램을 실행한다.


정상적으로 컴파일 완료후, 샘플 프로그램 테스트.


- D:\...\build>Release\tf_tutorials_example_trainer.exe


debug 버젼의 빌드는 동일한 구성으로 시도하였을 경우 빌드가 용이치 않다. 

makefiles를 수정하며 옵션 변경이 필요하다.


Tensorflow r1.1에 대한 64bit용 release에 대해서만 빌드가 정상적으로 수행되었으며, 32bit 컴파일 과정에 일부 라이브러리의 64bit 컴파일 환경에 따라서 정상적으로 빌드가 되지 않음을 확인하였다. 



참고 사이트 : 

https://github.com/tensorflow/tensorflow/blob/r1.1/tensorflow/contrib/cmake/README.md

https://www.facebook.com/notes/hyeon-gab-shin/windows-10-기반-tensorflow-빌드-및-실행하기/1264305280280854/

    

Web 연동 및 사용방법


본 강좌에서는 enuSpace를 이용하여 웹 브라우져에 화면 디스플레이 및 데이터 인터페이스를 구성하는 방법에 대하여 설명합니다.

enuSpace for mars 다운로드 : http://enuspace.tistory.com/entry/enuSpace-for-Mars-2017


enuSpace는 javascript와 lua script를 제공합니다. 웹 브라우져에서 동적인 현시를 위해서 javascript로 제작합니다.

enuSpace의 내부 구조와 웹 브라우져 랜더러간의 인터페이스 구조는 아래그림과 같습니다.



enuSpace에서 task scheduler는 lua 스크립트로 구현된 ontask()함수를 설정된 주기에 맞추어 호출되어 연산을 수행합니다. 또한, 뷰어가 드로잉시에 호출되는 ontaskview()함수는 루아스크립트와 자바스크립트 모두 이용할 수 있습니다. 웹 브라우져에서 랜더러의 함수 호출시에는 자바스크립트로 적용된 ontaskview()함수만 적용됩니다. 


웹 브라우져는 첫 기동시 서버측에 그래픽 리소스 svg 파일을 요청하며 관련 데이터를 연동합니다. 웹 브라우져는 내부 랜더러에서 서버 사이드에서 가져온 데이터와 ontaskview()함수를 호출하여 자신의 화면을 갱신합니다. 특정값을 제어하기 위해서 SetTagValue() 함수를 호출하여 서버사이드의 값을 제어합니다.  


enuSpace introduce의 설명


enuSpace for mars의 최신 버젼을 다운로드 하시면, 샘플 프로젝트 introduce를 오픈합니다. 


리본메뉴 Data/Communication->Web Browser 버튼을 클릭하여 브라우져를 실행합니다.  

웹 브라우져 창에 사용자 로그인창이 나타나고, 사용자 리스트에 추가된 로그인 정보를 이용하여 로그인을 수행합니다. 



여기에서 살펴볼 내용은 서버 사이드의 로직 변수, 전역변수 그리고 데이터베이스 tag 변수들에 대한 내용과 연동되는 부분과 enuSpace와 웹 랜더러간의 독립된 표현에 대한 부분이다. 

enuSpace 편집기에서 태양주의를 돌고 있는 별을 하나 선택하여 ontaskview() 함수를 확인하여 보면 다음과 같이 구현되어 있다. 



function _ontaskview()

{

rotate = rotate - 0.3;

if (rotate<0)

rotate = 360;

fill = GetValueColor( rotate/5 );

}

선택한 path객체(star)는 자신의 회전값을 0.3씩 줄이는 코드이며 0이하로 떨어진경우에는 초기값 360도로 설정하는 코드이다. 본 코드의 내용으로는 enuSpace의 서버와 웹 브라우져간의 동일한 현시를 수행하는 코드의 처리방식이 아니다.

만약 객체의 서버사이드의 회전값과 동일한 디스플레이를 수행하고자 하는 경우에는 다음과 같이 코드를 수정하여 보자.


main.svg를 선택하고 최상단에 전역변수를 하나 설정한다. 변수명은 g_rotate_star으로 하고 double 형으로 생성한다. 




생성된 g_rotate_star변수의 값을 갱신하는 코드를 추가하여야 한다. 이미 Main features 글자 객체 왼쪽에 원객체가 추가 되어 있다. 원 객체를 선택하고 Properties 윈도우의 Event 속성을 보면 Script Type에 text/lua 설정되어 있으며, ontask()함수를 수정한다. 



다음과 같이 추가 코드를 작성한다.

     g_rotate_star = g_rotate_star - 0.3 

if (g_rotate_star<0) then 

g_rotate_star = 360 

end


다음으로 그래픽 path 객체(star)의 ontaskview()함수를 다음과 같이 수정하자.

수정 전)

function _ontaskview()

{

rotate = rotate - 0.3;

if (rotate<0)

rotate = 360;

fill = GetValueColor( rotate/5 );

}

수정 후)

function _ontaskview()

{

rotate = g_rotate_star;

fill = GetValueColor( rotate/5 );

}


수정후 전역변수의 값을 이용하여 회전값을 적용하도록 구성하였다. 


enuSpace의 기동화면 모습과 웹 브라우져에서의 랜더링 출력 위치가 동일한 위치에서 출력되고 있음을 확인할 수 있다. 위 예제는 전역변수를 이용한 인터페이스 방법에 대하여 설명한 내용이다. 전역변수, 로직객체의 pin 변수, 데이터베이스의 tag변수는 동일한 형태로 연계하여 웹 브라우져에 동일한 디스플레이가 가능합니다.  


데이터베이스 TAG 인터페이스


데이터베이스 TAG를 이용하여 인터페이스를 위하여 데이터베이스 TAG 변수 하나를 추가합니다.  

TYPE : double

TAGID : @Presentation.rotate

VARIABLE : rotate


전역변수값을 디스플레이 위한 Text 객체를 추가하고 ontaskview()함수에 디스플레이 코드를 추가합니다.

function _ontaskview()

{

//TODO Add your javascript code here

textContent = GetTagValue("@Presentation.rotate").toString();

}


사각형 객체 2개를 추가하고, 각각 데이터베이스 TAG의 값을 변경하는 코드를 추가합니다.

function _onmousedown()

{

//TODO Add your javascript code here

SetTagValue("@Presentation.rotate", 90);

}


function _onmousedown()

{

//TODO Add your javascript code here

SetTagValue("@Presentation.rotate", 45);

}



enuSpace의 RunTime에서 사각형 객체를 클릭하여 Tag값이 변경됨을 확인할 수 있으며, 클라이언트 웹 브라우져에서 사각형 객체를 클릭하여 tag값이 변경되어 디스플레이 됨을 확인할 수 있습니다.




전역변수 및 로직객체 PIN 변수의 인터페이스


enuSpace에서는 전역변수와 로직객체의 PIN 변수의 인터페이스를 위하여 SetValue(), GetValue() 함수를 제공합니다.


SetValue 함수의 사용 예)

function _onmousedown()

{

//TODO Add your javascript code here

SetValue("ID_ARD.A0", 99);

}


GetValue 함수의 사용 예)

function _ontaskview()

{

//TODO Add your javascript code here

textContent = GetValue("ID_ARD.A0").toString();

}


* GetValue의 함수는 클라이언트 웹에서 특정 이벤트에 의해서 서버의 값을 가져와 처리하는 경우에 사용하며, 일반적으로 다음과 같이 코드를 사용하기를 권고합니다. (빠른 응답 속도)

textContent = GetValue("ID_ARD.A0").toString();  => textContent = ID_ARD.A0.toString();


* SetValue의 함수 또한 클라이언트 웹에서 특정 이벤트에 의하여 서버의 값을 설정하는 경우에 사용하며, 일반적으로 다음과 같이 코드를 사용하기를 권고합니다. (빠른 응답 속도)

SetValue("ID_ARD.A0", 99); => ID_ARD.A0 = 99;


본 강좌에서는 웹 브라우져와 연동시에 사용하는 함수에 대하여 알아보았습니다. 


-이엔유 주식회사-

IoT Platform 사용방법


본 강좌에서는 enuSpace for mars를 이용하여 IoT 디바이스의 센서값을 취득 및 데이터 로직을 구성하는 방법에 대하여 설명합니다.

enuSpace 학생용 버젼 다운로드 : http://enuspace.tistory.com/entry/enuSpace-for-Mars-2017


준비물

Raspberry PI, Arduino, sensor


프로그램 설치


1. Raspberry PI Installation (software)


enuSpace for mars와 연동하기 위하여 Raspberry PI에 windows 10 iot core 운영체제를 설치후 다운로드 링크에서 응용 프로그램을 설치합니다.


windows 10 iot core 설치 

설치 가이드 : https://developer.microsoft.com/ko-kr/windows/iot/GetStarted

마이크로소프트사에서 제공하는 설치 가이드를 기반으로 단계별로 설치 절차를 진행합니다.

윈도우 Edge 또는 웹브라우져를 이용하여 Window 10 iot core가 설치된 Raspberry PI에 접속을 수행합니다.



Windows 10 IoT Core의 기본 App의 IoTCoreDefaultApp 실행 화면입니다.



아래 그림과 같이 Raspberry PI와 Arduino 디바이스간에 USB Serial을 통하여 연결을 수행하고 아두이노에 센서 2종을 연결한 화면입니다.



Windows 10 IoT Core가 설치된 Raspberry PI에 아래 링크의 응용프로그램을 설치합니다. 


download link : http://enuspace.tistory.com/entry/enuSpace-for-Mars-2017

Windows 10 Core App : enuSpace_IoT (enuSpace_IoT_1.0.3.0_x86_x64_arm.appxbundle)



설정해상도는 1920 *1080으로 설정하여야 정상적인 디스플레이가 가능합니다.



App package 에서 다운로드한 파일을 선택합니다.




Go 버튼을 클릭하여 설치를 수행합니다.



설치를 완료 합니다.


Arduino Installation (software) 


아두이노 디바이스에 아두이노 IDE에서 제공하는 StandardFirmata 프로그램을 설치합니다. 

아두이노 IDE : https://www.arduino.cc/en/Main/Software

라즈베리 파이(Raspberry PI)와 아두이노(Arduino)간에는 StandardFirmata를 이용하여 통신을 수행합니다.


프로그램 기동


Raspberry PI와 Arduino에 프로그램을 설치 마무를 하였다면, 서버 프로그램을 기동합니다. enuSpace 프로그램을 기동하여 새로운 프로젝트를 생성합니다. 

enuSpace의 웹서버를 기동합니다. 웹 서버를 기동하기 전에 리본메뉴 Data/Communication->System Configuration 버튼을 클릭하여 웹서버 사용 유무 및 ip와 포트를 설정합니다.


리본메뉴 Data/Communication->Web Server의 Start 버튼을 클릭하여 서버를 기동합니다. 




서버 사이드 준비사항은 여기까지 입니다. 

라즈베리 파이 응용프로그램을 기동하여 enuSpace 프로그램에 디바이스 등록과정을 통하여 센서의 데이터 및 입출력 핀 제어를 수행합니다.


Raspberry PI -> enuSpace iot 응용프로그램 기동 


라즈베리 파이에 설치한 enuSpace iot 응용프로그램을 실행합니다. 상단의 Server URL의 정보를 enuSpace서버의 ip주소와 포트 정보를 입력합니다.


enuSpace 서버사이드에 본 디바이스를 접속하고자 하는 경우 서버 사이드에 사용자 등록되어 로그인을 수행하여야 합니다. 신규 프로젝트를 생성시에는 사용자 등록 버튼을 클릭하여 사용자 등록을 수행합니다. 


로그인 페이지는 자동 로그인 체크박스, 로그인 버튼, 아이디 찾기/비밀번호 찾기, 사용자 등록 버튼으로 구성, 자동 로그인 체크를 수행후 로그인을 실행하면, 다음 프로그램 재 기동시에는 자동 로그인이 수행됩니다. 

로그인 페이지에서 사용자 등록버튼을 클릭하면, 아래 그림과 같이 사용자 등록을 수행하는 페이지로 전환되면, 사용자 등록 버튼을 클릭을 수행하면, 설정된 서버 주소(enuSpace 서버 사이드)에 사용자 등록 요청을 수행합니다.



정상적으로 사용자 등록과 로그인 페이지가 완료되면, 디바이스 등록 페이지가 나타납니다.



디바이스의 타입은 현재 연결된 아두이노의 타입을 설정합니다. 디바이스 키는 통합 저작 도구 IOT 서버에 등록될 디바이스 키 정보이며, 라즈베리 파이의 시스템 이름을 활용합니다.

신규 디바이스를 등록하는 경우에는 관련 디바이스의 정보와 변수 정보를 enuSpace에 등록하는 과정입니다. 디바이스 등록 버튼을 클릭합니다.



아두이노와 연결된 시리얼 포트 리스트에서 아두이노와 연계된 시리얼 포트를 선택후 연결 버튼을 클릭하여 연결 수행합니다. 연결이 정상적으로 수행이 되면, 아두이노의 센서 데이터값이 현시되며, enuSpace에 등록된 서버에 전송을 수행하여 서버 사이드에서 데이터베이스화 되어 저장됩니다. enuSpace 서버 응용 프로그램에서 리본메뉴 Device List와 DB Show 버튼을 클릭하여 등록된 내용을 확인할 수 있습니다.


enuSpace 서버 사이드에서 프로그램 설치시 사용된 라이브러리를 불러와 화면 작도를 수행합니다. 아두이노 디바이스 심볼 객체의 속성 interface 설정값을 true로 설정하고, interface-id 항목에 #+디바이스 이름을 입력합니다. 이 작업은 디바이스와 디바이스의 tag db의 값이 그래픽적인 라이브러리에 인터페이스 됨을 의미합니다.


사용자 정의 device 심볼을 구성하고자 하는 경우에는 아래와 같은 절차를 따라서 생성합니다.

Project Explorer 하위 Libarary의 Logic에 라이브러리 파일을 생성하고, 디바이스 라이브러리 노드 이름을 입력하고 노드를 생성합니다. 로직의 핀을 추가하고 추가된 핀의 name 속성값을 device의 variable이름으로 설정합니다. 



다음 강좌에서는 클라이언트 웹 브라우져에서 랜더링을 위한 enuSpace 서버 사이드에서의 화면 구현 및 javascript 코드 구현 방법에 대하여 알아보겠습니다. 

-이엔유 주식회사-

enuSpace 시뮬레이션 기능 및 Data Visualization 사용방법


본 강좌에서는 enuSpace for mars를 이용하여 시뮬레이션을 수행하는 방법에 대하여 설명합니다. 

enuSpace 학생용 버젼 다운로드 : http://enuspace.tistory.com/entry/enuSpace-for-Mars-2017


enuSpace for mars에서 시뮬레이션 또는 task를 개발함에 있어 2가지 형태의 모델로 구성될 수 있습니다. enuSpace for mars의 ontask함수를 활용한 방법과 외부의 task의 모듈을 연동하는 방법입니다.


Lesson5 sample : lesson5.zip


1. 로직 라이브러리를 이용한 flowbased programming 방법.

2. 외부 모델을 이용한 연동 방법.


동영상 미리보기


New Project


새로운 프로젝트를 생성하기 위해서 Home->New->New Project메뉴를 이용하여 새로운 프로젝트를 생성합니다.



Simulation Time Setup


새로운 프로젝트 생성을 완료하였다면, 리본메뉴 Data/Communication->System Configuration메뉴를 선택하여 System Configuration 대화창의 속성을 설정합니다. 시뮬레이션용으로 설정하기 위해서는 Time의 속성중 Simulation Time을 설정합니다. Simulation Time을 설정하게 되면 enuSpace에서 기동되는 시작시간의 정보는 0초부터 동작을 수행합니다. 

System Time옵션에서 Simulation Time옵션으로 변경 수행시 프로젝트에 기존에 누적된 히스토리 데이터베이스가 모두 제거되어 초기화 됩니다. 프로젝트 로드시에도 기존의 히스토리 데이터베이스를 초기화 합니다.

참고로 System Time의 설정은 현재시간(UTC)을 기준으로 모든 데이터가 생성되고  히스토레 데이터에 누적됩니다.  



Simulation Scheduling


enuSpace for mars의 task()함수를 사용하는 경우에는 flowbased programming을 통하여 동작을 수행합니다. 내부 task()함수는 스케쥴링 속성값에 따라서 주기적인 연산을 호출하도록 구성되어 있습니다. 속성 설정하기 위해서 Project Explorer창 Task하위 logic_svg 아이템을 선택합니다. logic_svg 속성창 중 Cycle (Hz) 속성은 1초에 1, 2, 3, 4, 6, 8, 12, 24회 호출 주기에 대한 설정입니다. Task In/Out의 속성은 선택한 Task에 대하여 연산을 수행할 것인지, 제외할것인지를 설정합니다. 



시뮬레이션 모델을 제작하다보면 task()함수에서 delta T값을 이용하는 경우가 있습니다. 전역변수 dt값을 이용하여 코드를 구현합니다.


function _ontask()

--TODO Add your lua script code here

local deltaT = dt

--bla bla ~~

end


외부 모델 연계 API

시뮬레이션 모델 개발시 기존의 코드를 재활용하거나 외부의 모델과의 인터페이스가 필요한 경우가 있습니다. enuSpace는 외부 모델과 연동하기 위한 인터페이스 모듈을 제공합니다. 외부 모델과 연계시 dynamic link library(dll)을 이용합니다.

외부 연동 인터페이스 모듈의 dll의 주요 함수는 아래와 같습니다.


extern "C" __declspec(dllexport) bool OnInit();

extern "C" __declspec(dllexport) bool OnLoad();

extern "C" __declspec(dllexport) bool OnUnload();

extern "C" __declspec(dllexport) bool OnTask();


각 함수는 아래와 같은 조건에서 호출됩니다.

OnInit() : 첫 기동시 호출되는 초기화 함수

OnLoad() : dll 로드수행시 호출되는 함수

OnUnload() : dll 언로드 수행시 호출되는 함수

OnTask() : 스케쥴링 주기에 따라서 호출되는 함수


OnTask()함수 구현부에는 시뮬레이션을 수행하고자 하는 알고리즘을 추가합니다. 작성된 코드와 enuSpace와 연동하기 위해서 인터페이스용 콜백함수 4개를 제공합니다. 


extern "C" __declspec(dllexport) void SetCallBack_SetValue(void fcbSetValue(wchar_t*, double));

extern "C" __declspec(dllexport) void SetCallBack_GetValue(DBDataStruct* fcbGetValue(wchar_t*));

extern "C" __declspec(dllexport) void SetCallBack_SetArrayValue(void fcbSetArrayValue(wchar_t*, void*, int, int));

extern "C" __declspec(dllexport) void SetCallBack_GetArrayValue(DBDataStruct* fcbGetArrayValue(wchar_t*));


특정 데이터베이스의 Tag값을 읽고 쓰기 위한 함수 포인터입니다. 본 함수는 dll로드 수행시 함수의 포인터로 전달됩니다. 전달된 함수 포인터 이용하여 값을 읽거나 쓰기를 수행합니다. 


구현부를 보시면 아래와 같습니다.


void (*g_fcbSetValue)(wchar_t*, double) = NULL;

DBDataStruct* (*g_fcbGetValue)(wchar_t*) = NULL;

void(*g_fcbSetArrayValue)(wchar_t*, void*, int, int) = NULL;

DBDataStruct* (*g_fcbGetArrayValue)(wchar_t*) = NULL;


extern "C" __declspec(dllexport) void SetCallBack_SetValue(void fcbSetValue(wchar_t*, double)) g_fcbSetValue = fcbSetValue; }

extern "C" __declspec(dllexport) void SetCallBack_GetValue(DBDataStruct* fcbGetValue(wchar_t*)) g_fcbGetValue = fcbGetValue; }

extern "C" __declspec(dllexport) void SetCallBack_SetArrayValue(void fcbSetArrayValue(wchar_t*, void*, int, int)) g_fcbSetArrayValue = fcbSetArrayValue; }

extern "C" __declspec(dllexport) void SetCallBack_GetArrayValue(DBDataStruct* fcbGetArrayValue(wchar_t*)) g_fcbGetArrayValue = fcbGetArrayValue; }


위 코드는 기 제공되는 코드의 예시입니다. 


CMap<CString, LPCWSTR, DBDataStruct*, DBDataStruct*> g_DBMapList;

void SetArrayValue(CString strVariable, void* pSrc, int iType, int iSize)

{

if (g_fcbSetArrayValue)

g_fcbSetArrayValue(strVariable.GetBuffer(0), pSrc, iType, iSize);

}

DBDataStruct* GetArrayValue(CString strVariable)

{

if (g_fcbGetArrayValue)

return g_fcbGetArrayValue(strVariable.GetBuffer(0));

return NULL;

}

void SetValue(CString strVariable, double fValue)

{

double fReturn = 0;

DBDataStruct* pData = NULL;

g_DBMapList.Lookup(strVariable, pData);

if (g_fcbSetValue && pData == NULL)

{

pData = g_fcbGetValue(strVariable.GetBuffer(0));

g_DBMapList.SetAt(strVariable, pData);

}

if (pData && pData->pValue)

{

switch (pData->itype)

{

case DEF_INT:

*(int*)pData->pValue = (int)fValue;

break;

case DEF_FLOAT:

*(float*)pData->pValue = (float)fValue;

break;

case DEF_DOUBLE:

*(double*)pData->pValue = fValue;

break;

case DEF_BOOL:

if (fValue == 1)

*(bool*)pData->pValue = true;

else

*(bool*)pData->pValue = false;

break;

case DEF_WCHAR:

break;

default:

break;

}

}

}

double GetValue(CString strVariable)

{

double fReturn = 0;

DBDataStruct* pData = NULL;

g_DBMapList.Lookup(strVariable, pData);

if (g_fcbGetValue && pData == NULL)

{

pData = g_fcbGetValue(strVariable.GetBuffer(0));

if (pData)

g_DBMapList.SetAt(strVariable, pData);

}

if (pData && pData->pValue)

{

switch (pData->itype)

{

case DEF_INT:

fReturn = *(int*)pData->pValue;

break;

case DEF_FLOAT:

fReturn = *(float*)pData->pValue;

break;

case DEF_DOUBLE:

fReturn = *(double*)pData->pValue;

break;

case DEF_BOOL:

if (*(bool*)pData->pValue == TRUE)

fReturn = 1;

else

fReturn = 0;

break;

default:

break;

}

}

return fReturn;

}


실제 인터페이스는 값을 읽기 쓰기위한 코드와 모델 연산로직 코드를 추가함으로서 외부 모델을 연계할 수 있습니다. 


모델 예)

모델의 실행 코드와 인터페이스 코드 예시


double display[16][16];

float initValue = 1.0f;


extern "C" __declspec(dllexport) bool OnTask()

{

initValue = initValue + 0.1;

for (int x = 0; x < 16; x++)

{

for (int y = 0; y < 16; y++)

{

display[x][y] = 1.0 + sin(double((x * 16) + (y * 16)) / 3.141592 / 5 + initValue);

}

}

SetArrayValue(L"@CORE.display[0][0]", display, DEF_DOUBLE, 16 * 16);

return true;

}


sin파를 생성하여 데이터 인터페이스를 수행하는 코드를 작성하였습니다. 위와 같이 코드를 추가하고 컴파일을 수행하여 CoreTask.dll을 생성합니다. 모델 생성이 완료하였다면 데이터베이스와 연동하기 위한 tag id를 enuSpace 프로젝트에 추가를 수행합니다. SetArrayValue()함수는 배열 정보를 enuSpace에서 추가한 tag의(@CORE.display[0][0]) 값에 연산 결과를 전달하는 과정입니다. 


SetArrayValue() 함수의 파라미터 정보를 보면 변수명, 원본 데이터의 메모리 주소, 복사하고자하는 데이터 타입, 사이즈값입니다. 만약 단일 변수에 추가하고자 하는 경우에는 SetValue()함수를 이용합니다. 경우에 따라서 위의 예시에서 제공하는 SetValue()함수 등은 확장 및 변경하여 구현할 수 있습니다.


enuSpace for mars 데이터베이스 TAG 추가


enuSpace의 리본메뉴 Data/Communication->DB Show 버튼을 클릭합니다. 다음과 같이 DB Table의 정보가 나타나고 DB+ 버튼을 클릭하여 모델간의 인터페이스를 위한 TAG 변수를 추가합니다. 추가되는 최종 TAG ID는 @문자가 앞에 추가됩니다. @문자는 데이터베이스 TAG 변수와 전역변수와의 구분자로도 활용됩니다. 데이터베이스 TAG ID를 이용하여 스크립트에서 활용합니다.



정상적으로 데이터베이스 TAG가 추가완료 후 앞에서 제작한 외부 TASK(CoreTask.dll)를 enuSpace 프로젝트에 추가합니다. Project Explorer의 Task항목을 선택하고 팝업메뉴 Add Task를 선택하여 Task Module의 콤보박스에 CoreTask.dll을 선택합니다. 프로젝트 디렉토리 lesson5//Task//CoreTask에 앞에서 생성한 CoreTask.dll 파일이 존재하는 경우 자동으로 콤보박스에서 선택이 가능하도록 제공이 됩니다. 



디렉토리의 구조 및 외부 TASK의 위치는 아래 그림과 같습니다.



TASK가 정상 등록이 되었다면, TASK를 기동하기 위해서 리본메뉴 Home->Script Operation의 Run 버튼을 클릭합니다. 연산이 정상적으로 처리되고 있는지를 확인하기 위해서 리본메뉴의 리본메뉴의 Data/Communication->DB Show메뉴를 선택하여 데이터베이스의 실시간 값을 확인합니다. 



아래 그림과 같이 차트 버튼을 클릭하여 팝업 Trend를 이용하여 데이터값을 확인할 수 있습니다. 차트사용 방법은 별도의 강좌에서 설명하도록 하겠습니다. 



3D data visualization


앞에서 제작한 배열변수의 값을 3차원 디스플레이에 디스플레이 하기 위해서 픽쳐파일 core_display.x3d 파일을 추가합니다. 추가된 x3d 파일을 선택후 Terrain객체를 추가합니다. Terrain 객체의 속성중 subdivision_x, subdivision_y의 값을 데이터베이스 TAG의 배열정보 16, 16으로 설정합니다. subdivision의 값을 설정함에 따라 내부의 double형 데이터 변수 data[16][16]가 생성됩니다.



추가된 Terrain 객체에 javascript 또는 lua script를 이용하여 데이터베이스 tag의 값을 그래픽 객체의 디스플레이 객체에 전달하여 실시간 데이터를 디스플레이 하기 위해서 아래 예시 코드와 같이 memcpy() 함수를 이용합니다. memcpy() 함수를 이용하지 않고 개별적인 인터페이스는 

data[0][0] = @CORE.display[0][0];

data[0][1] = @CORE.display[0][1]; ... 와 같이 코드를 작성할 수 있습니다.


* memcpy함수 사용시 변수의 타입과 변수 사이즈 입력에 주의하여야 한다. 잘못된 인자의 사용으로 인한 메모리 릭 또는 비정상 종료가 발생할 수 있습니다.    


ex) lua script

function _ontaskview()

--TODO Add your lua script code here

memcpy(&data[0][0],&@CORE.display[0][0],16*16)

end

ex) javascript

function _ontaskview()

{

//TODO Add your javascript code here

memcpy(&data[0][0],&@CORE.display[0][0],16*16);

}



2D data visualization


앞 강좌에서 기초객체의 속성값을 이용하여 2D 그래픽에 가시화하는 방법에 소개하였습니다. 간략히 살펴보면 추가된 객체를 선택하고 ontaskview의 함수를 추가합니다. enuSpace는 javascript와 lua script를 지원하며 각각의 예시는 아래와 같습니다.


function _ontaskview()

{

//TODO Add your javascript code here

textContent = @CORE.display[0][0];

}

function _ontaskview()

--TODO Add your lua script code here

text = string.format("%f", @CORE.display[0][0])

end


데이터베이스의 tag 값을 가져오기 위해서는 데이터베이스 tag id를 이용합니다. 데이터베이스 변수는 첫문자에 @문자를 포함합니다. 



데이터베이스의 값을 가져와 Text 객체의 값으로 할당하는 예시 화면.

사각형의 객체를 가져와 연산 결과를 높이값으로 표현하기 위해서 아래와 같이 코드를 추가합니다.


function _ontaskview()

{

//TODO Add your javascript code here

height = @CORE.display[0][15]*50;

}



시뮬레이션 상태값 저장 및 복원 (Snap, Reset) 기능


enuSpace 시뮬레이션 기능은 현재 설정된 상태값을 저장하고 저장된 상태값에 대한 복원 기능을 제공합니다. 상단의 리본메뉴 Home->Condition의 Snap 버튼과 Reset 버튼을 이용합니다. 


다음 강좌에서는 Trend 객체와 히스토리 팝업 Trend의 기능 및 사용방법에 알아보겠습니다.

-이엔유 주식회사- 

LOGIC 프로그램밍, HMI라이브러리 인터페이스 방법


본 강좌에서는 로직 라이브러리를 이용하여 로직 프로그래밍을 수행하고, HMI 화면구성을 통하여 사용자 인터페이스 모니터링 및 제어화면을 구성하여 봅니다.


New Project

새로운 프로젝트를 생성하기 위해서 Home->New->New Project 메뉴를 선택합니다.

New Project (popup window)윈도우가 나타나면, 솔루션 이름과 솔루션을 저장할 디렉토리를 설정후 OK버튼을 클릭합니다.

Import Library

기존 제작한 Logic 및 hmi 라이브러리르 가져오기 위해서, Project Explorer의 Library의 팝업메뉴 Add Existing Hmi Library 메뉴를 이용합니다.

예시로 enuSpace for mars 설치시 포함된 presentation 디렉토리의 logic 라이브러리 파일을 선택하여 가져오기를 수행합니다. 기존 라이브러리는 유지하고, 본 프로젝트의 Library 디렉토리에 파일을 복사수행 후 로드를 수행합니다.

Properties 윈도우에서 상단의 콤보박스를 이용하여 해당사하는 라이브러리의 썸네일 이미지를 확인할 수 있습니다.  

불러온 라이브러리를 편집하고자 하는 경우에는, Project Explorer의 Library에서 HMI 또는 Logic의 파일의 하위의 심볼 아이템을 선택하여 Graphic 편집알 통하여 심볼을 편집합니다. 


New Picture

Create New Picture file

2개의 픽쳐화면을 생성합니다. 하나의 화면에는 로직 프로그래밍을 위한 픽쳐 페이지이고, 로직 프로그래밍에서의 입출력 변수 변수값을 사용자에게 제공할  HMI 화면작도를 위한 픽쳐입니다.

- 각종 연산 및 제어를 위한 로직을 구성하기 위해서 logic_picture.svg 파일을 추가합니다. 

- logic_picture.svg 파일에서 구성한 로직을 제어하기 위한 hmi_picture.svg 파일을 추가합니다.

본 강좌에서는 로직변수를 HMI변수에 적용하는 방법에 대하여 설명합니다. 

우선 간단하게 로직 페이지에 임의의 로직 객체를 추가합니다. 아래그림과 같이 로직을 추가하고 각각의 로직 객체의 id값을 고융한 id로 설정합니다.

로직 페이지 구성을 완료하였다면, hmi_picture.svg 파일에 로직의 값을 표현할 HMI 객체를 추가합니다.

Set Attribute

HMI 객체의 Properties 윈도우의 Variable Window를 확인하여 보면, 내부 멤버변수(Attribute)와 할당될 Assing 변수(Set Attribute)할당 부분이 있습니다. HMI 객체 제작시 제작자가 제공하는 인터페이스입니다. 자세한 구현 부분을 보고자 하는 경우에는 라이브러리 편집 모드에서 자세한 코드 구현 부분을 확인하시면 됩니다. 

본 예에서서는 추가된 HMI 객체에 logic_picture.svg파일에서 추가한 객체의 입력값을 인터페이스 합니다. 로직객체 ID_SINE_DOUBLE객체의 output값을 HMI객체에 연결하기 위해서 Set Attribute의 속성에 #+로직변수명을 입력합니다. 

추가한 HMI 라이브러리 gauge_pie의 라이브러리 제작은 아래와 같이 구성되어 있습니다. 인터페이스를 위한 멤버변수 m_value값에 따라서 게이지값을 표현되도록 구현된 라이브러리 입니다. gauge_pie의 라이브러리는 내부 구성을 보면 svg의 path객체가 포함되어 있습니다. path객체의 속성 d값을 변경하여 값에 따라 회전위치 정보를 계산하는 로직입니다. svg의 path정보는 사이트에서 좀더 자세히 확인해 보실수 있습니다.

참고 : https://www.w3schools.com/graphics/svg_path.asp

function _ontaskview()

{

//TODO Add your javascript code here

var datagap = m_max-m_min;

var data = m_value;


if (data < m_min)

data = m_min;

else if (data >m_max)

data = m_max;

var angle = ((360 * (data-m_min)) / (m_max - m_min) - 90);

// M40,40 L35.42,79.76 A40.00,40.00 0 1,0 40.00,0.00 Z

var x1 = 80+Math.cos(angle * 3.141592 / 180)*80;

var y1 = 80+Math.sin(angle * 3.141592 / 180)*80;

var dir = 0;


if (angle+90>180)

dir = 1;


ID_GAUGE.d = "M80,80 L"+x1.toString()+ ","+y1.toString()+" A80.00,80.00 0 "+ dir.toString()+",0 80.00,0.00 Z";

ID_LABEL.textContent = m_value.toString();

ID_GAUGE.fill = m_color;

}

내부 페이지 또는 별도의 페이지에 존재하는 로직 객체의 변수를 HMI 객체에 연동하는 방법에 대하여 알아보았습니다. 


다음 강좌에서는 시뮬레이션 사용방법에 대하여 알아보도록 하겠습니다.

-이엔유 주식회사-




enuSpace를 이용한 LOGIC 라이브러리 생성 및 적용 방법


본 강좌에서는 로직 라이브러리 생성 방법과 생성된 로직을 이용하여 프로그래밍 방법에 대하여 설명합니다.

강좌샘플 : lesson3.zip


동영상 미리보기



New Project

새로운 프로젝트를 생성하기 위해서 Home->New->New Project메뉴를 선택합니다.


New Project (popup window)윈도우가 나타나면, 솔루션 이름과 솔루션을 저장할 디렉토리를 설정후 OK 버튼을 클릭합니다.


New Logic library

Project Explorer->Library->Logic 아이템을 선택후 마우스 오른쪽 버튼을 클릭하여 팝업메뉴를 호출합니다. 팝업메뉴 Add New Hmi Library를 선택하여 라이브러리 이름을 입력합니다.

두개의 입력을 받아서 더하기 연산을 수행하는 ADD 로직 라이브러를 생성하기 위해서, Project Explorer에 추가된 logic_library.svg 파일을 선택, 팝업메뉴 Add Symbol을 선택하여 심볼의 이름을 ADD로 입력하고 New 버튼을 클릭합니다.


추가된 ADD 라이브러리를 선택하고 디자인을 수행합니다. 간단하게 사각형 객체와 Path 객체를 추가후

Ribbon Menu->Home->Connection Pin을 선택후 Graphic 윈도우에 마우스를 클릭하여 Connection Pin 객체를 생성합니다. 두개의 입력과 하나의 출력 핀을 생성하여 배치를 수행합니다.

배치를 모두 마치고나면, 각 핀의 이름을 설정합니다. 설정된 입력핀은 스크립트에서 사용되는 변수명으로 사용됩니다.

입력 핀과 출력 핀의 색상을 바꾸어 직관적 이해가 가능하도록 구성합니다.

위와 같이 입출력핀 구성을 마무리 하였다면, 라이브러리에 로직용 스크립트를 추가합니다. 라이브러리의 멤버함수 ontask() 함수를 추가합니다.

function _ontask()

--TODO Add your lua script code here

output = input1 + input2

end

이로써 더하기 연산을 수행하는 ADD 로직 라이브러리가 완성되었습니다. 추가적인 디자인과 현재값을 현시하는 라벨을 추가하거나 다양한 표현을 추가적으로 구성할 수 있습니다. 


Using Logic Library in picture

앞에서 제작한 로직 라이브러리를 이용하여 로직화면을 구성하도록 하겠습니다.

Project Explorer의 Picture를 선택후 오른쪽 버튼을 클릭하여 New Picture file 다이얼로그를 호출합니다. filename을 sample을 일력하여 새로운 픽쳐파일을 생성합니다.

Logic 라이브러리 창을 클릭후 앞에서 생성한 라이브러리를 선택후 Drag & Drop으로 객체를 생성합니다.

로직을 연산을 수행하기 위해서 Ribbon Menu->Home->Script operation의 Run 버튼을 클릭하여 기동을 수행합니다. 

추가된 객체를 마우스를 이용하여 더블 클릭하면, 로직의 입출력 테이블이 나타납니다. 테이블의 값 부분을 더블 클릭하여 입력값을 수정합니다.

입력값에 따라서 변경되는 것을 확인할 수 있습니다. 

아래 그림과 같이 로직 객체를 추가하여 Ribbon menu의 Home->Transfer 메뉴를 이용하여 객체간에 연결을 수행합니다.

테이블의 입력값을 조정하여 로직을 연산결과를 확인할 수 있습니다.

팝업 테이블의 변수리스트를 다중 선택하여 팝업 TREND로 데이터를 확인할 수 있습니다. 

Trend의 활용법은 별도의 강좌에서 설명하도록 하겠습니다.


다음 강좌에서는 logic객체의 변수값을 hmi객체에 값을 적용하는 응용에 대하여 알아보도록 하겠습니다.

-이엔유 주식회사-


enuSpace를 이용한 HMI 라이브러리 생성 및 적용 방법 (2/2)


본 강좌에서는 다이나틱 데이터 디스플레이를 HMI Panel 라이브러리 제작하는 과정을 포함하고 있습니다.

enuSpace를 이용한 HMI 라이브러리 생성 및 적용 방법(1/2)


강좌샘플 : lesson2.zip


enuSpace를 이용한 HMI 라이브러리 생성 및 적용 방법(1/2)절에 이어서 심볼의 사이즈 조정인자와 심볼의 색상, 라벨의 색상값을 설정할 수 있는 인터페이스를 추가합니다.


Project Explorer에서 LABEL_VALUE를 선택후 Properties창에서 Variable Window를 선택합니다. 다음과 같이 4개의 변수를 추가합니다.

double m_width;                // 라이브러리 폭 조정인자

double m_height;               // 라이브러리 높이 조정인자

wchar m_backcolor;            // 라이브러리 패널 색상 조정인자

wchar m_labelcolor;            // 라이브러리 라벨 색상 조정인자


라이브러리에 추가된 멤버변수는 onload() 함수를 통하여 연계를 수행합니다. onload() 함수는 객체가 초기에 로드시 호출되며, 멤버변수의 속성을 변경 수행시 호출되는 함수입니다.

추가된  코드 내용을 보면 아래와 같습니다.

function _onload()

{

//TODO Add your javascript code here

ID_PANEL.width = ID_PANEL.translate_x + m_width;

ID_PANEL.height = ID_PANEL.translate_y + m_height;

ID_PANEL.fill = m_backcolor;

ID_LABEL.stroke = m_labelcolor;

ID_LABEL.translate_x = ID_PANEL.width/2;

ID_LABEL.translate_y = ID_PANEL.height - ID_PANEL.height/5;

}

ID_PANEL의 폭값은 ID_PANEL의 위치 이동값과 사용자가 업데이트한 또는 초기화된 값의 합으로 설정되며, 높이 또한 동일한 연산을 통하여 ID_PANEL의 사이즈롤 조정합니다. 

또한, 패널의 내부 색상값은 멤버변수 m_backcolor값과 라벨의 폰트 색상은 m_labelcolor의 값을 이용하여 연계됩니다. 

패널의 사이즈 조정시 라벨의 위치값도 조정을 해주어야 합니다. 라벨의 속성중 text_anchor의 값은 middle로 설정되어 있기 때문에 폭의 중간값으로 설정하고 높이는 패널 높이의 4/5위치에 배치시켰다.


코드를 Compile 버튼을 클릭후 이전장에서 추가한 Project Explorer의 Picture의 sample.svg 파일을 오픈한다. 오픈을 수행하면 이전에 생성된 객체의 속성을 유지하고 있기 때문에 재로딩을 수행한다. 단축키 F5 버튼을 누르면 픽쳐페이지를 재로딩을 수행합니다. 수정한 라이브러리의 속성이 나타납니다.


sample.svg 픽쳐에 여러개의 LABEL_VALUE객체를 추가하여 각 객체의 멤버변수의 값을 조정하여 테스트를 합니다. 색상값을 입력할 경우 rgb(20,20,20) 형태로 입력합니다.

라이브러리의 속성값 변경에 따른 디스플레이


LABEL_VALUE 라이브러리에 패널의 외곽선 색상, 폰트의 사이즈에 대한 인터페이스도 추가하여 완성도 높은  라이브러리를 작성해 보세요.


다음 강좌에서는 로직 라이브러리 생성 및 적용방법에 대하여 알아보도록 하겠습니다.

-이엔유 주식회사-

+ Recent posts