[컴퓨터비전]이미지 변환시 DoF(Degrees of Freedom)에 대한 고찰

공대생의 팁 2015. 10. 13. 00:13

 영상처리와 컴퓨터비전 분야에서 가장 중요한 요소로 Matrix 변환을 기반으로 하는 선형대수(Linear Algebra)가 있습니다. 특히 화면에 나타나는 이미지를 변환할 때 (Geometric Transformations를 하기 위해 사용되는 행렬), DoF라는 개념이 언급됩니다. 본 포스팅에서는 이 DoF에 대해 이야기해 보려 합니다.


-DoF(Degrees of Freedom)란?

 DoF(Degrees of Freedom), 우리말로 '자유도'라 일컫는 요소로 이미지가 변환이 될 때 최소한으로 필요로 하는 독립변수의 수라고 정의할 수 있습니다. 이에 대해 각 Geometric Transformations들을 통해 알아보도록 하겠습니다.


-Translation


 이미지 변환중 가장 단순하다고 할 수 있는 변환 중 하나입니다. 이를 Matrix로 나타내면 다음과 같습니다.


위의 식에서 보이는 바와 같이 총 2개의 변수에 의해 이미지가 변환되고 있는 것을 알 수 있습니다. 각 변수는 이미지의 x축과 y축을 이동하는 식으로서 이는 Translation의 DoF가 2임을 알 수 있습니다.

 또한 Translation의 결과물은 원본 이미지에서 큰 변화가 일어나지 않습니다.


-Rigid(Euclidean)

위에서 보았던 Translation을 수행한 후 이미지를 일정 각도로 회전시킨 결과입니다. 이를 Matrix로 나타내면 다음과 같습니다.


위의 식에서 보는 바와 같이 x축으로의 이동, y축으로의 이동, 회전각도 Θ로 DoF는 3임을 알 수 있습니다.

 위 Rigid의 최종 결과물은 원본 이미지의 높이 및 너비와 같은 길이가 보존되는 것을 알 수 있습니다.


-Similiary

위의 Rigid Transform에서 결과물의 사진 크기가 변하였음을 확인할 수 있습니다. 이를 Matrix로 나타내면 다음과 같습니다.


 위의 식에서 보는 바와 같이 x축으로의 이동, y축으로의 이동, 회전각Θ, 크기변수s 로 DoF는 4임을 알 수 있습니다.

 위 Similary의 최종 결과물은 원본 이미지의 직각 부분이 유지되는 것을 알 수 있습니다.


-Affine

원본 이미지에 Affine Matrix가 적용되면 이미지가 위에서 보는 바와 같이 일그러진 모습을 하고 있는 것을 보실 수 있습니다. 이를 Matrix로 나타내면 다음과 같습니다.


Affine Matrix의 DoF는 6임을 확인하실 수 있습니다.

 위 Affine의 최종 결과물은 원본 이미지의 두 변의 평행이 보존됨을 확인하실 수 있습니다.


-Projective

 원본이미지에 Projectiive가 젹용되면 마치 이미지가 정사영에 투영된 듯이 이미지를 기울여서 보는 듯한 느낌이 들 겁니다. 이를 Matirx로 나타내면 다음과 같습니다.


Projective Matrix의 DoF는 8임을 알 수 있습니다.

 위 Projective의 최종 결과물은 원본 이미지의 특정 두 변의 평행이 유지되는 것을 알 수 있습니다.

300x250

IP v4 주소 0.0.0.0의 의미

공대생의 팁 2015. 9. 27. 23:42

 IP주소는 여러분들이 흔히 아시듯이 인터넷에 접속하기 위해 사용되는 자신의 기기에 할당되는 일종의 주소와 같은 역할을 합니다. 이 중 몇몇 IP주소의 경우 특수 용도로 쓰입니다.


 가장 대표적인 것이 0.0.0.0과 255.255.255.255입니다. 255.255.255.255는 한정된 범위 내에 접속된 모든 기기에 패킷을 보내는 용도로 사용됩니다. 그렇다면 0.0.0.0은 어떤 용도로 사용되는 것일까요?



 IP주소 0.0.0.0은 IPv4 패킷을 전송하고자 하는 컴퓨터가 자신의 IP주소를 모르는 경우 통신을 하기 위해 사용됩니다. 보통 자신의 IP주소를 모르는 컴퓨터는 부트스트랩(컴퓨터의 전원을 킬 때나 재부팅할 때)이 진행되는 도중에 위 주소를 사용합니다.


 이 신호를 보낸 컴퓨터는 자신의 주소를 알기 위해 이 주소를 발신지 주소로 설정하고 목적지 주소로 255.255.255.255로 설정한 IP 패킷을 DHCP서버로 전송합니다. DHCP서버는 신호를 받은 후 해당 PC에 IP 주소를 알려주며 PC는 해당 주소를 자신의 IP 주소로 사용합니다.


보다 더 자세한 내용을 알고 싶으신 분은 아래 링크를 참조해 주시길 바랍니다.

http://www.netmanias.com/ko/post/blog/5348/dhcp-ip-allocation/understanding-the-basic-operations-of-dhcp


300x250

PHLASHNT.SYS 드라이버를 로드할 수 없습니다. 오류 코드: 1275

공대생의 팁 2015. 9. 7. 23:36

 현재 제가 데스크톱으로 활용하고 있는 리퍼비시 PC인 Smasung 매직스테이션 DB-Z70을 사용하다가 최신 BIOS로 업그레이드를 해 보고자 삼성전자 홈페이지에서 해당 데스크톱의 최신 BIOS 버전을 다운로드 받은 후 실행해 보았습니다. 그러자 아래와 같은 경고문이 뜨면서 저를 반기더군요.

 "PHLASHNT.SYS 드라이버를 로드할 수 없습니다. 계정을 확인하십시오. 관리자 권한이 없는 경우에는 다시 로그인하십시오! 이 드라이버가 차단되었기 때문에 로드할 수 없습니다. 오류 코드: 1275"



 위 화면은 Windows 10 64-bit 버전에서 해당 프로그램을 실행하였을 때 위와 같은 현상이 발생합니다. 위와 같은 문제가 발생하는 원인은 아래 중 하나에 해당될 것입니다.


- 현재 자신이 사용하는 운영체제의 버전이 Windows 7 이상(8, 8.1, 10)인 경우

- 자신이 사용하는 운영체제가 64비트 기반일 경우


 구글링을 통해 다른 분들의 사례들을 분석해 본 결과, 해당 BIOS의 버전이 설치되지 않는 이유는 Windows 7에서 부터 실행권한이 Root와 User가 분리되면서 발생하는 것으로 추정됩니다. 현재 해외의 사례에서 가장 좋은 해결 방법은 32비트 기반의 Windows XP 운영체제를 통해 설치하는 것을 권장하고 있습니다. 위 프로그램을 설치하기 위해서는 아래의 방법 중 하나를 선택해 주시면 될 것으로 보입니다.


- 자신의 하드디스크에 임시로 파티션을 분리하여 Windows XP를 설치한 후 BIOS 설치 프로그램을 실행합니다.

- Windows XP가 설치되어 있는 하드디스크 혹은 USB를 통해 Windows XP를 부팅한 후 BIOS 설치 프로그램을 실행합니다. 


 위에서 제시한 방법들 중 하나를 선택하여 BIOS 설치 프로그램을 실행하시면 아래와 같이 정상적으로 설치되는 것을 확인하실 수 있습니다.


 


300x250

Intel Management Engine BIOS Extention 설정시 암호 변경이 안될 때 해결방법

공대생의 팁 2015. 8. 19. 21:12

 Intel 사의 bios를 설정할 때에 사용되는Intel Management Engine BIOS Extention을 처음 사용할 때에 default 암호를 알 수가 없어 이를 어떻게 해야 헤결될 수 있는지 방법을 한참 찾다 설정 방법을 알게 되어 이렇게 포스팅을 하게 되었습니다. 혹시 Intel Management Engine BIOS Extention을 설정하시다가 저와 같이 암호 설정 때문에 애를 먹는 분이라면 본 포스팅이 도움이 되었으면 합니다.


 먼저, Intel Management Engine BIOS Extention에 진입하는 방법부터 알아보도록 하겠습니다. 아래 화면은 Dell사의 컴퓨터를 기준으로 F12 버튼을 누른 후 Boot Device Menu로 진입한 화면입니다.



 이렇게 Boot Device Menu에 진입하게 되면 위와 같은 메뉴들을 확인하실 수 있습니다. 이 중 Intel Management Engine BIOS Extention을 선택하여 진입하도록 합니다.



 그렇게 해서 진입을 하면 아래에서 보는 바와 같이 처음부터 암호를 입력하라는 뜬금없는 화면이 뜨게 됩니다. 우리는 이 암호를 설정한 적도 없음에도 이렇게 버젓이 뜨니 당혹스러울 수 밖에 없는 상황이지요...

 실은 해당 암호는 처음에는 Defalt로 기본 암호가 설정되어 있습니다. 해당 Default 암호는 다음과 같습니다.


admin


 위의 디폴트 암호를 입력하시면 아래와 같이 암호를 새로 설정하라는 안내가 나옵니다.



 그런데 이상하게도 암호를 설정하려 할 때마다 위와 같은 경고문이 뜨면서 변경된 암호를 받아들이지 않는 당혹스러운 상황이 벌어집니다.


Error - Intel(R) ME password change rejected


 위와 같은 일이 발생하는 이유는 자신이 설정한 암호가 해당 프로그램이 요구하는 암호의 기준에 맞지 않아 보안에 약한 암호이기 때문에 위와 같이 자신이 설정한 암호가 거절당하는 상황이 발생하게 됩니다.

 위와 같은 상황이 생기시는 분들이 계신다면 아래의 규칙대로 자신의 암호를 다시 설정하시면 암호를 설정하실 수 있을 것입니다.


 1. 8자 이상의 암호로 구성되어야 합니다.

 2. 1개 이상의 숫자가 암호에 포함되어야 합니다.(1,2,...,0)

 3. 1개 이상의 기호(!,@,#,$,...)가 포함되어야 합니다. 단, '_'는 암호로 설정할 수 있으나 기호로는 예외입니다.

 4. 알파벳 설정시 대문자와 소문자를 섞어서 사용해야 합니다.



 예를 들어 다음과 같이 암호를 설정하시면 확실하게 적용되는 것을 확인하실 수 있습니다.


eLecs20!5



300x250

Ubuntu에서 특정 Unicode가 안보일 때

공대생의 팁 2015. 7. 22. 20:44

 우분투 운영체제로 웹사이트를 돌아다니다 보면 종종 네모 모양으로 깨져서 나오는 경우가 있습니다. 아래는 특정한 유니코드가 깨져 제대로 출력 되지 않고 있는 상황을 보실 수 있습니다.




 위와 같은 경우 몇몇 유니코드는 Terminal에서 다음과 같은 명령어를 입력하셨을 때 해당 유니코드가 출력 되는 경우가 있습니다.


$ sudo apt-get install ttf-ancient-fonts


 이후 컴퓨터를 리셋 하신 후 다시 확인하시면 유니코드가 제대로 출력 되는 것을 확인하실 수 있습니다.


 


300x250

GFDM(Generalized Frequency Domain Multiplexing)

공대생의 팁 2015. 6. 6. 18:42

 무선통신 방식은 하루가 다르게 빠른 속도로 발전하고 있습니다. 현세대의 이동통신인 4세대 이동통신인 LTE의 등장으로 우리나라에서의 휴대전화 데이터 전송 속도가 과거 3G 방식에 비해 매우 빨라졌음을 알 수 있습니다.

 본 포스팅에서는 지난 2014년에 발표된 새로운 개념의 통신방식인 GFDM(Generalized Frequency Domain Multiplexing)에 대해 간단하게 설명해볼까 합니다. 혹시 GFDM에 대해 좀 더 자세히 알고 싶으신 분께서는 출저에 표기된 논문을 읽어보셨으면 합니다.


1. Issue about 5G

 


 그래프는 지금까지 등장한 통신방식들과 그 방식의 속도를 나타내고 있습니다. 연도가 올라갈수록 WLAN과 Cellular 의 통신 속도가 급속도로 빨라지고 있는 경향을 확인할 수 있는데요. 통신 속도가 기하급수적으로 증가하여 오늘날의 통신기술인 LTE 방식을 통해 실시간으로 동영상을 다운로드하며 볼수 있는 환경에 도달할 수 있게 되었습니다.

 앞으로의 5G의 이슈로는 현재보다도 더 빠른 무선통신 환경이 구축될 것이며, 통신시 저전력 전송방식 또한 중요해질 것으로 보입니다. 또한, 통신중 latency의 최소화 또한 5G에서의 이슈가 될 것으로 보입니다.


2.GFDM이란 무엇인가?

 GFDM(Generalized Frequency Division Multiplexing)은 기존에는 없었던 새로운 개념의 다중주파수 전송방식입니다. 기존에 존재하였던 OFDM과 SC-FDE의 방식의 장점들을 유연하게 다루고 있으며 현재 사용되는 방식인 LTE 대역에서도 GFDM이 사용될 수 있다는 것이지요.



  


 시간 대 주파수 그래프를 통해 GFDM의 동작방식에 대해 좀 더 자세히 살펴보도록 하겠습니다. OFDM은 각 주파수 대역 별로 각각 데이터를 전송하는 방식입니다. 이는 각 Subcarrier에 동시간대에 데이터를 전송할 수 있어 짧은 시간에 많은 데이터를 전송할 수 있는 장점을 갖추고 있습니다. OFDM의 최대 단점으로는 전력 소모가 매우크며 ISI(Intersymbol Interference)가 발생할 확률이 높다는 점입니다. 반면, SC-FDE의 경우 전력 소모가 OFDM에 비해 낮으며 그로 인해 역방향 채녈의 커버리지를 넓게 사용이 가능하다는 장점을 가지고 있으나 OFDM에 비해 여전히 데이터 속도와 용량 등 전송 데이터량이 적다는 단점을 가지고 있습니다.




 이러한 OFDM과 SC-FDE의 장점을 아우르고 있는 방식이 바로 GFDM인데요 그 특징을 그래프를 통해 살펴보겠습니다. 보시는 바와 같이 GFDM은 각각의 단위를 독립적인 블록과 같은 개념으로 보실 수 있는데요 각 블록은 Subcarrier와 Sub-symbol로 구성되어 있습니다. 하나의 Subcarrier가 여러개의 Sub-symbol을 전송하는 방식으로 구성되어 있기 때문에 블록 구조는 낮은 latency조건을 설계할 수 있습니다.


3.Details of the GFDM modulator

Block diagram of the transceiver


 위 그림은 GFDM의 송수신과정을 블록 다이어그램으로 나타낸 모습입니다. 겉모습으로 보기에는 다른 전파방식과는 큰 차이가 없어보입니다. 이번에는 GFDM modulator을 살펴보도록 합시다.



 위 그림은 GFDM의 modulator의 내부 동작 방식을 그림으로 나타낸 것입니다. GFDM에 입력되는 N개의 입력값 d[n]이 modulator을 통과하고 있는 모습입니다. GFDM은 해당 입력을 각 Subcarrier에 값을 분산시키며 해당 Subcarrier 내에서도 각각 별개의 Sub-symbol에 값을 적용한 후 값을 전달하는 모습을 나타내고 있습니다. 이 때의 값은 D[K-1][M-1]로 타나나고 있습니다. 이때 각 K와 M의 값은 다음과 같습니다.


N : GFDM에 입력된 값의 총 갯수

K : Subcarrier의 총 갯수

M : Sub-Symbol의 총 갯수


 N개의 입력이 K개의 Subcarrier에 나누어 들어가게 되었으며 또한 각 Subcarrier에는 M개의 Sub-symbol로 나누어져 값이 입력됩니다. 즉, 이는 아래의 공식이 성립됩니다.

N = K × M


 각 Subcarrier에 도달하게 된 데이터값 d는 해당 Subcarrier의 Sub-symbol에 할당되었을 때 d[k][m]에 값이 들어가게 됩니다. 이는 곧 위에서 설명해드린 한 단위의 '블록'이 되는 것이지요. 이렇게 만들어진 각 블록은 이에 해당되는 파형에 적용되는데요 해당 파형의 공식은 다음과 같습니다.




그리고 위의 파형화 블록의 곱을 모두 합하면 전송되는 실제 파형이 만들어지게 됩니다.




 이 때 x[n]의 값이 GFDM을 통해 출력되는 값을 나타냅니다. 위 식은 아래와 같이 간단하게 표현될 수 있습니다.



 이 때 A가 바로 GFDM의 modulation matrix라 할 수 있겠습니다. 입력벡터 d에 modulation matrix를 행렬곱하면 출력값으로 벡터 x가 나온다고 이해하시면 되겠습니다. 아래는 modulation matrix인 A의 값을 그램으로 표현한 모습입니다. 해당 예시의 그림은 4개의 Subcarrier와 7깨의 Sub-Symbol로 구성된 28 × 28 matrix입니다.



 이렇게 GFDM modulation을 통과한 x[n]이 실제 전파될 때는 수신측에서 받게되는 신호 y[n]는 아래의 식으로 표현될 수 있습니다.


 여기서 GFDM 모듈레이터 값인 x와 h는 순환 컨볼루션을 적용한 후 AWGN 값을 더해줍니다. 여기서 AWGN(Additive White Gaussian Noise)이란 노이즈 주파수를 값에 더하여 실제 신호와 같게 만들어 기 위해서 적용하는 값입니다.


4.Details of the GFDM demodulator


 다음으로 GFDM의 demodulator에 대해 살펴보도록 하겠습니다. demodulator에 값을 적용하기 전에 먼저 Frequency Domain Equalization을 통해 새로운 y[n]값을 얻습니다. 


 그렇게 FDE가 적용된 새로운 y[n]값에 Demodulation matrix인 B를 행렬곱하면 수신값 d[n]을 얻게 됩니다.


 여기서 Demodulation matrix인 B의 값을 구하는 방법 3가지를 살펴보도록 하겠습니다.


-Matched Filter Receiver

 이 방식은 애르미드 공액 방식을 활용하는 방식으로 각 서브캐리어 당 SNR 값을 최적화 함으로서 전송 도중 손상되는 데이터 심볼을 회복시키는 것을 목표로 합니다. 단점으로는 ISI와 ICI(Intercarriers Interference) 문제가 발생한다는 점입니다.


-Zero-forcing Receiver

 이 방식은 단순히 modulation matrix A의 역행렬 방식을 취하며 Subcarrier 간의 간섭을 없애는 것을 목표로 하고 있습니다. 이를 통해 ISI와 ICI 문제를 해결할 수 있으나 송신측에서 전송하는 데이터 값에 따라 값이 손실될 가능성이 발생합니다.


-Minimum Mean Square Error Receiver

 이 방식은 이전 두 가지 방식인 Matched Filter Receiver 방식과 Zero-forcing Receiver 방식을 혼합한 방법으로 이 식 자체에 신호를 equalize하는 기능이 포함되어 있기 때문에 Frequency Domain Equalization을 사용하지 않아도 된다는 장점이 있습니다만, 이와 같은 구조는 수신측에서 값을 계산하는 방식이 복잡해진다는 단점을 가지고 있습니다.

 

5. LTE compatibility

 GFDM은 5세대 이동통신으로서의 머물지 않고 현재 4세대 통신기술인 LTE에도 이론적으로 적용할 수 있다는 특징을 가지고 있습니다. 이러한 GFDM의 특성을 활용한다면 이전 세대에서 사용하던 기술들을 혼용함으로서 혼합형 디바이스를 설계하는 것이 좀 더 수월해질 수 있습니다. GFDM의 주파수를 현재 운용중인 LTE의 클럭주파수인 30.72MHz를 활용하면 LTE의 시간-주파수 grid를 사용할 수 있습니다. 또한, 이렇게 적용된 GFDM 방식을 통해 기존 LTE 방식에서도 좀더 짫은 Latency를 기대할 수 있게 됩니다.


 GFDM 방식이 LTE에 적용되는 방법을 설명하기에 앞서 먼저 LTE의 프레임 구조를 살펴보도록 하겠습니다. 그림에서 보시는 바와 같이 LTE는 프레임 단위로 단말기와 통신을 하고 있는 것을 확인하실 수 있습니다. 하나의 프레임은 10개의 서브프레임으로 구성되어 있으며, 서브프레임은 2개의 슬롯으로 이루어져 있으며 해당 슬롯은 Cyclic prefix와 심볼로 구성되어 있음을 확인하실 수 있습니다.


- LTE-FDD 방식에서의 OFDM


CP : 16μs

Symbol : 66.7μs

 LTE 기술 중 하나인 LTE-FDD 방식에 대해 살펴보도록 하겠습니다. 위 그림에서 보시는 바와 같이 LTE-FDD 방식은 여러개의 Subcarrier를 활용하는 OFDM 방식을 사용하고 있음을 확 수 있습니다. Cyclic prefix의 간격은 16μs이며, 각 심볼은 66.7μs입니다. GFDM 방식과 비교하였을 때, LTE-FDD 방식의 단점으로는, 각 Symbol이 만들어질 때 마다 Cyclic prefix가 사용되어지고 있으며, 이는 전송시 Frame의 간격을 최대한으로 줄일 수 없어 Latency 문제가 발생하게 됩니다.


- GFDM 방식이 적용된 LTE-FDD

CP : 4.17μs

Subsymbol : 4.17μs

 그렇다면 LTE 통신방식에 GFDM을 적용하였을 때 어떤 효과가 나타나는지 보도록 하겠습니다. 보시는 바와 같이 스펙적인 면에서 확인하였을 때, Cyclic prefix와 Symbol이 4.17μs로 눈에 띄게 줄어들었음을 확인하실 수 있습니다. GFDM의 경우 LTE-FDD와는 달리 여러개의 Subsymbol을 하나의 Cyclic prefix를 통해 전송하는 것이 가능하며, Symbol duration을 무려 7.5배 작게 할 수 있기 때문에 전송시 프레임 단위 하나의 duration을 줄일 수 있습니다. 즉, 이는 무선통신시의 Latency를 확연히 줄일 수 있어 이론적으로 통신 속도가 증가함을 알 수 있습니다.


 GFDM이 OFDM을 대체하게 되었을 경우 얻을 수 있는 또 다른 장점으로는 Out-of-Base emission을 줄일 수 있다는 점입니다. 여기서 Out-of-Base emission이란 통신시 자신에게 해당되는 대역폭을 벗어난 주파수 영역으로 데이터가 전송되는 현상으로 이는 신호간의 간섭을 유발할 수 있습니다. 특히 각 주파수 대역별로 근접해 있는 OFDM의 경우 Out-of-Base emission에 취약하다는 단점을 가지고 있습니다. 반면 GFDM은 시간-주파수 영역이 블록 단위로 구성되어 있고 이 구조는 순환적으로 변하기 때문에 Out-of-Base emission 문제를 해결할 수 있습니다. 이렇게 GFDM이 오늘날의 통신 방식인 LTE에 적용하였을 때에도 상당히 효율이 높아질 것으로 기대할 수 있겠습니다.


- Conclusion

 GFDM 방식은 기존의 통신방식인 LTE에서도 적용할 수 있어 이전 세대의 통신방식을 아우를 수 있는 기존에는 없던 새로운 방식이라는 점이 상당히 매력적입니다. GFDM의 특성으로 Latency 이슈가 해결된다면 머지않은 미래에는 촉감 인터넷(Tactile Internet)과 같이 기존의 방식으로는 구현하기 힘들었던 분야가 새롭게 부상할 것으로 보입니다. 또한, MIMO와 같이 GFDM 또한 잠재적인 5G 시대의 기술이 될 것으로 기대됩니다.


- Reference

1. I.Gaspar, L.Mendes, M.Matthe, N.Michailow, A.Festag, G.Fettweis, "LTE-compatible 5G PHY base on Generalized Frequency Division Multiplexing", Wireless Communications Systems (ISWCS), 2014 11th International Symposium, pp. 209 - 213, 26-29 Aug. 2014


2. N. Michailow, M.Matthe, I.S.Gaspar, A.N.Caldevilla, L.L.Mendes, A.Festag, G.Fettweis, "Generalized Frequency Division Multiplexing for 5th Generation Cellular Networks", IEEE Transactions Communications, Vol.62, pp.3045 - 3061, Sept. 2014

300x250

TIZEN Native 단계에서 LOG를 활용해보자!

공대생의 팁 2015. 6. 5. 23:59

 프로그래머로서 코딩을 할 때 가장 중요한 요소가 무엇이냐 누군가가 묻는다면 저는 자신의 결과물을 직접 확인할 수 있는 LOG를 보는 것이라고 말하고 싶군요. 프로그램을 제작하던 도중 잘못된 동작을 하는 부분이 어떠한 문제가 있는지 알고 싶을 때 이 LOG가 어떤 때보다 가장 빛을 발하게 되지요!

 특히 안드로이드의 경우 logcat(로그캣)이라는 기능이 있어 자신이 제작한 프로그램의 로그를 손쉽게 확인할 수 있는 기능을 갖추고 있습니다.


 이토록 편리한 로그캣과 같은 기능이 TIZEN에서도 사용이 가능할까요? 정답을 말씀드리자면 Yes입니다. 다만, Android의 로그캣을 쓰는 것 처럼 Java 단계에서 손쉽게 로그를 보는 방식이 아니라는 점이 상당히 아쉬운 부분입니다.




 어찌보면 타이젠의 SDK도 안드로이드의 로그캣을 밴치마킹한 듯 비슷해 보이지만 아무쪼록 TIZEN의 Native 단계에서 로그를 확인하는 방법을 살펴보도록 하겠습니다!


#include <dlog.h>

TIZEN의 Native 단계에서 로그를 확인하고 싶을 때 해당 소스코드에 dlog.h를 include 해줍니다.


int      dlog_print (log_priority prio, const char *tag, const char *fmt,...)


이 부분에서 자신이 출력하고자 하는 내용을 입력합니다.


log_priority prio

log_priority 부분에는 해당 로그의 속성을 설정합니다. 로그 속성의 종류는 다음과 같습니다.


DLOG_DEBUG    : 개발자가 확인해보고자 하는 내용

DLOG_INFO         : 일반적인 정보 메시지. 이 로그는 항상 출력됩니다.

DLOG_WARN      : 에러는 아니지만 의도하지 않은 에러가 발생할 가능성이 있을 때 나타나는 메시지. 이 로그는 항상 출력됩니다.

DLOG_ERROR     : 에러 발생시 출력. 이 로그는 항상 출력됩니다.


대략적으로 로그의 속성들은 위와 같이 정의되고 있습니다만, 자신이 쓰고 싶은 속성을 선택하시면 해당 선택사항대로 로그가 출력됩니다.


const char *tag

 해당 로그의 태그를 입력합니다 태그를 설정해두면 이후 자신이 찾고자 하는 로그를 확인하는 것이 수월해집니다.


const char *fmt,...

 해당 로그에서 출력하고자 하는 메시지를 입력합니다.


 위에서 설명드린 dlog_print() 함수를 적절히 사용하신다면 TIZEN의 Native 환경에서 로그를 보는 것이 상당히 수월해질 것입니다. 혹시 출력하고자 하는 메시지가 있다면  sprintf() 함수를 통해 출력하고자 하는 내용을 설정해 주시면 되겠습니다.


 아래는 dlog_print() 함수가 적용된 예제와 그 결과를 나타내고 있습니다. 아래의 소스코드를 참조하시고 여러분들도 TIZEN Native 프로그레밍이 한층 더 수월하게 진행되셨으면 합니다!


/framework/system/deviced/src/display/core.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <dlog.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <vconf-keys.h>
#include <Ecore.h>
 
....
 
static int default_trans(int evt)
{
    struct state *st = &states[pm_cur_state];
    int next_state;
 
    next_state = (enum state_t)trans_table[pm_cur_state][evt];
 
 
    sprintf(pbuffer,"current state : %d, next state : %d, evt : %d", pm_cur_state ,next_state, evt);
    dlog_print(DLOG_INFO, "USR_TAG", pbuffer);
 
    /* check conditions */
    while (st->check && !st->check(next_state)) {
        /* There is a condition. */
        if (standby_mode) {
            _D("standby mode, goto next_state %s",
                state_string[next_state]);
            break;
        }
        _I("%s -> %s : check fail", state_string[pm_cur_state],
               state_string[next_state]);
        if (!check_processes(next_state)) {
            /* this is valid condition - the application that sent the condition is running now. */
            return -1;
        }
    }
 
    /* smart stay */
    if (display_info.face_detection &&
        (pm_status_flag & SMAST_FLAG) && hallic_open) {
        if (display_info.face_detection(evt, pm_cur_state, next_state))
            return 0;
    }
 
    /* state transition */
    pm_old_state = pm_cur_state;
    pm_cur_state = next_state;
    st = &states[pm_cur_state];
 
    /* enter action */
    if (st->action) {
        if (pm_cur_state == S_LCDOFF)
            update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_TIMEOUT);
 
        if (pm_cur_state == S_NORMAL || pm_cur_state == S_LCDOFF)
            if (set_custom_lcdon_timeout(0== true)
                update_display_time();
 
        if (check_lcdoff_direct() == true) {
            /* enter next state directly */
            states[pm_cur_state].trans(EVENT_TIMEOUT);
        }
        else {
            st->action(st->timeout);
        }
    }
 
    return 0;
}
cs



/framework/system/deviced/src/display/device-interface.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <dlog.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <math.h>
#include <journal/display.h>
 
....
 
static int _bl_brt(PMSys *p, int brightness, int delay)
{
    int ret = -1;
    int cmd;
    int prev;
    char pbuffer[100];
 
    sprintf(pbuffer,"bright : %d, delay : %d", brightness, delay);
    dlog_print(DLOG_INFO, "USR_TAG", pbuffer);
 
    if (delay > 0)
        usleep(delay);
 
    if (force_brightness > 0 && brightness != p->dim_brt) {
        _I("brightness(%d), force brightness(%d)",
            brightness, force_brightness);
        brightness = force_brightness;
    }
 
    cmd = DISP_CMD(PROP_DISPLAY_BRIGHTNESS, DEFAULT_DISPLAY);
    ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &prev);
 
    /* Update new brightness to vconf */
    if (!ret && (brightness != prev)) {
        vconf_set_int(VCONFKEY_PM_CURRENT_BRIGHTNESS, brightness);
    }
 
    /* Update device brightness */
    ret = device_set_property(DEVICE_TYPE_DISPLAY, cmd, brightness);
 
    _I("set brightness %d, %d", brightness, ret);
 
    return ret;
}
cs


Native 단계에서 위와 같이 설정을 해주셨다면 아래와 같이 자신이 설정한 프로그램의 진행중인 값을 로그를 통해 실시간으로 확인하실 수 있습니다.

(아래 스크린샷의 경우 필자가 내용을 수정하였기 때문에 각자의 환경에서는 로그가 다른 결과로 출력됩니다.)




300x250

Tizen Mobile Native App Programming - 네이티브 센서 예제 분석

공대생의 팁 2015. 5. 26. 13:13

 타이젠의 Web 애플리케이션 제작은 개발자가 약간의 직감으로 마치 안드로이드의 XML을 꾸미듯이 작업을 하는 것이 용이합니다만 Native 단계에서 애플리케이션을 제작하려면 무식하게도 C와 C++을 통해 애플리케이션을 설계해야 하지요. 물론 안드로이드에서도 JAVA 소스코드로 UI를 디자인 하는 경우도 있지만 왠만해선 XML를 많이 사용하긴 하죠.


 본 포스팅에서는 타이젠의 Native 애플리케이션의 예제 중 하나인 SensorApp Sample을 예를 들어 설명해 나가도록 하겠습니다.


 SensorApp 샘플 애플리케이션은 타이젠 기반의 디바이스 내의 센서들의 동작을 확인할 수 있도록 만들어져있습니다. 일단 실행을 해보면 대략 어떠한 방식으로 애플리케이션이 센서값을 받고 있는지 짐작하실 수 있을 것입니다.



타이젠 SensorApp 예제의 소스코드는 다음과 같이 구성되어 있습니다.(버전은 2.3.3 기준)






각 소스의 내용을 살펴보면 다음과 같습니다.


General


main.c

SensorApp의 시작포인트를 제공합니다. 애플리케이션의 instance를 생성한 후 실행합니다.


main-app.c

애플리케이션 life-cycle을 관리합니다. 애플리케이션의 main window, naviframe, 센서 리스트의 view를 생성합니다.


Utils


logger.h

로고 메시지를 작성하기 위한 매크로를 제공합니다.


color-utils.h

integer 값으로 저장된 color값에 대한 매크로를 제공합니다.


Model


sensor-info.h

각각의 센서에 대한 데이터 타입을 정의합니다.


sensor-list.h

SensorApp에서 제공하는 센서 리스트를 정의합니다.


sensor-magnetic.c

마그네틱 센서의 세기값을 계산하는 알고리즘을 정의합니다.


View


window.c

애플리케이션의 main window를 담당합니다.


sensor-list-view.c

센서의 리스트뷰를 제공합니다.


snesor-data-view.c

센서로부터 받은 데이터값과 그 값을 그래픽으로 표현하는 부분을 담당합니다.


sensor-data-chart.c

기본적인 데이터의 그림 기능을 정의합니다.


snesor-data-chart-private.h

벡터나 앵글값을 나타내는 챠트에 대한 센서 데이터값을 정의합니다.


snesor-vector-chart.c

화살표를 사용한 벡터값을 그려주는 일을 수행합니다.


sensor-angle-chart.c

각도값을 활용하여 pie chart를 그리는 역할을 합니다.



다음은 SensorApp 애플리케이션이 구현되는 과정을 나타내 보겠습니다.


1. 먼저 Sensor API의 헤더를 등록합니다.

1
#include <sensor.h>
cs


2. 다음으로 센서의 핸들값과 하드웨어의 정보를 검색합니다.

sensor-list.c 코드 내에 있는 sensor_list_init() 함수는 센서의 핸들값과 하드웨어의 정보를 검색한 후 이를 sensor_info 배열에 저장합니다. 검색된 센서의 정보는 이후 센서 데이터를 표현하는데 사용됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void sensor_list_init()
{
   sensor_info *info = sensors;
   sensor_info *end = info + sensor_count;
   for (; info != end; ++info)
   {
      float resolution = 1.0;
      // Retrieve sensor handle using sensor type
      sensor_get_default_sensor(info->type, &info->sensor);
      // Retrieve sensor minimal and maximal values
      sensor_get_min_range(info->sensor, &info->value_min);
      sensor_get_max_range(info->sensor, &info->value_max);
      // Retrieve sensor resolution
      sensor_get_resolution(info->sensor, &resolution);
   }
}
cs


<sensor-info.h> 헤더파일은 센서의 리스트와 데이터를 표현하는 데에 사용될 센서에 대한 정보를 저장하기 위한 자료구조를 정의합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
struct _sensor_info
{
   sensor_h sensor; // Sensor handle
   sensor_type_e type; // Sensor type
   sensor_unit_e units; // Value measurement units
 
   const char *name; // Sensor display name
   const char **value_names; // Value names array of value_count size
   int value_count; // Values count
 
   float value_min; // Minimal value
   float value_max; // Maximal value
};
cs


3. 센서의 유효성을 확인합니다.

sensor-list-view.c 파일은 sensor-list.c 파일에 의해 제공되는 센서 리스트들을 사용하는 elm_list 를 생성합니다. 센서의 리스트들이 채워지는 동안, _list_view_fill() 함수는 sensor_is_supported() 함수를 통해 디바이스의 센서 들이 사용가능한지에 대한 여부를 체크합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
static void _list_view_fill(list_view *view)
{
   unsigned count = 0;
   const sensor_info *item = sensor_list_get(&count);
   const sensor_info *end = item + count;
 
   RETM_IF(!item, "item is NULL");
   for (; item != end; ++item)
   {
      bool is_supported = false;
      // Check whether sensor is supported by device
      sensor_is_supported(item->type, &is_supported);
      if (is_supported)
      {
         elm_list_item_append(view->list, item->name, NULL, NULL, _list_view_sel_cb, item);
      }
   }
}
cs


어떤 센서가 선택되었을 때,  _list_view_sel_cb() 함수가 선택된 함수 정보를 보내 센서의 데이터를 찾습니다.

1
2
3
4
5
6
static void _list_view_sel_cb(void *data, Evas_Object *obj, void *event_info)
{
   sensor_info *item = data;
 
   sensor_data_view_create(view->navi, item);
}
cs


4. 센서 데이터를 수신합니다.

 센서 데이터의 수신을 시작할 때, _data_view_sensor_start() 함수가 센서의 listener를 등록한 후, 센서의 event callback를 설정한 다음, 센서의 동작을 개시합니다.

1
2
3
4
5
6
7
8
static void _data_view_sensor_start(data_view *view)
{
   sensor_error_e err = SENSOR_ERROR_NONE;
   err = sensor_create_listener(view->sensor_info->sensor, &view->sensor_listener);
   RETM_IF(err != SENSOR_ERROR_NONE, "sensor_create_listener() failed(%d)", err);
   sensor_listener_set_event_cb(view->sensor_listener, SENSOR_INTERVAL, _data_view_sensor_cb, view);
   sensor_listener_start(view->sensor_listener);
}
cs


_data_view_sensor_cb() 센서 이벤트 callback 함수가 호출되었을 때, _data_view_value_items_update() 함수가 수신된 센서의 데이터값을 chart에 적용합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
static void _data_view_sensor_cb(sensor_h sensor, sensor_event_s *sensor_data, void *user_data)
{
   data_view *view = user_data;
 
   _data_view_value_items_update(view, sensor_data->values);
   _data_view_extra_items_update(view, sensor_data->values);
}
 
static void _data_view_value_items_update(data_view *view, float *values)
{
   bool update_chart = false;
 
   // Update genlist items with values received from the sensor
   for (; item != end; ++item, ++value)
   {
      if (item->value != *value)
      {
         // Chart MUST be updated if any value has changed
         update_chart = true;
         item->value = *value;
         // Update genlist item part that displays value
         elm_genlist_item_fields_update(item->obj_item, PART_VALUE, ELM_GENLIST_ITEM_FIELD_TEXT);
      }
   }
 
   // Update chart if necessary
   if (view->chart && update_chart)
   {
      sensor_data_chart_update(view->chart, view->sensor_info->value_range,
         view->sensor_info->axes, values, data_view_item_colors,
         view->sensor_info->value_count);
   }
}
cs


5. 센서의 동작을 중단합니다.

센서 데이터의 view가 destroy 상태가 되었을 때, 센서의 데이터값 수신을 중단하기 위해, _data_view_destroy_cb() 함수가 sensor_listener_stop() 함수를 호출하고 난 후 sensor_destroy_listener() 함수를 사용하여 listener를 중단시킵니다.

1
2
3
4
5
static void _data_view_destroy_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
   sensor_listener_stop(view->sensor_listener);
   sensor_destroy_listener(view->sensor_listener);
}
cs




Reference : Tizen Help guide

300x250

공유기에 연결된 Linux(Ubuntu) 컴퓨터를 외부에서 원격 데스크톱 연결을 통해 조작하기

공대생의 팁 2015. 5. 7. 16:51

최근에는 노트북의 성능도 꽤 좋아진 편이라 한 대만 들고다녀도 어지간한 데스크탑 컴퓨터의 기능은 무리없이 수행할 수 있게 되었습니다만 그럼에도 아직까지는 데스크톱의 성능을 따라가지는 못하는 것이 현실이지요. 그렇다고 해서 데스크탑 컴퓨터를 이리저리 들고다닐 수는 없는 노릇이지요.


 이러한 경우를 위해 최근의 운영체제에서는 다른 컴퓨터를 통해 원격으로 조작이 가능한 기능이 구현되어 있는데요 이 원격 기능이 서로 다른 운영체제끼리도 호환이 된다는 점이 있습니다. 그렇기에 자신의 노트북 컴퓨터가 Windows라 하더라도 자신의 집에 있는 데스크탑이 Ubuntu라면 원격접속을 통해 데스크탑 PC를 마치 내 노트북에서 사용하는 듯이 원거리에서 조작이 가능합니다!


 이번 포스팅에서는 공유기와 연결되어 있는 Ubuntu 운영체제 데스크톱을 야외 등 외부에서 인터넷을 통해 접속하여 데스크톱을 원격조작하는 방식에 대해 알아보고자 합니다. 그럼 시작해보도록 하겠습니다.


1. 먼저 Ubuntu에 다음 명령어를 입력하여 프로그램을 설치합니다.


$ sudo apt-get install vnc4server xrdp


4. 설치한 프로그램을 바로 적용합니다.


$ sudo service xrdp restart


 만약 자신의 컴퓨터가 다른 포트가 설정되어 xrdp와 충돌하게 될 경우 설정을 변경해야 되는 경우가 있습니다. 이는 /etc/xrdp/xrdp.ini 와

/etc/xrdp/sesman.ini 파일을 수정해 주시면 되겠습니다.


/etc/xrdp/xrdp.ini

 위 화면의 설정을 보았을 때 현재 [globals]에서 포트번호가 기본으로 3389번으로 설정되어 있습니다. 만약 자신의 환경에서 해당 포트를 다른 곳에서 사용하고 있거나 자신이 설정하고자 하는 다른 포트번호가 있으면 해당 부분을 변경해 주시면 되겠습니다.


3. 아래 명령어를 입력하여 포트가 제대로 설정되었는지 확인합니다.


$ netstat -antp




 위의 명령어를 통해 화면에 나오는 것처럼 자신이 설정한 포트가 LISTEN으로 설정되어 있다면 외부에서 접속을 받을 준비가 되었다는 의미입니다.


 4. 외부의 원격 조정 요청을 처리하는 부분을 설정해줍니다. Windows버튼 (혹은 우분투 왼쪽 상단 버튼)을 누르신후 한글로 '데스크톱'이라고 입력하시면 '데스크톱 공유'라는 이름의 프로그램이 나타납니다. 해당 프로그램을 실행합니다.



 5. 실행시 '데스크톱 공유 기본 설정'창이 나타납니다. 해당 설정을 아래와 같이 해줍니다. 다음으로 외부에서 접속하였을 때 입력할 비밀번호를 설정해주신 후 닫기 버튼을 클릭합니다.



 여기까지 진행하셨다면 Ubuntu 데스크톱에서 설정은 모두 끝났습니다. 만약 자신의 데스크톱PC가 인터넷선과 직접적으로 연결되어 있다면 자신의 IP 주소만 기억해두시면 바로 원격조정이 가능합니다만 공유기의 경우 포트포워딩을 통해 공유기와 연결된 데스크탑 PC로 연결될 수 있도록 해주어야 합니다. 포트포워딩에 대해 좀 더 자세히 알고 싶신 분께서는 아래 포스팅을 참조해 주시기 바랍니다.


WF2411 공유기를 통한 외부 기기와 소켓 통신 프로그래밍

http://elecs.tistory.com/45


 이번에는 자신의 공유기에 포트포워딩을 설정해줍니다. 본 포스팅에서는 Netis사의 WF2411 공유기를 기준으로 설명하겠습니다. 자신의 공유기를 통한 포트포워딩 설정에 대한 자세한 사항은 공유기 제조사 홈페이지를 참조해주시길 바랍니다.


 6. 현재 자신의 PC에 설정된 IP 주소를 확인합니다. 이 과정을 통해 확인하게 되는 IP주소는 공유기가 자신과 연결된 기기에 할당한 가상 IP로서 공유기와 연결된 기기 사이에서만 사용될 수 있는 내부 IP 주소입니다.


$ ifconfig




 Terminal을 통해 현재 Ubuntu 데스크탑 컴퓨터가 공유기로부터 192.168.1.9 번의 주소를 할당 받고 있음을 확인하실 수 있습니다. 이 주소를 기억하신 후 포트포워딩 설정시 적용하도록 합니다.


 7. 자신의 공유기 설정 모드로 로그인합니다. 일반적으로 공유기 설정 모드에 접속하는 주소는 http://192.168.1.1 입니다.



 8. 포트포워딩 메뉴에 들어가신 후 자신의 컴퓨터 환경에 맞추어 접속 포트를 설정해줍니다.


이곳에서 입력하셔야 할 내용은 다음과 같습니다.

내부 IP주소(서버 PC) - 자신의 Ubuntu 데스크탑이 공유기로부터 할당받은 주소값을 입력합니다.

포트번호(외부) - 원격 접속을 할 컴퓨터가 공유기에 접속하게 될 때 사용할 포트 번호를 입력합니다.

포트번호(내부) - 공유기가 Ubuntu 데스크탑으로 접속하게 될 때 사용할 포트번호를 입력합니다. Ubuntu xrdp의 경우 내부 포트 설정 기본값이 3389로 설정되어 있습니다.


 여기서 외부 포트번호는 원격접속을 하게 될 컴퓨터가 접속하고자 하는 포트 번호를 입력하고 외부에서 해당 포트번호를 입력하게 되면 공유기는 해당 신호를 내부 IP주소가 설정된 컴퓨터로 내부 포트번호를 통해 접속하게 됩니다. 자세한 사항은 아래 그림을 참조해주시면 되겠습니다.

이미지 출저 : http://documentation.commvault.com/hds/v10/article?p=features/firewall/port_forward_gateway.htm


 443번과 444번은 외부 포트번호를 나타내고 있으며 해당 포트 번호로 공유기에 연결을 시도하면 공유기는 이를 해당 색깔과 같은 색깔로 내부 IP주소가 설정된 대로 신호를 전송합니다. 이 때 해당 신호는 내부 포트번호가 440으로 설정된 상황입니다.


  9. 이제 자신의 공유기가 외부로부터 할당받은 IP 주소를 확인합니다. 이 또한 자신의 공유기 설정 페이지에서 확인이 가능합니다.


 위에서 보셨을 때 WAN IP 주소 부분에 적혀있는 것이 바로 자신의 공유기가 외부에서 할당받은 주소입니다. 앞으로 우리는 위 주소를 통해여 원격 데스크톱에 접속할 것입니다.


 이번에는 외부의 컴퓨터를 통해 Ubuntu 데스크톱 컴퓨터를 조종해 보도록 하겠습니다. 먼저 시작(윈도) 버튼을 누르신 후 검색창에 '원격 데스크톱' 을 검색합니다.



 '원격 데스크톱 연결' 프로그램을 실행하신 후 Ubuntu 데스크탑과 연결된 공유기의 IP 주소를 입럭하신 후 포트포워딩으로 설정해 두었던 포트번호를 입력하신 후 '연결' 버튼을 클릭합니다.



 노란 경고 화면이 등장하면서 연결 여부를 확인합니다. '예(Y)'버튼을 클릭합니다.



 아래와 같은 화면이 나온다면 Ubuntu 데스크탑에 연결되는 데에 성공한 것입니다. Module을 'console'로 선택하신 후 우분투에서 '데스크톱 공유 기본설정'시 설정한 비밀번호를 입력합니다.



 올바른 비밀번호를 입력하시게 되면 아래와 같이 원격으로 접속된 Ubuntu 데스크탑 화면이 등장하게 됩니다. 이제 여러분들께서 하고자 하는 작업을 원격으로 수행해 보시기를 바랍니다~!






300x250

TIZEN 소스코드 빌드 gbs가 설치되지 않을 때 수동으로 설치하기

공대생의 팁 2015. 5. 2. 10:48

 Tizen 개발에 입문하기 위해 프로그램들을 설치하는 과정을 진행하던 도중 참으로 이상한 문제가 발생했습니다. 다음과 같이 우분투 apt-get reopsitory에 Tizen 관련 패키지들을 설치할 수 있도록 환경을 구성한 후 gbs 설치를 시도하려 하였으나 더이상 진행이 되지 않는 것이었습니다.


$ sudo vim /etc/apt/sources.list
deb http://download.tizen.org/tools/latest-release/Ubuntu_14.04 /
$ sudo apt-get update

$ sudo apt-get install gbs




 위에서와 같이 gbs를 apt-get을 통해 설치를 시도하니 위에 보는 저 3줄만 덩그러니 뜨기만 하고 설치가 더이상  진행이 되지 않는겁니다. 무언가 제 컴퓨터상의 설정이 잘못되어서 그런지는 잘 모르겠으나 일단 gbs를 설치하셔야 TIZEN 개발환경을 사용하실 수 있습니다. 이 경우 본인은 사이트에 직접 접속하여 소스를 다운로드 받았습니다. 그렇다면 그 방법에 대해 자세히 살펴보도록 합시다.


 먼저 아래 주소로 이동합니다. 우분투 운영체제가 12.04일 경우를 기준으로 설명해 드리겠습니다.


 http://download.tizen.org/tools/latest-release/Ubuntu_14.04



 이 사이트에서 우리들이 설치하고자 하는 패키지를 찾아 설치해보도록 하겠습니다. 현재 우리들이 설치하고자 하는 패키지는 gbs로 해당 패키지를 찾아보도록 하겠습니다.

 apt-get에서 자신이 설치하고자 하는 패키지를 찾는 방법은 위의 파일목록 중 'Packages'를 클릭하시면 TIZEN과 관계된 패키지 목록들을 살펴보실 수 있습니다.



 위의 화면에서 보시는 바와 같이 Package 명이 gbs인 패키지의 정보를 찾으실 수 있습니다. 여기서 해당 패키지의 경로가 'Filename' 부분에 자세히 표기되어 있습니다. 이 위치에 있는 패키지를 다운로드 받으신 후 자신의 컴퓨터에서 실행해줍시다.



 처음 패키지를 실행하게 되면 의존성 문제로 인해 설치가 더이상 진행되지 않습니다. 그렇습니다.. apt-get 명령어를 사용하면 관련 의존성 패키지들이 단 한번에 설치되지만 수동으로 설치하게 되는 경우 이러한 의존성 패키지를 일일히 찾아주어야 하는 상당히 번거로운 과정을 거쳐야 하는 것입니다.

 위에서 보이시는 부분에서 '패키지 의존관계가 불충분함:gbs-api(=0.23.2)' 부분에서 해당 패키지를 위 Package 파일에서 해당 패키지를 찾는 과정을 한 번 더 거쳐줍니다.



 이러한 방식으로 조금은 불편하고 번거롭습니다만 의존성 파일을 지속적으로 찾아주시면서 설치를 진행하시면 gbs 패키지를 모두 설치하실 수 있을 것입니다. 모두들 패키지를 모두 설치하시고 TIZEN 개발자로서의 첫 걸음을 밟아보시기를 바랍니다!

300x250

컴퓨터가 대기모드 되자마자 바로 풀릴 때 해결방법

공대생의 팁 2015. 4. 5. 16:41

 최근에 노트북에 문제가 생긴 듯 하여 프로그램을 업데이트 하는 김에 BIOS를 최신버전으로 교체한 후 컴퓨터를 껏다 켜보았습니다. 이전과는 그다지 달라진 점은 보이지 않았습니다만 평상시 때와 같이 노트북을 닫았는데 이상하게도 노트북이 대기모드에 들어가자마자 바로 풀리는 것이 아닙니까! 그것도 노트북이 접혀있는 상태 그대로 말이지요!



 참으로 골치가 아파오더군요. 기껏 새로운 BIOS를 적용시켜 줬건만 평소에 쓰던대로 못하게 된게 참으로 골치가 아파오더군요. 원인이 대체 무엇인지 알 수 없어 일단은 절전모드 설정과 관련된 자료들을 살펴보았습니다.


 우선 자신의 컴퓨터에 절전모드에서 깨어나게 하는 기능들에 대해 알아보도록 합니다. 먼저 컴퓨터의 CMD창을 열어서 다음과 같이 검색해 주시면 되겠습니다. CMD는 Windows7 기준으로 시작메뉴를 누른 후 'cmd'라고 입력하시면 되겠습니다.


powercfg -devicequery wake_armed



 일단 위와 같이 자신의 컴퓨터를 깨우게 되는 기능들이 쭉 나오고 있습니다. HID의 경우 거의 대부분이 자신의 컴퓨터에 연결된 마우스로 추정하시면 될 듯 합니다.


 일단 제 컴퓨터의 상황상 마우스가 범인일 확률이 높아졌습니다. 안그래도 마우스가 고장나서 최근에 새로 구매했었는데 왠지 새로 구매한 마우스에 해당 기능을 가지고 있는 듯 해 보이는 것이었지요. 그래서 노트북에서 마우스의 연결을 해제한 후 절전모드에 들어가 보았습니다.


 이럴수가! 역시나 마우스가 범인이었습니다! 마우스를 빼고 절전모드에 돌입하더니 노트북 덮개를 열기 전까지 컴퓨터는 절전모드를 계속 유지하고 있음을 확인하였습니다.


 그렇다면 이제부터는 마우스가 연결된 상태에서도 노트북이 절전모드에서 깨어나지 않도록 한다면 문제를 해결할 수 있을 듯 합니다! 그래서 이번에는 마우스가 절전모드에 개입하지 않도록 설정하는 방법에 대해 알아보도록 합니다!


 먼저 시작메뉴를 여신 후 자신의 컴퓨터 속성 메뉴로 들어갑니다. 시작메뉴를 클릭하신 후 '컴퓨터' 메뉴에서 오른쪽 마우스 클릭 후 '속성(R)'을 클릭하시거나 'Windows키 + pause' 버튼을 동시에 누르면 바로 보실 수 있습니다.


그 다음 장치괸리자로 들어갑니다.



그 다음 장치관리자에서 자신의 기기에 해당하는 부분을 마우스 오른쪽을 클릭하신 후 '속성(R)'을 선택합니다.



'전원관리' 탭으로 이동하신 후 '이 장치를 사용하기 위해 컴퓨터의 대기 모드를 종료할 수 있음(O)'의 체크를 해제하신 후 확인 버튼을 눌러줍니다.



이제 자신의 컴퓨터에서 설정된 대기모드들을 확인해 봅니다.

powercfg -devicequery wake_armed



 보시는 바와 같이 HID가 해제되어있는 것을 확인하실 수 있습니다. 이제 자신의 컴퓨터의 절전모드가 문제없이 동작되는 것을 확인하실 수 있으실 겁니다!



300x250

우분투에서 인터넷창을 통해 윈도 미디어 플레이어 관련 영상 보는 방법

공대생의 팁 2015. 4. 4. 02:07

 불과 10년 전만 해도 인터넷 환경으로 동영상을 인터넷 창을 통해 실시간으로 감상하는 일은 쉽지 않았습니다. 지금에 비해 인터넷 속도가 고화질의 동영상을 실시간으로 받아보기에는 매우 느렸으며, 동영상 스트리밍을 운영하는 사이트들은 상당한 트래픽 압박 때문에 동영상을 전문적으로 하려던 사이트는 거의 전무하다 싶었지요.

 하지만 2005년 2월 유튜브가 인터넷 세계에 등장하면서 부터 인터넷 창을 통한 실시간 동영상 서비스라는 매력적인 사업이 발전하기 시작하였습니다. 유튜브가 등장한 이래로 한국 내에서도 mncast 등 동영상 스트리밍을 전문으로 하는 사이트들이 우후죽순 생겨났으나 위에서 어마어마한 트래픽을 감당하기엔 비용을 감당하기 어려워 순식간에 역사속에서 사라지고 맙니다. 그 덕분에 국내에서 동영상을 전문으로 다루는 사이트는 사실상 유튜브 뿐이라 해도 할 말이 없는 상황이 되어 버렸습니다.



 유튜브가 이렇게 성공할 수 있었던 이유는 사용자의 컴퓨터 환경에 전혀 구애받지 않고 어디에서든 재생할 수 있는 flv라는 플래시 비디오 기법을 통해 저용량으로 간편하게 동영상을 공유하는 방법을 사용하였습니다. 그 덕분에 이전에 AVI와 같은 동영상을 통째로 제공하던 사이트들은 이러한 간편함에 매료되어 유튜브를 사용하게 되었고 그 덕에 현재 유튜브는 전 세계 사람들이 동영상을 공유하기 위해 찾아오는 사이트로 우뚝 서게 되었습니다.


 .. 아 서론이 참으로 길었습니다. 두말하면 잔소리가 되겠습니다만 유튜브는 참으로 훌륭한 동영상 공유 사이트가 아닌가 싶습니다. 이렇게 현대에는 유튜브와 같이 동영상을 편하게 감상할 수 있는 환경이 구축되어 있는 경우가 많습니다만, 과거에 만들어진 국내의 몇몇 사이트들은 현재까지도 자체 동영상을 웹페이지에 직접 제공하는 사례가 종종 있습니다. Windows 운영체제를 사용하시는 분들이라면 약간의 대기시간만 있다면 동영상을 그나마 보실 수 있습니다만 우분투와 같은 리눅스의 경우 Windows 기반으로 만들어진 동영상을 보는게 쉽지 않습니다. 동영상을 시청하려 하게 되면 다음과 같은 화면이 우리를 맞이해 주기 때문이지요.



 그렇습니다! 과거의 사이트들은 거의 대부분이 Windows 환경의 컴퓨터를 기준으로 하여 사이트를 만들다 보니 위와 같이 Windows Media Player 기반의 영상들은 바로 볼 수 없는 불편함을 가지고 있습니다. 그렇다면 이제 우분투를 통해 이러한 영상을 볼 수 있는 방법에 대해 알려드리도록 하겠습니다.


 먼저 자신의 우분투 환경에 맞는 우분투 소프트웨어 센터를 실행합니다.

위 화면에서 마우스 커서가 있는 검색창 부분을 다음과 같이 입력해주세요.

'GStreamer'



 검색시 다음과 같은 화면을 보실 수 있습니다. GStreamer는 Windows Media Player 환경에서 실행할 수 있는 동영상을 linux에서도 실행할 수 있도록 해줍니다. 이제 위에 보이는 저 3개를 모두 설치해 줍니다.



먼저 첫 번째인 'GStreamer ffmpeg' 비디오 플러그인을 설치해주신 다음



나머지 2개의 코덱도 설치해주시면 되겠습니다.


설치후 인터넷창을 종료하신후 다시 실행하시면 동영상이 원활하게 돌아가고 있는 것을 보실 수 있을 것입니다.




300x250