# ๐ฑ GrowWise: An AI Garden Coach That Wants You to Close This Tab and Touch Some Actual Grass
ํ๋ฉด ๋๋ผ๋ AI, ํ๋ฉด ์ผ์ ๋ ๊ณ ์น๋ VR โ GrowWise์ AmblyoPunch๊ฐ ๋ง๋ ์ง์ Hacktoberfest 'Touch Grass' ์ฑ... ์ง๋ ๊ฐ์, ๋๋ ํด์ปคํค ์์ฆ์ ๋ง์ Hacktoberfest โTouch Grassโ ์ฑ๋ฆฐ์ง์ ์ฐธ์ฌํ๊ธฐ๋ก ํ๋ค. ํ์์ ์คํ์์ค ๊ธฐ์ฌ๋ฅผ ์ํด PR์ ๋์ง๋ ๊ฒ ์ผ์์ด์์ง๋ง, ์ด๋ฒ์๋ โํ๋ฉด์ ๋๋ผ๋ AIโ์ โํ๋ฉด์ ์ผ์ ๋์ ๊ณ ์น๋ VRโ์ด๋ผ๋ ๋ชจ์๋ ๋ฌธ๊ตฌ๊ฐ ๋จธ๋ฆฟ์์ ๋งด๋์๋ค. ๋ด ๋์ ์ด๋ฏธ ์ค๋์ ๋ถํฐ ์ฝ์(amblyopia) ์ฆ์์ผ๋ก ํ๋ฆฟํ๊ณ , ์์ฌ๋ โ์คํฌ๋ฆฐ ํ์์

์ง๋ ๊ฐ์, ๋๋ ํด์ปคํค ์์ฆ์ ๋ง์ Hacktoberfest โTouch Grassโ ์ฑ๋ฆฐ์ง์ ์ฐธ์ฌํ๊ธฐ๋ก ํ๋ค. ํ์์ ์คํ์์ค ๊ธฐ์ฌ๋ฅผ ์ํด PR์ ๋์ง๋ ๊ฒ ์ผ์์ด์์ง๋ง, ์ด๋ฒ์๋ โํ๋ฉด์ ๋๋ผ๋ AIโ์ โํ๋ฉด์ ์ผ์ ๋์ ๊ณ ์น๋ VRโ์ด๋ผ๋ ๋ชจ์๋ ๋ฌธ๊ตฌ๊ฐ ๋จธ๋ฆฟ์์ ๋งด๋์๋ค. ๋ด ๋์ ์ด๋ฏธ ์ค๋์ ๋ถํฐ ์ฝ์(amblyopia) ์ฆ์์ผ๋ก ํ๋ฆฟํ๊ณ , ์์ฌ๋ โ์คํฌ๋ฆฐ ํ์์ ์ค์ด๋ผโ๊ณ ๋ง ๋ฐ๋ณตํ๋ค. ๊ทธ๋ฐ๋ฐ VR ํค๋์ ์ ์ฐ๊ณ ํ๋ จ์ฉ ์ฝํ ์ธ ๋ฅผ ๋๋ฆฌ๋ฉด ์คํ๋ ค ์๋ ฅ์ด ๊ฐ์ ๋ ์ ์๋ค๋ ์ด์ผ๊ธฐ๋ฅผ ๋ค์๋ค. GrowWise์ AmblyoPunch๋ผ๋ ๋ ํ๋ก์ ํธ ์ด๋ฆ์ด ๋์์ ๋ฑ์ฅํ๊ณ , ๋๋ ๊ทธ ๋์ด ์ด๋ป๊ฒ ๋ง๋๋์ง ์ง์ ํ์ธํด๋ณด๊ณ ์ถ์๋ค.
GitHub์์ growwise/vr-amblyopia ์ amblyopunch/training-core ๋ฆฌํฌ์งํ ๋ฆฌ๋ฅผ ํด๋ก ํ๋ค. ๋ ๋ค MIT ๋ผ์ด์ ์ค๋ก ๊ณต๊ฐ๋์ด ์์๊ณ , README์๋ โ์ค์๊ฐ ์์ ์ถ์ ๋ฐ์ดํฐ ์์งโ๊ณผ โ์ ์ํ ๋ ๋๋ง ํ์ดํ๋ผ์ธโ์ด๋ผ๋ ํค์๋๋ง ์ ํ ์์๋ค. ๋ฌธ์ํ๋ ์ต์ํ์ด์์ง๋ง, ์ด์ ํธ๋์ปค์๋ โUnity 2022.3 + OpenXR 1.5์์ ๋์ ํ์ธโ์ด๋ผ๋ ์ฝ๋ฉํธ๊ฐ ์์๋ค. ๋๋ ๊ณง๋ฐ๋ก ๋ก์ปฌ ๋จธ์ ์ Unity Hub๋ฅผ ์ด๊ณ , OpenXR ํ๋ฌ๊ทธ์ธ์ ์ถ๊ฐํ ๋ค ์ํ ์ฌ์ ๋น๋ํด๋ณด์๋ค.
// Assets/Scripts/AmblyopiaTrainer.cs using UnityEngine; using UnityEngine.XR; public class AmblyopiaTrainer: MonoBehaviour { void Update () { // ํ๋ ์๋ง๋ค ์์ ๋ ๋๋ง ํด์๋ ๋์ ์กฐ์ float scale = Mathf. Lerp ( 0.5f, 1.5f, GetGazeWeight ()); XRSettings. eyeTextureResolutionScale = scale; } float GetGazeWeight () { // GrowWise ์์ ๋ฐ์ดํฐ ์คํธ๋ฆผ์์ ๊ฐ์ค์น ์ถ์ถ (์์) return GrowWiseSDK. Instance?. CurrentGazeWeight?? 0.5f; } } Enter fullscreen mode Exit fullscreen mode ์ ์ฝ๋๋ ๋ด๊ฐ ์์ฑํ ํ๋กํ ํ์ ์ ํต์ฌ ๋ฃจํ๋ค. XRSettings.eyeTextureResolutionScale ์ ๋ฐํ์์ ์กฐ์ ํด ์์ ํด์๋๋ฅผ ๋น๋์นญ์ผ๋ก ๋ง๋ค๋ฉด, ์ฝ์ ๋์ ๋ ๋ง์ ๋ํ ์ผ์ ์ ๊ณตํ ์ ์๋ค๋ ์์ด๋์ด๋ค. ์ค์ GrowWise SDK๊ฐ ์ด๋ค ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๋์ง๋ ๋ฌธ์๊ฐ ์์ด์, CurrentGazeWeight ๋ผ๋ ๊ฐ์์ ํ๋กํผํฐ๋ก ๊ฐ์ ํ๋ค. ์ด ๋ถ๋ถ์ ๋์ค์ ๊ณต์ API๊ฐ ๊ณต๊ฐ๋๋ฉด ๊ต์ฒดํ ์์ ์ด๋ค.
๊ธฐ์ ๋ธ๋ก๊ทธ๋ฅผ ์ฐ๋ ์ ์ฅ์์ ๊ฐ์ฅ ํฅ๋ฏธ๋ก์ ๋ ๊ฑด โ์์ ๋ฐ์ดํฐ โ ๋ ๋๋ง ํ๋ผ๋ฏธํฐโ ํ๋ฆ์ ์ด๋ป๊ฒ ์ง์ฐ ์์ด ์ฐ๊ฒฐํ๋๋์๋ค. GrowWise๋ ํค๋์ ๋ด์ฅ ์์ดํธ๋์ปค์์ 90 Hz๋ก ์์ ๋ฒกํฐ๋ฅผ ๋ฟ๋ ค์ค๋ค. AmblyoPunch๋ ์ด ๋ฒกํฐ๋ฅผ ๋ฐ์ ๊ฐ ํ๋ ์๋ง๋ค eyeTextureResolutionScale ๊ณผ foveatedRendering ํ๋ผ๋ฏธํฐ๋ฅผ ๊ฐฑ์ ํ๋ค. ๋ ์์คํ ์ฌ์ด์ ๋ฉ์์ง ํ๋ฅผ ๋๋ฉด ๋ ์ดํด์๊ฐ 2~3 ํ๋ ์(์ฝ 30 ms) ๋์ด๋๋ค. ๋ฐ๋ฉด, Unity์ XRDisplaySubsystem ์ฝ๋ฐฑ ์์์ ์ง์ ์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ผ๋ฉด 1 ํ๋ ์(โ11 ms) ์ด๋ด๋ก ๋๋ผ ์ ์๋ค.
๋ด ํ ์คํธ ํ๊ฒฝ(Quest 2, Snapdragon XR2)์์ ๋ ๋ฐฉ์์ ํ๋ ์ ํ์์ ์ธก์ ํด๋ดค๋ค.
์ง์ ์ฝ๋ฐฑ ๋ฐฉ์์ด 1.5 ms ์ ๋ ๋น ๋ฅด์ง๋ง, ์ฝ๋ ๋ณต์ก๋๋ ๋ ๋๋ค. ๋๋ โ์์ ์ฑ > ์ต๊ณ ์ฑ๋ฅโ์ด๋ผ๋ ํ๋จ ์๋ ๋ฉ์์ง ํ๋ฅผ ์ ์งํ๊ธฐ๋ก ํ๋ค. ๋์ค์ ํ๋ก๋์ ๋น๋์์๋ Burst Compiler ์ Job System ์ผ๋ก ๋ณ๋ ฌํ๋ฅผ ์๋ํด๋ณผ ์๊ฐ์ด๋ค.
๋น๋๋ฅผ ๋ง์น๊ณ ํค๋์ ์ ์ฐ๊ณ ์ฒซ ์ธ์ ์ ์์ํ๋ค. ํ๋ฉด ์ค์์ ๋ ์๋ ๊น๋นก์ด๋ ํ๊ฒ์ ์ ๋์ผ๋ก ์ซ์ผ๋ผ๋ ์๋ด๊ฐ ๋ด๋ค. ๊ทธ๋ฐ๋ฐ ๋ด ์ผ์ชฝ ๋(์ฝ์ ๋)์ ํ๊ฒ์ ๊ฑฐ์ ์ธ์ํ์ง ๋ชปํ๋ค. ํ๋ ์ ๋๋์ด ์ฌํด์ ธ 45 fps๊น์ง ๋จ์ด์ก๊ณ , ํค๋์ ๋ด์ฅ ํฌ์ด ๊ณผ์ด ๊ฒฝ๊ณ ๋ฅผ ์ธ๋ ธ๋ค. ๋๋ ๋นํฉํด์ ํค๋์ ์ ๋ฒ๊ณ ์ฑ ์์ ์๋๋ ธ๋ค. โ์ด๊ฒ ์ ๋ง ๋ ๊น?โ๋ผ๋ ์์ฌ์ด ๋ฐ๋ ค์๋ค.
๊ทธ ์๊ฐ, ๋ด ๋ฐฉ ์ฐฝ๊ฐ๋ก ๋ค์ด์จ ์คํ ํ์ด์ด ์ฑ ์ ์ ํค๋ณด๋์ ๋น์ณค๋ค. ๋๋ ์จ์ ๊น๊ฒ ๋ค์ด๋ง์๊ณ , ๋ค์ ํค๋์ ์ ์ผ๋ค. ์ด๋ฒ์๋ QualitySettings.vSyncCount = 0 ์ผ๋ก ์ค์ ์ ๋ฐ๊พธ๊ณ , Application.targetFrameRate = 72 ๋ก ๊ณ ์ ํ๋ค. ํฌ ์์์ด ์ค์ด๋ค์๊ณ , ํ๋ ์ ํ์์ด 11 ms๋๋ก ์์ ๋๋ค. ํ๊ฒ์ด ์ ๋ช ํด์ง์ ์ผ์ชฝ ๋์ด ์กฐ๊ธ์ฉ ๋ฐ์ํ๊ธฐ ์์ํ๋ค. 10๋ถ ๋ค, ๋๋ ์ฒ์์ผ๋ก โ์ผ์ชฝ ๋์ผ๋ก๋ ๋ฌด์ธ๊ฐ๋ฅผ ๋ณผ ์ ์๋คโ๋ ๋๋์ ๋ฐ์๋ค. ๊ทธ ์๊ฐ์ ๊ฐ๋์ ์ฝ๋ ํ ์ค๋ก๋ ์ค๋ช ํ ์ ์๋ค.
๋ PR ๋ชจ๋ 24์๊ฐ ๋ด์ ๋ฉ์ธํ ์ด๋๋ก๋ถํฐ โThanks! Merged.โ๋ผ๋ ์ฝ๋ฉํธ๋ฅผ ๋ฐ์๋ค. ๋ด ๊ธฐ์ฌ๊ฐ ๋๊ตฐ๊ฐ์๊ฒ ๊ฐ์ ๊ณ ํต์ ๋์ด์ค ์ ์๋ค๋ ์ฌ์ค์ด, ํด์ปคํค ๋ณด์๋ณด๋ค ๋ ํฐ ๋ณด๋์ด์๋ค.
์์ผ๋ก ํด๋ณด๊ณ ์ถ์ ๊ฑด, GrowWise์ ์์ ํํธ๋งต์ ์ค์๊ฐ์ผ๋ก ์๊ฐํํด ํ๋ จ ์งํ๋๋ฅผ ๋์๋ณด๋์ ๋์ฐ๋ ๊ฒ ์ด๋ค. Grafana + Loki ์คํ์ผ๋ก ๋ก๊ทธ๋ฅผ ๋ชจ์ผ๊ณ , Unity ์ชฝ์์ UnityWebRequest ๋ก ๋ฉํธ๋ฆญ์ ํธ์ํ๋ฉด ๋๋ค. ์ด ๋ถ๋ถ์ ๋ค์ Hacktoberfest ๋ ๋์ ํด๋ณผ ๊ณํ์ด๋ค.
์ฒ์์ โํ๋ฉด์ ๋๋ผ๋ AIโ๋ผ๋ ๋ง์ ๊ณ ๊ฐ๋ฅผ ๊ฐธ์ํ๋ค. ๊ทธ๋ฐ๋ฐ VR ํค๋์ ์ ์ฐ๊ณ , ์ฝ๋ ํ ์ค ํ ์ค์ด ๋ด ๋์ ์ด์ ์ ์กฐ๊ธ์ฉ ๋ง์ถ์ด์ฃผ๋ ๊ฑธ ๋ณด๋ฉฐ ๊นจ๋ฌ์๋ค. ๊ธฐ์ ์ ๋จ์ํ ํ๋ฉด์ ์ผ๊ณ ๋๋ ์ค์์น๊ฐ ์๋๋ผ, ์ฐ๋ฆฌ ๋ชธ๊ณผ ๋ง์์ ๋ค์ ์ฐ๊ฒฐํด์ฃผ๋ ๋ค๋ฆฌ๊ฐ ๋ ์ ์๋ค.
๋ง์ฝ ๋น์ ๋ ๋น์ทํ ๊ณ ๋ฏผ์ ์๊ณ ์๋ค๋ฉด, ์์ ํค๋์ ๊ณผ ์คํ์์ค ๋ฆฌํฌ์งํ ๋ฆฌ ํ๋๋ถํฐ ์์ํด๋ณด๊ธธ ๊ถํ๋ค. ํจ๊ป ์ด ์ฌ์ ์ ๊ฑธ์ด๋ณด์๊ฒ ์ด์?