Kinnect 요즘은 실패한 발명품 취급 받고 있지요.

그래도 이만한 모션 인식 시스템을 이 가격에 찾기 힘듭니다. 모션 카메라인데 10만원 남짓에 구할 수 있다는게 보통 물건이 아니란 거지요.

 

그리고 재밌게도 초기 물건인 Xbox360용 키넥트는 USB커넥터로 PC에 바로 연결이 가능합니다. 윈도우용 키넥트도 따로 있긴 한데 리눅스에선 이게 더 인식이 잘 됩니다.

 

리눅스에서는 보통 https://github.com/OpenKinect/libfreenect

 

GitHub - OpenKinect/libfreenect: Drivers and libraries for the Xbox Kinect device on Windows, Linux, and OS X

Drivers and libraries for the Xbox Kinect device on Windows, Linux, and OS X - GitHub - OpenKinect/libfreenect: Drivers and libraries for the Xbox Kinect device on Windows, Linux, and OS X

github.com

이 라이브러리를 사용하게 됩니다. 그리고 키넥트 관련 솔루션은 OS문제가 없는 대부분 이걸 사용합니다.

 

그리고 최근 https://github.com/meshonline/kinect-openni-bvh-saver

 

GitHub - meshonline/kinect-openni-bvh-saver: This project is based on OpenNI2, NITE2, and OpenCV2, it will automatically save ma

This project is based on OpenNI2, NITE2, and OpenCV2, it will automatically save many skeleton animation clips to bvh files. - GitHub - meshonline/kinect-openni-bvh-saver: This project is based on ...

github.com

이걸 사용해보려고 했는데 Readme에는 리눅스가 없지만 그냥 OpenNI2폴더와 NiTE2폴더를 만들고 여기에 그냥 빌드된걸 넣으면 되는 거였습니다. OpenNI2와 NiTE2는 https://github.com/suiwenfeng/Ubuntu_x64_Openni2.2_NiTE2.2_FreenectDriver

여기 있었는데 날아가버렸네요. 이건 뭐...어떻게든 되겠죠.

 

그리고 g++ main.cpp -I OpenNI2_Include -I NiTE2_Include -L./ -lOpenNI2 -lNiTE2 `pkg-config opencv4 --cflags --libs` -Wl,-rpath='$ORIGIN'

이렇게 명령 내려서 빌드하면 a.out으로 멀쩡히 나오는군요.

 

딱 하나 문제가 있는데 OpenNI2/Drivers에 libFreenectDriver.so 파일이 시스템 업그레이드 할때마다 세그멘테이션 오류를 일으킨다는 겁니다. 그래서 libfreenect를 일일이 빌드해서 build/lib/OpenNI2-FreenectDriver/에 있는 so 파일을 가져와서 넣어줘야 합니다. 귀찮은데 이대로면 정상적으로 잘 돌아갑니다. libusb나 기타 문제겠제요.

 

libfreenect빌드 명령은 다음과 같습니다.

sudo apt-get install git-core cmake pkg-config build-essential libusb-1.0-0-dev
sudo adduser $USER video

cd libfreenect
mkdir build
cd build
cmake -L .. -DBUILD_PYTHON3=ON -DBUILD_OPENNI2_DRIVER=ON -DBUILD_EXAMPLES=OFF
make

 

그런데 또 문제가 하나 있습니다.

권한 문제로 키넥트 접속 할때마다 root로 해야한다는겁니다. 이건 udev문제인데

 

/etc/udev/rules.d 경로에 다음 파일을 만들어서 넣습니다

# ATTR{product}=="Xbox NUI Motor"
SUBSYSTEM=="usb", ATTR{idVendor}=="045e", ATTR{idProduct}=="02b0", MODE="0666"
# ATTR{product}=="Xbox NUI Audio"
SUBSYSTEM=="usb", ATTR{idVendor}=="045e", ATTR{idProduct}=="02ad", MODE="0666"
# ATTR{product}=="Xbox NUI Camera"
SUBSYSTEM=="usb", ATTR{idVendor}=="045e", ATTR{idProduct}=="02ae", MODE="0666"

# Kinect for Windows
SUBSYSTEM=="usb", ATTR{idVendor}=="045e", ATTR{idProduct}=="02c2", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="045e", ATTR{idProduct}=="02be", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="045e", ATTR{idProduct}=="02bf", MODE="0666"

 

파일명은 대충 51-kinnect.rules 정도로 하면 되겠죠.

 

그리고 lsusb를 치면 보통 Xbox NUI Motor, Xbox NUI Audio, Xbox NUI Camera 이 세가지가 모두 떠야 하는데 하나만 뜨는 경우가 있습니다. 이경우 원인은 두가지 있습니다.

명령을 내리면 아래같이 뜨는게 정상이지만 하나만 뜨거나 하나도 안 뜨는경우가 있습니다.

lsusb | grep Xbox                                                
Bus 001 Device 021: ID 045e:02ae Microsoft Corp. Xbox NUI Camera
Bus 001 Device 019: ID 045e:02b0 Microsoft Corp. Xbox NUI Motor
Bus 001 Device 020: ID 045e:02ad Microsoft Corp. Xbox NUI Audio

 

1. Autosuspend 문제

전력 문제로 USB장치의 전력을 제한 하는 경우가 있습니다. 보통 노트북이 그렇죠.

간단하게 autosuspend를 끄면 됩니다.

echo -1 | sudo tee -a /sys/module/usbcore/parameters/autosuspend

 

위 명령을 쓰고 키넥트를 다시 연결하면 잘 뜹니다.

 

2. 그냥 어댑터 전력 문제

2023년 현재 키넥트가 나온지 오래된 관계로 어댑터들이 상태가 안 좋습니다. 그래서 전력문제를 호소하는 경우가 있더군요.

간단하게 어댑터를 바꾸거나 선을 잘라서 12V를 직접 넣어주면 됩니다.

 

https://www.reddit.com/r/kinect/comments/g7nlei/tips_for_making_your_own_kinect_360_power_adapter/

 

From the kinect community on Reddit

Explore this post and more from the kinect community

www.reddit.com

레딧을 보면 선 형태가  대충 나오는데 이런식으로 잘라서 가공하면 됩니다. 12V어댑터와 USB2.0케이블이 하나 필요합니다.

일단 이렇게 만들면 거의 문제는 해결 됩니다.

 

키넥트라는게 원래 게임용인걸 다른 용도로 쓰려다 이렇게 된거니 뭐...

 

삽질은 어쩔 수 없겠지요. 

,

요즘은 와이파이 확장에 무선 리피터보다 Mesh망을 더 많이 쓰는 듯 합니다

그도 그럴게 무선 리피터는 그냥 와이파이 신호를 받아서 다시 와이파이 신호를 쏘는 방식을 쓰는 반면 Mesh망은 여기저기 퍼진 노드들이 연계되면서 AP를 붙였다 뗐다 하는 방식이라 더 안정적이거든요

 

이렇게 되면 장점이 AP당 가해지는 부하가 분산 되면서 더 빨라지고 움직이면서 사용할 때 알아서 Handover 되면서 자연스럽게 속도 저하없이 와이파이 사용이 가능해집니다.

 

그에비해 리피터는 그냥 중간 지점에서 신호 중계하는 역할만 합니다. 그래서 대역폭이 반토막이 나는 문제가 생깁니다. 하지만 그만큼 오래된 기술이기에 그럭저럭 안정화 되어 최신 기기에선 적극적 Handover로 더 빠른 AP에 붙는 기능을 사용하면 그럭저럭 쓸만하게 인터넷을 쓸 수 있습니다.

 

다만 요즘 메쉬 기능이 갖는 큰 문제가 하나 있는데 제조사마다 호환을 말아먹은지 오래라서 같은 제조사제품 끼리만 된다는 겁니다. OpenWRT가 지원되는 공유기들이라면 이 문제는 빠져나갈 수 있지만 국내 원탑인 iptime제품은 OpenWRT가 쉽지 않지요. 그나마 MediaTek제품이면 어느정도 가능한데 대부분 쓰인 리얼텍 제품은 OpenWRT지원을 생각하기 힘듭니다.

 

 

 

최근 방에서 네트워크 속도가 너무 떨어져서 확인해보니 겨울이 되서 방문을 닫고 살아서 벽 2개를 뚫고 전파가 오기 힘들어서 그렇다는 결론을 냈습니다. 그래서 Mesh를 생각하고(방에서 쓰는 공유기가 A8004T로 컨트롤러모드가 가능한 제품입니다. 신호도 강한 편이지요. Mesh네트워크로 쓸만한게 무엇이 있을까 찾아보고 있었는데 밖에 비가 억수로 와서 나가기 귀찮음+방구석에서 옛날에 쓰던 A604(2014년 제조)이 보이는데 이건 Mesh가 안 되는 물건이라네요. 그래서 그냥 무선 리피터로 만들어서 달아봤습니다.

 

A604가 요상한 물건이라 유선은 100Mbps로 제한이 걸렸는데 무선은 867Mbps가 되는거라 무선 리피터용으로 쓰긴 좋았습니다. 무선을 받아서 무선으로 뿌리면 대역폭이 400정도로 반토막 나지만 어차피 유선이 100짜리인 이상한 물건이라 그냥 저냥 쓸 수 있습니다. 애초에 벽2개 뚫고 오는 신호도 80였었기에 박살나더라도 이게 어디냐 싶기도 했고요.

 

저희집 네트워크 구조는 대충 그리면 다음과 같습니다

 

방1에서 AP가 있고 다른 방에서 이 신호를 받아다가 인터넷을 합니다만 방1의 벽이 내력벽인 것인지 엄청 두꺼워서 다른 방에선 신호가 박살이 납니다.

 

그래도 거실은 문방향이기도 하고(문은 나무라 신호강도 문제가 없지요.) 거리상 문제로 속도가 떨어질 뿐이지만 다른 방은 속도가 엄청 떨어졌습니다. 특히 저 침실의 속도가 처참한데 5GHz는 포기해야 할 수준이고 2.4GHz가 딱 저 속도가 납니다. 심지어 화장실이 더 속도가 나네요. 그래서 메쉬를 쓰려고 한건데 역시 쉽지 않더군요. 대신 찾아보니 옛날에 쓰던 A604가 있더군요. 오래된 물건인데 어댑터가 망가진걸 제외하면 멀쩡합니다. 심지어 찾아보니 12V짜리 1A아무거다 꽂으면 된다네요.

 

그래서

 

이렇게 A604제품을 무선 리피터 설정 후에 돌리니까 침실에서 도저히 못볼 수준의 속도가 회복 되었습니다. 그리고 SSID와 비밀번호를 기존 A8004와 A604를 동일하게 하니 사용상의 큰 문제는 보이지 않았습니다. 

 

하지만 가끔 거실에서 침실로 들어오면 속도가 떨어지는 것이 보이더군요. 알고보니 무선 리피터는 동일한 SSID라도 성능이 더 높은걸 잡는게 아니라 기존에 잡았던 AP를 잡으려고 한다네요. Mesh는 컨트롤러가 이걸 확인하면서 다시 잡아주고요. (이러한 방식의 통신을 Backhaul이라고 합니다.) 물론 그럴때는 Wifi를 껐다 켜주면 되긴 합니다.

 

어쨌건 이것이 Mesh와 무선 리피터의 큰 차이점입니다. 알아서 더 강한 신호의 AP로 바꿔주는것과 기존의 것을 잡으려 시도하는 것. 당연히 Mesh가 쓸 수 있다면 무선 리피터 보다 훨씬 더 낫겠죠. 무엇보다 IP대역 하나를 더 먹지요. 어차피 255개중 하나라 크게 문제는 없겠지만...그리고 Iptime의 EasyMesh의 쉬운 구성방법보다 무선 리피터는 DHCP설정부터 해서 좀 복잡한 편이고요.

 

그러면 복잡한 방법을 한번 소개하고자 합니다.

 

우선, 위의 것을 생각해봅시다.

1. 2.4GHz는 이미 포화상태고 굳이 리피터로 퍼트릴 이유가 없습니다. 무엇보다 자세히는 말하지 않았지만 침실 앞에 전자렌지가 있다보니 2.4GHz는 기존 방1의 것만 쓰고 리피터로는 따로 안 쓰기로 합니다.

2. 그리고 리피터와 기존 AP의 이름을 동일하게 해서 귀찮음을 해소합니다.

 

그러기 위해선 우선 기존 공유기가 아닌 리피터로 쓸 공유기를 유선으로 연결합니다. 그리고 브라우저를 켜고 192.168.0.1(기본 관리자 모드)로 들어갑니다.

그리고 당연히 관리자 비밀번호를 바꿔야겠지요. 이건 뭐... 알아서 하실거고 기존 공유기와 충돌을 막기 위해 설정을 해야 합니다.

고급설정 - 내부 IP주소를 바꿔줍니다. 이게 곧 해당 리피터의 관리IP가 됩니다. 기존에 사용하던 공유기나 PC와 다른 IP를 써야 합니다. 그리고 DHCP를 꺼야 하는데 그냥 끄는 것이 아닌 간단한 옵션으로 DHCP가 유동적으로 꺼질 수 있게 하는 것이 좋습니다.

 

네트워크 관리 - DHCP서버설정에서 DHCP서버충돌에 "충돌 발견시 중단" 체크해 주시면 지금 설정 단계에선 DHCP가 동작하지만 만약 다른 공유기가 있거나 다른 DHCP서버가 있다면 알아서 서버가 꺼집니다.

 

이제 핵심기능입니다. 무선확장설정으로 들어가서 무선 확장 방식을 멀티브리지(리피터)로 바꾸고 AP검색 버튼을 눌러서 우리가 사용할 AP, 기존 공유기로 접속 합니다. 이때 접속이 되어다면 유선으로 연결된 PC에서 갑자기 인터넷이 될겁니다.

 

이제 편의를 위해서 무선설정/보안에서 기존에 쓰던 SSID와 비밀번호를 동일하게 합니다. 이래야 좀 편해질거거든요.

무선설정/보안에서 기존에 쓰던 이름과 암호를 그대로 넣어서 똑같이 해줍니다. 이러면 Handover가 되는 기기라면 알아서 바뀔것이고 안된다면 재접속시 더 강한 AP로 접속 할 겁니다.

 

설정이 완료된 공유기를 이제 중간 위치에 설치하면 리피터로 사용이 완료 됩니다.

 

Mesh가 안 되는게 아쉽기는하지만 이렇게라도 확장하니 그래도 편하네요.

,

옛날에 엄청 좋아했던 편의점?! 이라는 경영게임입니다.

 

보시다시피 가운데 그래픽이 돌아가있습니다.

원인은 솔직히 모르겠습니다...

 

우분투에서 Wine으로 돌리는 것이 문제인건지 아니면 그냥 최신 그래픽칩셋에서 문제가 일어난건지... DirectX 6으로 돌아가서 문제가 더 있는 것일지도 모르겠습니다. 일단은 가상머신에 Win98을 올린 다음 확인해볼 생각입니다.

 

그런데 진짜 왜 이러는지 모릅니다...

 

=================2022.05.17=================

 

해결했습니다

아주 간단한 문제인데 DirectDraw가 문제를 일으킨것이므로 이를 Direct3D11로 래핑(?)하고 이를 Wine의 Vulkan으로 추가 컨버팅하면 되는 것 이었습니다.

 

이방법은 dgvoodoo2 라는 프로그램으로 문제를 해결 할 수 있습니다.

고전게임 돌리는데 거의 필수적으로 사용됩니다만 아는 사람이 많지 않더군요. 본래는 고전게임중 Voodoo Glide 게임을 돌리기 위해서 시작되었던 것이 이젠 고전게임 필수 호환성 레이어가 되었습니다.

 

http://dege.freeweb.hu/dgVoodoo2/dgVoodoo2/

 

Downloads - Dege's stuffs

Downloads You need the 3Dfx splash dlls for Glide if you want 3Dfx splash screen or watermark (shameless plug) through dgVoodoo. 3DfxSplashDlls.zip  You may also need D3DRM.dll (Direct3D Retained mode) for some games and demos. It's not part of the OS sin

dege.freeweb.hu

위의 홈페이지에서 다운로드가 가능하며 

dgVoodoo2_78_2.zip
4.99MB

여기서도 다운로드가 가능합니다. 가능한 공식홈페이지에서 받는 것이 버전이 높아서 좋겠지요.

 

해당 파일의 압축을 풀면

이렇게 되어있는데 여기서 MS가 중요합니다. MS의 고전 파일 호환이라는 의미로 DirectX 구버전API용이란 의미입니다.

이 안에는 x86이라고 되어 있는 폴더가 있고 이 안에 DLL 4개가 핵심입니다.

특히 DDRAW.dll파일이 중요합니다.

어찌 되었건 해당 파일 4개를 설치된 고전게임의 exe가 있는 곳에 풉니다.

exe파일과 DDRAW.dll파일이 함께 있는 것이 확인되면 wineconfig을 실행합니다.

PlayonLinux나 Bottles를 쓴다면 해당 Prefix의 config을 실행합니다.

여기서 ddraw를 추가하여 네이티브로 설정합니다. 경고메시지가 뜨는데 무시합시다.

 

그리고 실행하면...!!! 

Wine Debugger창에서 신기한 내용이 뜹니다.

 

바로 d3d11을 사용하기 시작합니다. 물론 정확히는 d3d11을 다시 OpenGL로 한번더 컨버팅해서 렌더링하는 것인데 이걸로 그래픽깨짐을 회피 할 수 있습니다.

 

어찌되었건 간만에 이 오래된 고전게임을 할 수 있게되었네요.

 

-----------------그런데 생각해보면 미친짓이긴 하네요.

DirectDraw - D3D11 - OpenGL 두번거치면서 렌더링을 하다보니 쓸데없이 CPU가 묵직합니다. 이게 이럴정도는 아닌데...

 

---------------위에 미친짓이라고 쓰긴했는데...

생각보다 이런 방식으로 고전게임을 돌리는 경우가 많다고 합니다.

DirectDraw(DirectX7이하) - dgvoodoo(DirectX11)-DXVK(Vulkan)

이렇게 두번 거쳐서 현대적인 API인 Vulkan으로 최종 출력하는게 상당히 사례가 많다고 하네요.

저도 Wine의 OpenGL대신 DXVK를 써서 Vulkan으로 출력하니 묵직함이 사라졌습니다. 

 

만약 DirectX8이상이라면 그냥 DXVK를 적용해서 바로 Vulkan으로 출력하면 어지간해선 해결된다고 합니다.

,

사실 Chrome에서만 벌어지는 것이 아니지만 Firefox같은 다른 브라우저는 다른 방식인 건지 문제가 없었습니다.

 

아무튼 Youtube에서 메뉴버튼도 안 먹히고 재생버튼도 안 먹히는 등 문제가 생길 수 있습니다.

 

범인은..

https://chrome.google.com/webstore/detail/allow-right-click/hompjdfbfmmmgflfjdlnkohcplmboaeo

 

Allow Right-Click

Re-enable the possibility to use the context menu on sites that overrides it.

chrome.google.com

이 확장이 범인이었습니다.

 

오른쪽 버튼을 못 쓰게 막은 페이지를 가능하게 만드는 확장인데 이것이 유튜브와 문제를 일으키고 있었습니다.

 

Youtube에서 해당 기능이 동작하지 않도록 설정하면 아무 문제 없이 해당 확장 사용이 가능합니다.

크롬 오른쪽 위에서 해당 아이콘을 클릭 한 후에 옵션을 눌러주세요.

 

 

그러면 White list에 google|yahoo 라고 써있을 것입니다. 이 뒤에 

|youtube

이렇게 pipe ( | ) 기호를 적고 youtube라고 적은 다음 Save 버튼을 눌러주시면 기능이 정상적으로 동작 할 것입니다.

 

절대로 Slash ( / ) 가 아닙니다. Pipe기호 입니다. 역슬래시 ("\")위에 적힌 해당 기호를 말합니다.

,

이전에 Blu-ray를 우분투에서 보기위해 makemkv라는 프로그램을 설치했던 적이 있습니다.

참고 : https://moordev.tistory.com/322

 

지금은 사실상 유일한 블루레이 리핑 프로그램이라고 해도 과언이 아닙니다. DVD시절에는 DVDFab, Handbrake 등 여러수단이 있었지만 Blu-ray는 이상한 DRM을 넣어놓아서 굉장히 어려워 졌습니다. (그마저도 재생을 방해하는 수준입니다.)

 

심지어 4k 시대에 들어오면서 DRM이 너무 심해져서 그냥 4k BD대신 넷플릭스를 권할 정도가 되었습니다. 그렇지만 넷플릭스에 비해 워낙 화질이 좋다보니 BD로 나오면 이쪽으로 보고 싶어지는데 그냥보지 말라는 수준으로 만들어 놓아서 사놓아도 쓸 수가 없습니다. 그나마 PS5나 엑스박스정도만이 편하게 감상이 가능합니다.

 

이쯤되면 그냥 리핑해서 영상을 USB나 SD카드에 담은 다음 BD는 책꽂이 구석에 박아두는게 더 유리할겁니다. 그러려면 어찌되었건 리핑을 해야합니다.

제가 갖고 있는 것은 HP노트북에 끼워주었던 CU10N이라는 BD DVD RW 드라이브 입니다. DVD나 CD는 구울 수 있지만 BD는 못 굽습니다.

 

그런데 모든 블루레이 드라이브가 리핑이 가능한 것이 아니라고 합니다. 심지어 기존 FHD 블루레이는 리핑이 되지만 4k는 되지 않는 경우도 있고 그냥 최신 DRM이 지원이 안되서 BD재생은 폼인 경우도 있습니다.

그래서 많은삽질이 필요한데 리핑 가능성을 보고 싶다면 MakeMKV에서 확인이 가능합니다.

 

오른쪽에 LibreDrive Information을 보면 알 수 있습니다.

다 필요없고 Status에서 Enable 되면 4k UHD도 리핑이 가능합니다.

Possible이라고 되어있으면 수정된 펌웨어를 입히는 것으로 사용이 가능합니다.

Hardware Support가 No라고 되어있으면 포기하세요.

 

대부분 BD Drive는 LG-Hitachi의 제품을 추천합니다. 저는 다행히 OEM제품인데도 불구하고 Enable로 되어있습니다. (아무래도 LG에서 제작한 것으로 보입니다.) 엥간하면 지원이 된다는 거지요. 특히 Drive Platform이 MT1959면 다 가능성이 있다고 합니다.

 

아마도 3월중에 4K BD가 하나 올 예정인데 그때 한번 이걸로 시도해봐야 할 듯 합니다.

,

https://github.com/kornelski/pngquant

 

GitHub - kornelski/pngquant: Lossy PNG compressor — pngquant command based on libimagequant library

Lossy PNG compressor — pngquant command based on libimagequant library - GitHub - kornelski/pngquant: Lossy PNG compressor — pngquant command based on libimagequant library

github.com

png 파일은 그림파일로 많이 쓰입니다.

사실 png는 비손실 압축이기 때문에 용량은 줄이면서 화질을 유지하고 싶은사람들에게 좋은포맷입니다.

무엇보다 워낙 오래쓰여왔기에 못 여는 프로그램이 없지요.

 

사실 png파일 하나만 써도 용량문제는 거의 해결되는데 이걸 또 한번 더 압축하는 방법이 있습니다.

 

기본 png는 24비트로 구성되어 있고 포토샵이나 김프에서 작업한 이후에도 24비트로 만들어진 png파일이 나옵니다.

이것을 투명도를 깨뜨리지 않고 256색 png형태로 바꾸거나 JPEG수준으로 압축을 하는 형태로 용량을 줄일 수 있습니다.

 

TinyPNG라는 사이트가 있는데 이게 pngquant를 사용하는 것입니다.

 

우분투에서는 다음 명령으로 설치가 가능합니다.

sudo apt install pngquant

 

데비안에도 그대로 있습니다.

 

사용방법은

pngquant <압축할려고 하는 파일>.png

이렇게 하면 -fs8이라는 것이 붙으면서 파일 크기가 줄어듭니다.

한번 이 스크린샷을 이용해봅시다.

이 파일의 용량은 648.4KiB 입니다.

이걸 pngquant로 한번 압축을 하면...

이겁니다만... 별 차이가 없죠? 하지만 용량은

209.8KiB로 확 줄어들었습니다.

 

이것만으로도 엄청나게 용량절약이 되는겁니다. 포토샵 플러그인등으로도 나와있으니 이를 이용하면 PNG파일의 용량을 더 줄일 수 있을겁니다.

 

엄청나죠?

,

보통 동전건전지는 LR44 혹은 CR2032를 주로 씁니다. 자동차 스마트열쇠나 소형 손전등에 사용되지요.

 

그런데 가끔 CR1632배터리를 쓰는 것이 있습니다. 유럽에서는 CR2032보다 CR1632를 쓰는거 같더군요. 유럽산 자동차나 가전제품은 CR1632를 요구하는 경우가 있습니다.

 

사진은 일렉트로룩스사의 청소기인데 컨트롤러 부분이 고장나서 뜯어보니

건전지 끼우는 부분에 CR1632배터리를 끼워야 하더군요. 혹시나 하고 집에 굴러다니던 CR2032배터리를 끼우려고 하니 안 들어갑니다. 당연하겠지만...

 

그래서 근처에 배터리를 사러 갔더니 CR1632는 없네요..

 

대신 다이소에서 CR1616은 팝니다.

전압은 동일하고 지름은 같습니다. 대신 두께가 반정도로 얇습니다.

CR2032는 CR1632와 두께는 동일하지만 지름이 다르지요.

 

여기서 눈치 채신분이 있을거 같은데 CR 뒤에 붙는 숫자는 지름 두자리 + 두께 두자리 입니다. 그래서 앞에 두자리가 같으면 지름이 같다는 겁니다.

 

그럼 모자란 두께는 어떻게 처리하냐면..

이렇게 쿠킹호일을 사용하시면 됩니다. 이걸 접고 접고 접어서 모자란 부분에 끼워넣으면 됩니다.

 

다만, 이것도 극성이 있으니 +극쪽(그니까 글씨 써있는 쪽)에 호일을 끼우시는걸 추천합니다. -극쪽에서 옆부분과 닿으면 쇼트 납니다.

 

음.... 고쳤네요!

,

Renpy의 버전이 7.x로 넘어간지 오래되었다. 하지만 여전히 Python특유의 성능은 발목을 잡기는 하지만 2D 게임 특성상 기기의 성능이 좋아지면 당연히 요구치가 낮아지니까 크게 문제 되지 않을 수도 있다. (하지만 일부 효과가 가득한 게임은 스마트폰에서 문제가 많이 일어난다. 심지어 무한루프에 빠지는 경험도 했다.)

그리고 일부 게임은 여전히 6.xx를 사용하고 있고 이 버전은 안드로이드 포팅이 상당히 힘들다.

우선 필요한 것.
OpenJDK-8
이전버전도 안 되고 이후 버전도 안 된다. 이것을 사용해야 한다. 왜냐하면 android-sdk-23을 사용하기 때문인데 이건 자그마치 안드로이드 6.0이 나오면서 나온 SDK다. 당시 Java는 8버전이 LTS로 지원되고 있었기에 해당 버전을 써야한다.

우분투에서는 openjdk-8-jdk 패키지로 설치가 가능하다. 필요하다면 oracle에서 받아서써도 되지만 굳이 그럴 필요는 없다. (라이센스 문제가 복잡해진다.)

그다음 Google관련 툴에서 에러가 엄청나게 나온다.

처음 안드로이드 빌드에 들어온 사람은 Install SDK & Create Keys에서 처음 보는 에러를 경험하게 된다.

원래는 렌파이에서 SDK설치가 원할했지만 구글에서 SDK들을 정리하다보니 조금 복잡해져버렸다.
그래서 Android Studio를 설치해서 SDK복사를 해와야 한다.

우선 Android Studio를 설치하고 SDK Manager를 실행한다.

More Actions를 누르면 SDKManager가 있다. 이것을 실행하자

SDK Platforms 탭에선 23버전 (Android 6.0)을 설치하고 그리고 제일 중요한 SDK Tools 탭에서 Google Play APK Expansion library 와 Google Play licensing Library 두가지를 체크한뒤에 Apply를 누르자.

그리고 SDK가 설치된 곳으로 가자
SDK Manager에서 위에보면 Android SDK Location이라고 있다. 이것을 보면 된다.

그다음 extras 폴더를 복사해서 Renpy가 설치된 곳/rapt/android-sdk-r23 에 복사한다.

저 extras 폴더 안에 구글 라이브러리들이 들어있어야 한다.

그리고 또 수정을 해야 한다.
복사된 extras 폴더 안에 google로 들어가면

market_licensing market_apk_expansion 이렇게 되어있다. 이것을

play_licensing play_apk_expansion 으로 바꿔준다.

이제 Renpy를 다시 켜면 활성화가 안 되어있던 Configure가 활성화 되어있다.
빌드까지 하고 나면 rapt/bin안에 설정한이름-release.apk가 짠하고 있을 것이다. 원래는 Build & Install 하면 디버깅설정된 휴대폰에 설치까지 되어야 하는데 가끔 안 되는 경우가 있다. 그때는 이 apk를 가지고 사이드로딩을 시도하면 될 것이다. 의외로 ADB관련 오류도 잦은 편이다. (특히 케이블이 불량인 경우)

왜 이딴 작업을 했냐고 물어보면... 의뢰가 들어와서 한창 삽질을 했다. 자바 버전으로인해 오류가 날때는 정말....

그리고 지속적인 구버전 오류가 날 때는 .android.json파일을 수정해서 target과 minsdk를 수정할 필요가 있다. 특히 이제는 사용되지 않는 4.0 아이스크림 샌드위치용 코드가 문제를 일으킬 수 있으니 애초에 지원 안 됨을 못 박는게 더 나을 수 있다.

하지만 제일 좋은건 호환성에 전혀 문제가 없다면 렌파이 버전도 함께 올리는 것. 그래야 최신 폰 대응이 쉬워진다.

추가로 안드로이드는 rpa포맷 지원이 안 되는듯. rpa를 풀어서 game폴더에 위치해야 정상 구동이 가능하다. 이것 때문에 이틀동안 밤샘한거 생각하면 어휴...

,

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

요즘은 하도 버추얼 유튜버라는게 많아서 버추얼 유튜버가 되기위한 도구들이 많이 개발되었는데 (주로 일본에서) 이 버추얼 유튜버라는게 워낙 준비비용이 많이 들다보니 어떻게든 저렴하게 만들고자 많은 것들이 개발되었습니다.

 

그중 하나가 바로 웹캠으로 모션을 인식하는 것.

 

보통은 모션캡처 장비를 이용하거나 더 저렴하게 이용하고자 키넥트 여러개와 조합하거나 아니면 가속도센서를 부착한 팔과 머리만을 IK로 구현하거나 하는 방식이 주를 이루었는데 구글에서 Mediapipe라는 것을 공개하면서 2D 이미지만으로 사람의 모션을 그대로 인식하는 것이 만들어지게 되었습니다.

 

그런데... 본래 Mediapipe는 사람의 모션, 손의 제스처, 얼굴표정이 따로따로인데

https://github.com/yeemachine/kalidokit

 

GitHub - yeemachine/kalidokit: Blendshape and kinematics solver for Mediapipe/Tensorflow.js face, eyes, pose, and hand tracking

Blendshape and kinematics solver for Mediapipe/Tensorflow.js face, eyes, pose, and hand tracking models. - GitHub - yeemachine/kalidokit: Blendshape and kinematics solver for Mediapipe/Tensorflow.j...

github.com

이 툴킷은 그걸 한번에 모두 쓸수 있게 만든 툴킷입니다.

그것도 자바스크립트로 만들어서 그냥 웹브라우저에서 돌아갑니다.

 

자세히 보면 Mediapipe뿐만 아니라 tfjs도 사용합니다. 얼굴 표정은 Blendshape형태로 쓸수있게 - 눈을 감았다 떴다 여부와 입모양 아에이오우 정도)로 간략하게 인식하고 손가락은 따로 인식해서 각 손가락의 관절이 돌아간 각도를 리턴합니다.

 

일단 장점이라면 사용하기 편하다는것이랑 JS형태이므로 웹브라우저로 그냥 처리가 가능하다는점.

그리고 웹브라우저를 쓰는게 마음에 안 들면 JSON형태이니 그걸 그대로 뿌려버리면 된다는 것.

 

대충 예제코드를 살펴보면

import * as Kalidokit from 'kalidokit'
import '@mediapipe/holistic/holistic';
import '@mediapipe/camera_utils/camera_utils';

let holistic = new Holistic({locateFile: (file) => {
    return `https://cdn.jsdelivr.net/npm/@mediapipe/holistic@0.4.1633559476/${file}`;
}});

holistic.onResults(results=>{
    // do something with prediction results
    // landmark names may change depending on TFJS/Mediapipe model version
    let facelm = results.faceLandmarks;
    let poselm = results.poseLandmarks;
    let poselm3D = results.ea;
    let rightHandlm = results.rightHandLandmarks;
    let leftHandlm = results.leftHandLandmarks;

    let faceRig = Kalidokit.Face.solve(facelm,{runtime:'mediapipe',video:HTMLVideoElement})
    let poseRig = Kalidokit.Pose.solve(poselm3d,poselm,{runtime:'mediapipe',video:HTMLVideoElement})
    let rightHandRig = Kalidokit.Hand.solve(rightHandlm,"Right")
    let leftHandRig = Kalidokit.Hand.solve(leftHandlm,"Left")

    };
});

// use Mediapipe's webcam utils to send video to holistic every frame
const camera = new Camera(HTMLVideoElement, {
  onFrame: async () => {
    await holistic.send({image: HTMLVideoElement});
  },
  width: 640,
  height: 480
});
camera.start();

여기서 faceRig ,poseRig, rightHandRig, leftHandRig는 각각 JSON형태로 되어있는 객체이며

{
    eye: {l: 1,r: 1},
    mouth: {
        x: 0,
        y: 0,
        shape: {A:0, E:0, I:0, O:0, U:0}
    },
    head: {
        x: 0,
        y: 0,
        z: 0,
        width: 0.3,
        height: 0.6,
        position: {x: 0.5, y: 0.5, z: 0}
    },
    brow: 0,
    pupil: {x: 0, y: 0}
}
{
    RightUpperArm: {x: 0, y: 0, z: -1.25},
    LeftUpperArm: {x: 0, y: 0, z: 1.25},
    RightLowerArm: {x: 0, y: 0, z: 0},
    LeftLowerArm: {x: 0, y: 0, z: 0},
    LeftUpperLeg: {x: 0, y: 0, z: 0},
    RightUpperLeg: {x: 0, y: 0, z: 0},
    RightLowerLeg: {x: 0, y: 0, z: 0},
    LeftLowerLeg: {x: 0, y: 0, z: 0},
    LeftHand: {x: 0, y: 0, z: 0},
    RightHand: {x: 0, y: 0, z: 0},
    Spine: {x: 0, y: 0, z: 0},
    Hips: {
        worldPosition: {x: 0, y: 0, z: 0},
        position: {x: 0, y: 0, z: 0},
        rotation: {x: 0, y: 0, z: 0},
    }
}
{
    RightWrist: {x: -0.13, y: -0.07, z: -1.04},
    RightRingProximal: {x: 0, y: 0, z: -0.13},
    RightRingIntermediate: {x: 0, y: 0, z: -0.4},
    RightRingDistal: {x: 0, y: 0, z: -0.04},
    RightIndexProximal: {x: 0, y: 0, z: -0.24},
    RightIndexIntermediate: {x: 0, y: 0, z: -0.25},
    RightIndexDistal: {x: 0, y: 0, z: -0.06},
    RightMiddleProximal: {x: 0, y: 0, z: -0.09},
    RightMiddleIntermediate: {x: 0, y: 0, z: -0.44},
    RightMiddleDistal: {x: 0, y: 0, z: -0.06},
    RightThumbProximal: {x: -0.23, y: -0.33, z: -0.12},
    RightThumbIntermediate: {x: -0.2, y: -0.19, z: -0.01},
    RightThumbDistal: {x: -0.2, y: 0.002, z: 0.15},
    RightLittleProximal: {x: 0, y: 0, z: -0.09},
    RightLittleIntermediate: {x: 0, y: 0, z: -0.22},
    RightLittleDistal: {x: 0, y: 0, z: -0.1}
}

이런 구조이니 다른 프로그램에서 JSON을 파싱해서 쓰면 되는 것이지요. 자바스크립트로 만들면 JSON파싱하고 자시고도 필요없지만 특정 프로그램을 위해 Unity에서 사용한다거나 다른 프로그램에서 쓰겠다면 JSON파싱을 해주면 읽어낼수 있습니다. 저기있는 x,y,z가 LocalEulerRotation의 RADIAN이라는 것만 안 잊어버려도 충분히 쓸 수 있습니다.

 

Unity에선 그냥 Quarterninon으로 써주는게 가장 최적의 시나리오지만 일단 느리긴 하지만 Euler각도도 쓸 수는 있으니 이런 방식도 나쁘지는 않은 듯 합니다. Unity가 아닌 godot엔진을 쓴다고 해도 Python은 Json파서가 기본적으로 갖추어져 있으니 더더욱 편리하게 쓸 수 있을 겁니다. 혹은 blender도 쓸 수 있고요.

,