2017년 12월 31일 일요일

IIoT시스템 개발을 위한 오픈소스

이 글은 IIoT(Industrial Internet of Things, 산업용 사물인터넷) 개발을 위한 PCB 레이아웃 설계를 위한 오픈소스를 간략히 소개한 글입니다. 이 다음 글을 레퍼런스하였습니다.

TinyCAD 
TinyCAD는 다양한 라이브러리를 지원하는 PCB 레이아웃 및 회로도 설계 도구이다. TinyCAD는 심볼, 텍스트, 주석, 버스 및 전원 신호, 기호 속성에서 도면 편집에 이르는 다양한 기능을 제공한다.

AdvancedHMI
이 프로그램을 이용하면 HMI(Human-Machine Interface)를 손쉽게 만들 수 있다. 이는 Visual Studio가 필요하며 .NET Framework를 기반으로 한다.
SCADA가 가능하며 Omron, Allen Bradley DF1 RS232 드라이버를 지원한다. Linux의 Mono에서 테스트되었으며, Raspberry Pi에서도 작동된다.

Shotcut
Shotcut 비디오 편집 소프트웨어는 다양한 종류의 비디오 및 오디오 형식을 지원한다. 동일한 프로젝트에서 기본 편집, 다중 형식 타임 라인, 해상도 및 프레임 속도를 지원한다. 이 프로그램은 화면, 웹캠, 오디오 캡처에도 사용된다. 최대 4k의 해상도를 지원하고 X11 화면과 Windows DirectShow를 캡처할 수 있다.

iDempiere
기업용 오픈 소스 ERP 소프트웨어이다. 고객 관계 관리 및 공급망 관리를 지원한다. iDempiere는 여러 조직, 다중 언어 지원, 다중 통화 및 다중 계정 스키마를 지원한다. 엔터티, 유효성 검사 규칙, 사용자 지정 응용 프로그램을 관리 할 수 있는 Java 기반 서버로 구성된다.

LibrePlan
프로젝트 관리를 위한 공동 협업 도구이다. 사용자는 작업 및 프로젝트를 계획, 모니터링, 제어, 구성을 할 수 있다.


2017년 12월 21일 목요일

사용자 인터페이스 개발을 위한 오픈소스 프론트엔드 프레임웍 Vue.js

vue는 javascript 기반 사용자 인터페이스 개발을 위한 오픈소스 프런트엔드 프레임웍이다.
이와 비슷한 프레임웍은 React, AngularJS, express와 함께 가장 많이 사용된다. 이 글은 관련 내용 및 사용법을 간단히 설명한다.

머리말
vue는 상대적으로 사용하기 쉽고 플러그인이 다양하며 설치가 쉽다. vue 웹 애플리케이션 프레임웍크를 제공해, 손쉽게 앱 사용자 인터페이스를 개발할 수 있다.


하이브리드 앱 개발을 위해 Cordova(코르도바)와 함께 사용하기도 한다.

Vue는 Evan You에 의해 개발되었으며, Angular의 장점을 도입하였다.

Vue.js는 템플릿 문법을 이용해 DOM에 데이터를 렌더링하기 쉽다.

<div id="app">
  <span v-bind:title="message">
    you can see the binding message.
  </span>
</div>

var app = new Vue({el: '#app', data: {message: 'Hello world! ' + new Data() + '...'}})

Vue는 이미 만들어놓은 컴포넌트를 재활용해, 응용 프로그램을 손쉽게 개발할 수 있다.

설치
node 링크를 방문해 설치한다. 설치 후 터미널이나 명령창에서 버전을 확인한다.
node -v
npm -v

다음과 같이 폴더를 생성한다.
mkdir vue-npm && cd vue-npm

npm을 초기화하고, vue를 설치한다. 패키지 설치가 안되면, 시스템 변수 PATH 에 node package 경로를 추가해 주어야 한다.
npm init -y
npm install vue --save

npm CLI(command line interface)를 설치한다.
npm install -g @vue/cli
npm install vue-cli -g

프로젝트 생성
이제 다음과 같이 프로젝트를 생성한다. 옵션은 default로 선택한다.
vue create vue-proj
vue project 설치 후 모습

프로젝트 생성 후, 다음 명령으로 생성된 프로젝트를 node서버로 실행한다.
npm run serve

yarn을 사용하면 'yarn serve'로 실행한다. 그리고, 실행된 서버 주소를 크롬에서 입력하면 다음 같은 웹페이지를 확인할 수 있다.
vue 설치 후 프로젝트 생성. 서버 실행 모습

간단한 ToDo 프로젝트 개발
다음과 같이 todos-client 이름으로 프로젝트를 생성한다. webpack은 기본적인 vue 템플릿과 패키지가 포함된 패키지이다.

vue init webpack todos-client
옵션은 다음과 같다. 이름을 넣고 router 기능을 활성화한다.

이 결과로 다음 프로젝트 폴더와 파일이 생성된다. 

다음 명령을 통해 서버를 실행한다.
cd todo-client
npm install
npm run dev

크롬을 실행해 http://localhost:8080 을 접속하면, 다음 화면을 볼 수 있다.

이제, /index.html 을 열고, 다음 코드를 붙여 넣는다. 이를 통해, 다양한 그래프, 그리드, 디자인된 템플릿 등을 제공하는 boostrap을 사용할 수 있다.
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">

    <meta name="viewport" content="width=device-width, user-scalable=no">
    <title>todo-client</title>
    <!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

  </head>
  <body>
    <div class="container">
      <div id="app"></div>
    </div>
    <!-- built files will be auto injected -->
  </body>

  <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
  <!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</html>

이제 src/App.vue를 열어본다. 말 그대로 vue 프로젝트의 어플리케이션 컴포넌트로 다음 3개 구조로 되어 있다.
template: HTML DOM (Document Object Model) 구조를 정의함(디자인)
script: 스크립트를 정의한다.
style: 디자인 스타일을 정의한다.

이 중에 template 에 다음과 같이 button을 추가한다.
<template>
  <div id="app">
    <img src="./assets/logo.png">
    <router-view/>
<button class="btn btn-primary">Button</button>
  </div>
</template>

그럼 다음과 같이 button이 동적으로 생성된다. 
이제 2개의 컴포넌트를 만들고, router를 이용해 각 컴포넌트가 특정 URL일 경우, 라우팅하여 동작하도록 해 보겠다. 

src/components에 Example.vue 컴포넌트를 다음과 같이 만든다.
<template>
  <div class="panel panel-default">
    <div class="panel-heading">Panel heading without title</div>
    <div class="panel-body">
      Panel content
    </div>
  </div>
</template>

<script>
export default {
  name: 'Example',
  data () {
    return {
      msg: 'Basic panel example'
    }
  }
}
</script>

src/components에 TodoPage.vue 컴포넌트를 다음과 같이 만든다.
<template>
  <div>
    
  </div>
</template>

<script>
  export default {
    data(){
      return {
        msg:'Example Vue'
      };
    },
    mounted() {
      console.log('Component mounted.')
    }
  }
</script>

src/router/index.js를 열고, 다음과 같이 파일을 수정한다.
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Example from '@/components/Example'
import TodoPage from '@/components/TodoPage'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Hello',
      component: HelloWorld
    },
    {
      path: '/example',
      name: 'Example',
      component: Example
    },
    {//추가
      path: '/todos',
      name: 'TodoPage',
      component: TodoPage
    }
  ]
});

이제, URL 주소창에 example, todos를 다음과 같이 입력해 본다. App.vue의 <router-view/> 디자인이 라우팅된 컴포넌트에 따라 동적으로 생성되는 것을 확인할 수 있다.

TodoPage.vue를 다음과 같이 수정한다. 이 결과로 TODO를 입력할 Text 박스와 Add 버튼, Add버튼 클릭시 추가되는 ToDo list-group이 생성된다.
<template>
<div class="container">
<h2>Todo List</h2>
<div class="input-group" style="margin-bottom:10px;">
<input type="text" class="form-control" placeholder="Input TODO">
<span class="input-group-btn">
<button class="btn btn-default" type="button">Add</button>
</span>
</div>
<ul class="list-group">
<li class="list-group-item">
Clean
<div class="btn-group pull-right" style="font-size: 12px; line-height: 1;">
<button type="button" class="btn-link dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
See more<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a href="#">Delete</a></li>
</ul>
</div>
</li>
</ul>
</div>
</template>

App.vue의 style 부분은 불필요하므로 삭제한다.

이제 Input TODO text 에 입력된 값을 Todo list에 추가하는 스크립트 코드를 다음과 같이 TodoPage.vue에 코딩한다.
<template>
<div class="container">
<h2>Todo List</h2>
<div class="input-group" style="margin-bottom:10px;">
<input type="text" class="form-control" placeholder="Input TODO">
<span class="input-group-btn">
<button class="btn btn-default" type="button">Add</button>
</span>
</div>
<ul class="list-group">
<li class="list-group-item" v-for="(todo, index) in todos">
{{todo.name}}
<div class="btn-group pull-right" style="font-size: 12px; line-height: 1;">
<button type="button" class="btn-link dropdown-toggle" data-toggle="dropdown" 
aria-haspopup="true" aria-expanded="false">
More <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a href="#">Delete</a></li>
</ul>
</div>
</li>
</ul>
</div>
</template>

<script>
export default {
  name: 'TodoPage',
  data () {
    return {
      todos: [
        {
          name:'Clean'
        },
        {
          name:'Writing'
        },
        {
          name:'Eat'
        },
        {
          name:'Make'
        }
      ]
    }
  }
}
</script>

다음과 같이 ToDo 추가/삭제 기능을 만들어 본다.
<template>
<div class="container">
<h2>Todo List</h2>
<div class="input-group" style="margin-bottom:10px;">
<input type="text" class="form-control" placeholder="Input TODO" v-model="name" v-on:keyup.enter="createTodo(name)">
<span class="input-group-btn">
<button class="btn btn-default" type="button" @click="createTodo(name)">Add</button>
</span>
</div>
<ul class="list-group">
<li class="list-group-item" v-for="(todo, index) in todos">
{{todo.name}}
<div class="btn-group pull-right" style="font-size: 12px; line-height: 1;">
<button type="button" class="btn-link dropdown-toggle" data-toggle="dropdown" 
aria-haspopup="true" aria-expanded="false">
More <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a href="#" @click="deleteTodo(index)">Delete</a></li>
</ul>
</div>
</li>
</ul>
</div>
</template>

<script>
export default {
  name: 'TodoPage',
  data () {
    return {
      todos: [
        {
          name:'Clean'
        },
        {
          name:'Writing'
        },
        {
          name:'Eat'
        },
        {
          name:'Make'
        }
      ]
    }
  },
methods: {
deleteTodo(i) {
this.todos.splice(i, 1);
}, 
createTodo(name) {
this.todos.push({name:name});
this.name = null;
}
}
}
</script>

이제 제대로 동작하는 ToDo 어플리케이션을 완성했다.

다른 개발자가 만든 Todo 앱도 많다. 이 링크를 참고한다.

웹 기반 BIM checker 프로그램 개발
웹기반 BIM 품질검토 프로그램을 개발해 보겠다. 이 프로젝트는 2개의 텍스트 입력, BIM(Building Information Modeling) IFC(Industry Foundation Classes) 파일을 업로드받고, 파일을 파싱한 후, 기본적인 속성 품질 체크 결과를 출력하는 프로그램이다. 다음과 같은 폼을 가진다.
vue 사용방법을 익히는 것이 목적이므로, 파일 파싱 등 상세한 내용은 여기서 다루지 않는다. 다음 같이 프로젝트를 생성한다.
vue create bim-checker
npm run serve

부록: REST API 활용 데이터 추가/삭제/리스트
앞의 ToDo 어플리케이션에서 REST API를 사용해 보겠다. API는 List, CRUD(create, read, update, delete) 연산을 지원하다. 이를 위해 axios 라이브러리를 이용한다. axios는 비동기 HTTP 를 지원한다. 다음과 같이 설치한다.
npm install axios --save-dev

src/main.js 에 다음과 같이 axios를 import한다. 이를 통해 axios를 전역적으로 사용할 수 있다.
import axios from 'axios'

Vue.prototype.$http = axios
Vue.config.productionTip = false

이제 TodoPage.vue 컴포넌트를 다음과 같이 CRUD REST API 지원하는 서버를 통해, Todo 데이터를 추가, 삭제, 리스트하도록 기존 코드를 변경해 본다. 
<template>
<div class="container">
<h2>Todo List</h2>
<div class="input-group" style="margin-bottom:10px;">
<input type="text" class="form-control" placeholder="Input TODO" v-model="name" v-on:keyup.enter="createTodo(name)">
<span class="input-group-btn">
<button class="btn btn-default" type="button" @click="createTodo(name)">Add</button>
</span>
</div>
<ul class="list-group">
<li class="list-group-item" v-for="(todo, index) in todos">
{{todo.name}}
<div class="btn-group pull-right" style="font-size: 12px; line-height: 1;">
<button type="button" class="btn-link dropdown-toggle" data-toggle="dropdown" 
aria-haspopup="true" aria-expanded="false">
More <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a href="#" @click="deleteTodo(todo)">Delete</a></li>
</ul>
</div>
</li>
</ul>
</div>
</template>

<script>
export default {
  name: 'TodoPage',
  data () {
    /* return {
      todos: [{name:'Clean'}, {name:'Writing'}, {name:'Eat'}, {name:'Make'}]
    */
return {
name: null,
todos: []
}
  },
methods: {
deleteTodo(todo) {
// this.todos.splice(i, 1);
var vm = this
this.todos.forEach(function(_todo, i, obj){
if(_todo.id === todo.id){
vm.$http.delete('http://vue.todo.data/api/todos/'+todo.id)
.then((result) => {
obj.splice(i, 1)
})
}
})
}, 
createTodo(name) {
if(name != null){
var vm = this;
this.$http.defaults.headers.post['Content-Type'] = 'application/json';
this.$http.post('http://vue.todo.data/api/todos',{
name:name
}).then((result) => {
vm.todos.push(result.data);
})
this.name = null;
}
}, 
getTodos(){
this.$http.get('http://vue.todo.data/api/todos')
.then((result) => {
console.log(result)
})
}
},
mounted() {
this.getTodos();
}
}
</script>

앞의 코드에서 vue.todo.data에 해당하는 주소는 실제 API를 지원하는 주소로 변경해 본다.

레퍼런스
부록: React 
Vue와 유사하게 React는 인터렉티브 인터페이스를 웹에서 제공해주는 라이브러리이다. 2011년 페이스북에서 개발되었다. 리액트는 복잡한 웹 인터페이스를 개발할 수 있도록 해준다.
다음은 간단한 리액트 코드 예시이다(in vscode).

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

var element = React.createElement('h1', { className: 'greeting' }, 'Hello, world!');
ReactDOM.render(element, document.getElementById('root'));

reportWebVitals();

리액트를 이용해 멀티플렛폼 동작 가능한 인터페이스를 개발할 수 있다.

2017년 12월 19일 화요일

Node기반 RESTful API 개발

서버 개발 시 API(Application Program Interface)를 지원해야하는 경우가 종종 생긴다. 이 경우, 많은 대안이 있을 수 있으나, 가볍고, 빠른 개발을 고려한다면, Node기반 RESTful API를 활용할 수 있다.
RESTful API 설명

Node기반 RESTful API 개발을 위해 주로 사용하는 패키지는 익스프레스이다. Node 패키지이므로 아래 명령어로 설치할 수 있다.

npm install express --save

Node와 Mongo DB를 이용하면, 데이터 RESTful 서버를 만드는 것은 그리 어렵지 않다.

좀 더 자세한 개발 방법(Node + Express + Mongo DB)은 아래 튜토리얼을 참고한다.

레퍼런스

AngularJS 기반 앱 어플리케이션 개발

AngularJS는 자바스크립트 기반 오픈소스(github) 프론트엔드 웹 애플리케이션 프레임워기다. 구글 및 여러 커뮤니티에서 유지보수 되고 있으며, 크로스 플랫폼 모바일 앱 개발 프레임웍인 아파치 코도바에 사용된다(위키피디아). MVC(Model View Controller) 구조를 제공함으로써 개발 및 테스트를 단순화한다.


다음은 간단한 AngularJS기반 앱 개발 순서이다. Java나 ASP기반 방법보다 간단하다.

1. set up the development environment
npm install -g @angular/cli

2. create new project
ng new my-app

3. serve the application
cd my-app
ng serve --open

4. Edit your first Angular component
edit src/app/app.component.ts

export class AppComponent {
  title = 'My First Angular App';
}

edit src/app/app.component.css

h1 {
  color: #369;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 250%;
}

5. run
Output of QuickStart app

좀 더 상세한 개발 방법은 다음 튜토리얼을 참고한다.




2017년 12월 13일 수요일

FPGA 하드웨어 기반 고수준 성능 논리칩 개발을 위한 Verilog HDL

이 글은 고수준의 정확성과 성능을 요구하는 논리 칩 개발에 주로 사용되는 FPGA(field programmable gate array) 개발을 위한 Verilog HDL(Hardware Description Language)에 대한 내용을 간략히 요약한다. 최근 FPGA는 딥러닝 기반 비전 등 특수한 분야 응용이 확산되고 있다(사례). 참고로, FPGA는 기존 CPU, GPU에 비해 저전력 (5~6배)과 고속처리를 지원한다.

1. FPGA
FPGA(field programmable gate array, 필드 프로그래머블 게이트 어레이)는 설계 가능 논리 소자와 프로그래밍가능 내부선이 포함된 반도체 소자이다. 설계 가능 논리 소자는 ANDORXORNOT, 더 복잡한 디코더나 계산기능의 조합 기능같은 기본적인 논리 게이트의 기능을 복제하여 프로그래밍할 수 있다. 대부분의 FPGA는 프로그래밍가능 논리 요소 (FPGA 식으로는 논리 블록이라고도 함)에 간단한 플립플롭이나 더 완벽한 메모리 블록으로 된 메모리 요소를 포함하고 있다.
프로그램이 가능한 내부선 계층구조는 FPGA의 논리블록을 시스템 설계자가 요구하는 대로 단일 칩 프로그래밍가능 빵판처럼 내부연결을 할 수 있다. 이 논리블록과 내부선은 제조공정 이후에 소비자/설계자가 프로그램할 수 있으므로 요구되는 어떠한 논리기능도 수행할 수 있다.
자일링스는 FPGA 칩을 개발해 판매하는 회사이다. 이 칩을 이용해 개발 보드 등을 제공하는 회사가 여럿있다. 디질런트도 그 중 하나이다.



2. HDL
HDL은 Hardware Description Language 로 말 그대로, 논리회로를 만들어주기 위한 기술 언어이다. 플립플롭, 시퀀서, 카운터 등 논리회로를 코딩하듯이 만들 수 있다.

3. Verilog
HDL은 VHDL과 Verilog HDL 종류로 나누어 진다. VHDL은 HDL표준이며, Verilog HDL은 C언어와 유사한 HDL이다. 국내에서는 90%이상이 Verilog를 사용한다.

4. Vivado
Vivado 는 자일링스사가 최근 릴리즈한 HDL 코딩을 위한 통합 개발 환경이다. 코딩, 핀 배치 설정, 회로 합성, 회로 구현, 비트스트림 생성 등의 작업을 손쉽게 할 수 있다.

디질런트의 Zynq(징크)칩이 내장된 지보(ZYBO) 보드를 이용하면, Vivado에 비트스트림을 업로드하고, 내장된 CPU를 이용해, 구현된 논리회로를 실행할 수 있다. 참고로, Zynq 시리즈 칩은 PS(process system), PL(process logic)이 함께 임베디드되어 있는 칩이다.
`
Zynq는 FSBL (first stage boot loader)를 이용한다. FSBL은 보드의 SD메모리에 BIN파일로 비트스트림과 함께 다음과 같이 저장된다.

  • SD memory = {BIN, LINUX}
  • BIN = {FSBL, BIT}

SD메모리에 PETA(페타) 리눅스 이미지를 넣으면, 리눅스로 부팅하고, 리눅스에서 FPGA 로직을 실행할 수 있다.
5. 마무리
FPGA칩은 일반적으로 가격이 비싸고, 구현하기 어려우나, 성능과 확장성이 뛰어나 특수한 어플리케이션에서 주로 많이 사용된다. FPGA는 대량으로 칩을 양산하기 어렵지만, 고성능의 비전이나 계산, 타이밍에 정확하고 특수한 시그널을 만들어야할 때 사용한다. 참고로, 윈도우즈, 리눅스, 아두이노, 라즈베리파이와 같이 운영체계 환경에서 실행되는 프로그램은 정확한 타이밍에 특정 시그널을 만들기가 어렵다(이를 위해 리얼타임 OS가 개발되기도 하였음). 

최근 GPU와 경쟁을 하고 있어, 머신러닝, 비전 등을 지원하는 SDK를 릴리즈하고 있다. 아울러, 라즈베리파이와 같은 오픈소스 보드의 확장성, 개발 편의성을 고려해, PYNQ, ARTY와 같은 보드도 개발하고 있다.