ํ๋ฉด ๋๋ผ๋ AI, ํ๋ฉด ์ผ์ ๋ ๊ณ ์น๋ VR โ GrowWise์ AmblyoPunch๊ฐ ๋ง๋ ์ง์ Hacktoberfest 'Touch Grass' ์ฑ๋ฆฐ์ง
์ง๋์ฃผ ๊ธ์์ผ ๋ฐค, GitHub ์๋ฆผ์ฐฝ์ด ์ธ๋ ธ๋ค. Hacktoberfest 'Touch Grass' ์ฑ๋ฆฐ์ง ์ด์๊ฐ ์ฌ๋ผ์จ ๊ฒ์ด๋ค. "ํ๋ฉด์์ ๋ฒ์ด๋ ๋ฐ๊นฅ ๊ณต๊ธฐ ๋ง์๊ธฐ"๋ผ๋ ์ทจ์ง. ์์ด๋ฌ๋ํ๊ฒ๋ ๋ด ๋ชจ๋ํฐ ์์๋ Unity ์๋ํฐ๊ฐ ์ด๋ ค ์์๊ณ , HMD ๋ ์ฆ ๋๋จธ๋ก ์์ด์ ์ฝ์ ์น๋ฃ์ฉ ์ฝํ ์ธ ๊ฐ ๋์๊ฐ๊ณ ์์๋ค. ํ๋ฉด ๋๋ผ๋ ์ด๋ ํ๋ณตํ์์, ํ๋ฉด ์ผ์ ๋์ ๊ณ ์น๋ ์ฝ๋๋ฅผ ์ง๊ณ ์๋ ๋. ๊ทธ ๋ชจ์์ด ์ ํํ GrowWise์ AmblyoPunch๊ฐ ๋ง๋๋ ์ง์ ์ด์๋ค.
์ฝ์ ์น๋ฃ, ์ VR์ธ๊ฐ
์ฝ์(amblyopia)๋ ๋๊ฐ ํ์ชฝ ๋์ ์ ๋ ฅ์ ์ต์ ํ๋ฉด์ ์๊ธด๋ค. ๊ธฐ์กด ์น๋ฃ๋ ์๋ ํจ์นญ(patching) โ ๊ฐํ ๋ ๊ฐ๋ฆฌ๊ณ ์ฝํ ๋๋ง ์ฐ๊ฒ ํ๊ธฐ. ์์ด๋ค์ ์ซ์ดํ๋ค. ์์ผ๊ฐ ์ข์์ง๊ณ , ์ ์ฒด์(stereopsis) ๋ฐ๋ฌ์ ๋์ ์ ๋๋ค. ์์๋(compliance) ๋จ์ด์ง๋ฉด ํจ๊ณผ๋ ์๋ค.
AmblyoPunch๋ ๋ค๋ฅธ ์ ๊ทผ์ ํํ๋ค. ์ด์์(dichoptic) ์๊ทน: ์ ๋์ ์๋ก ๋ค๋ฅธ ์ด๋ฏธ์ง ๋ณด์ฌ์ฃผ๋, ์ฝํ ๋์๋ง ์ค์ํ ์ ๋ณด(ํ๊ฒ, ๋ณด์ ์๊ทน) ๋ฃ๊ธฐ. ๊ฐํ ๋์ ๋ฐฐ๊ฒฝ๋ง. ๋๊ฐ "์ด? ์ฝํ ๋ ์ ๋ณด ํ์ํ๋ค" ํ๊ณ ํตํฉํ๋๋ก ์ ๋. ์ด๊ฑธ VR HMD๋ก ๊ตฌํํ๋ค. ๊ฐ ๋ ํด์๋ยท๋ฐ๊ธฐยท๋๋น ๊ฐ๋ณ ์ ์ด ๊ฐ๋ฅ. ์๊ฒฝํ AR๋ณด๋ค ๊ดํ ์๊ณก ์ ๊ณ , ์์ด๋ค ๋ชฐ์ ๋ ๋๋ค.
๊ธฐ์ ์คํ: Unity 2022 LTS + OpenXR. Meta Quest 2/3, Pico 4 ํ๊ฒ. ์
ฐ์ด๋์์ ์ข์ฐ ๋ ๋ ๋ ํ๊ฒ ๋ถ๋ฆฌ(Graphics.SetRenderTarget + singlePassStereoRendering false). ํฌ์คํธ ํ๋ก์ธ์ค์์ ๊ฐ ๋๋ณ ๊ฐ๋งยท๋๋นยท์ฑ๋ ์ปค๋ธ ์ ์ฉ. ํ๋ ์ ๋๋กญ 1ms๋ผ๋ ์๊ธฐ๋ฉด ๋ฉ๋ฏธ ์ ๋ฐ โ FixedUpdate ๋ฃจํ์์ ์์ ์ถ์ (eye tracking) ๋ฐ์ดํฐ ์ฝ์ด ์ค์๊ฐ ํฌ๋น์์ดํฐ๋ ๋ ๋๋ง(foveated rendering) ์ผ๊ณ ๋๋ค. Quest 2 ๊ธฐ์ค 72Hz ๊ณ ์ , GPU 12ms ์์ฐ.
GrowWise: ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ, ์๋ '์ฑ์ฅ ๊ธฐ๋ก'
AmblyoPunch๊ฐ ํด๋ผ์ด์ธํธ๋ผ๋ฉด GrowWise๋ ๋ฐฑ์๋. ์น๋ฃ ์ธ์ ๋ก๊ทธ ์์ง โ ์ง๊ณ โ ๋ณดํธ์ยท์๋ฃ์ง ๋์๋ณด๋. ๋จ์ ํ ๋ ๋ฉํธ๋ฆฌ ์๋๋ค. '์ฑ์ฅ ๊ธฐ๋ก'์ผ๋ก ํ๋ ์ ์ก์๋ค.
๋ฐ์ดํฐ ํ๋ฆ: HMD ๋ก์ปฌ SQLite(์คํ๋ผ์ธ ์ฐ์ ) โ ๋ฐฑ๊ทธ๋ผ์ด๋ ๋๊ธฐํ(Exponential backoff, max 24h) โ Firebase Firestore. ๋ฌธ์ ๊ตฌ์กฐ:
{
"sessionId": "uuid",
"childId": "hashed",
"date": "2024-10-15T19:30:00Z",
"durationSec": 1800,
"dichopticConfig": { "contrastRatio": 0.3, "targetFreq": 2.5 },
"gazeHeatmap": "base64_compressed",
"complianceScore": 0.92,
"visualAcuityEstimate": { "logMAR": 0.4, "confidence": 0.78 }
}
gazeHeatmap์ 1์ด๋น 1์ํ, 30๋ถ ์ธ์
์ด๋ฉด 1800ํฌ์ธํธ. ์์ถ ํ 40KB ์์ค. Firestore ๋ฌธ์ ํฌ๊ธฐ 1MB ์ ํ ์ฌ์ ์๊ฒ ๋ง์ถ๋ค.
์ง๊ณ ํ์ดํ๋ผ์ธ์ Cloud Functions (Node 20) + BigQuery. ์ผ๋ณยท์ฃผ๋ณยท์๋ณ ์ปดํ๋ผ์ด์ธ์ค ํธ๋ ๋, ์๋ ฅ ์ถ์ ์น ํ๊ท์ , ์๊ทน ํ๋ผ๋ฏธํฐ๋ณ ํจ๊ณผ ํฌ๊ธฐ(effect size) ์ฐ์ถ. ๋ณดํธ์ ์ฑ(React Native Expo)์์ "์ด๋ฒ ์ฃผ 4์ผ, ํ๋ฃจ 25๋ถ ํ๊ท " ๊ฐ์ ๋ฌธ์ฅ์ผ๋ก ๋ณด์ฌ์ค๋ค. ์ซ์ ์๋ '์ด์ผ๊ธฐ'๋ก.
ํด์ปคํค ์ด์์์ ๋ง๋ ์ ์ฝ๋ค
Hacktoberfest ์ด์ ํ
ํ๋ฆฟ์ "Touch Grass: ์ผ์ธ ํ๋ ์ฌ์ง ์ฌ๋ฆฌ๊ธฐ"๋ผ ์ ํ ์์๋ค. ๋ด PR ์ ๋ชฉ: feat: add outdoor-mode ambient-light-compensation. ๋ด์ฉ: ์ค์ธ์์ HMD ์ธ ๋ ์ฃผ๋ณ๊ด ๊ฐํด์ง๋ฉด ๋๋น๋น(contrast ratio) ์๋ ๋ณด์ . AmbientLightSensor API(์น) ํน์ Android SensorManager.TYPE_LIGHT ์ฝ์ด ์
ฐ์ด๋ ์ ๋ํผ u_AmbientLux๋ก ๋๊ธด๋ค. 10,000 lux ์ด์์ด๋ฉด contrastRatio *= 1.3. ์ค๋ด 300 lux ๊ธฐ์ค ๋๋น.
๋ฆฌ๋ทฐ์ด ์ฝ๋ฉํธ: "์ด๊ฒ ์ง์ง Touch Grass๋ค. ๊ทผ๋ฐ ๋ฐฐํฐ๋ฆฌ 20% ๋ ๋จน๋๋ฐ?" ํ๋กํ์ผ๋ง ํด๋ณด๋ ์ผ์ ํด๋ง 10Hz โ 1Hz๋ก ์ค์ด๊ณ , ๋ณด์ ์ฐ์ฐ์ ํ๋ ์ ์ฒซ 0.2ms๋ง. ๋ฐฐํฐ๋ฆฌ ์ํฅ 3% ์ด๋ด๋ก ์ก์๋ค. adb shell dumpsys batterystats ๋ก ํ์ธ.
๋ ๋ค๋ฅธ ์ด์: "์์ด๋ค HMD ๋ฒ์ ๋ ๋จธ๋ฆฌ์นด๋ฝ ์ํค์ง ์๊ฒ ์คํธ๋ฉ ๊ฐ์ ". ์ด๊ฑด ํ๋์จ์ด์ง๋ง, ์ํํธ์จ์ด๋ก ํ ์ ์๋ ๋ถ๋ถ โ ์ธ์
์ข
๋ฃ 30์ด ์ ๋ถํฐ ํ์ด๋์์ํ๋ฉด์ "์ ์๋ง์, ์คํธ๋ฉ ํ๊ณ ๋ฒ์ผ์ธ์" ์์ฑ ์๋ด(ํ๊ตญ์ด/์์ด/์ผ๋ณธ์ด TTS). AudioSource.PlayScheduled๋ก ํ์ด๋ฐ ๋ง์ถค. ์์ UX์ง๋ง ๋ณดํธ์ ๋ฆฌ๋ทฐ์์ "์ด๊ฑฐ ์ง์ง ์ธ์ฌํ๋ค์" ๋๊ธ ๋ฌ๋ ธ๋ค.
๋ด ์์ด, ๋ด ์ฝ๋, ๋ด ๋ฐค
๋ฏผ์ค์ด(๊ฐ๋ช ), ์ฌ์ฏ ์ด. ์ค๋ฅธ์ชฝ ๋ logMAR 0.6. ์๋ ํ๋ฃจ ๋ ์๊ฐ, ์ธ๋ฉด์ ๋ฒ์ผ๋ ค ํ๋ค. ์๋ 11์, AmblyoPunch ๋ฒ ํ ๋น๋ ๋ฐ์์๋ค. ์ฒซ๋ 8๋ถ. ๋์งธ ๋ 12๋ถ. ์ผ์ฃผ์ผ ๋ค 25๋ถ ์ฑ์ ๋ค. "์๋น , ์ด๊ฑฐ ๊ฒ์์ด์ผ? ๋ ์ด๋์ด์ผ?" ๋ฌป๊ธธ๋ "๋ ๋ค"๋ผ๊ณ ๋ตํ๋ค.
GrowWise ๋์๋ณด๋์์ ์ปดํ๋ผ์ด์ธ์ค 0.87 ์ฐํ ๋ , ๋๋ ๋ชจ๋ฅด๊ฒ ์คํฌ๋ฆฐ์ท ์ฐ์ด ์๋ดํํ ๋ณด๋๋ค. ์๋ด๋ "๊ณ ์ํ์ด" ํ ๋ง๋. ๊ทธ ๋ค์ ์ค๋ ์นจ๋ฌต์ด ๋ ๋ฌด๊ฒ๋ค. ๊ฐ๋ฐ์๋ก์ ๋ด ์ฝ๋๊ฐ ์์ด ๋ ์์ ๋ค์ด๊ฐ๋ค๋ ๊ฑด, ๋ฐฐํฌ ํ์ดํ๋ผ์ธ ํต๊ณผ ๋ฉํธ๋ฆญ๊ณผ๋ ๋ค๋ฅธ ๋ฌด๊ฒ๋ค.
๋ฐค 11์, git push origin main ํ๊ณ CI ๊ทธ๋ฆฐ ๊ธฐ๋ค๋ฆฌ๋ฉฐ ์๊ฐํ๋ค. Hacktoberfest 'Touch Grass' ์ฑ๋ฆฐ์ง๋ ๊ฐ๋ฐ์๋ค์๊ฒ "ํ๋ฉด ๋ฒ์ด๋๋ผ"๊ณ ๋งํ๋ค. ๋ง๋ค. ์ฐ๋ฆฌ๋ ๊ทธ๋์ผ ํ๋ค. ํ์ง๋ง ์ด๋ค ํ๋ฉด์ ์ผ์ ธ ์์ด์ผ ํ๋ค. ์์ด์ ์ฝํ ๋์ด ์ธ์์ ๋ค์ ๋ฐฐ์ฐ๋ ๋์, ๊ทธ ํ๋ฉด์ ์น๋ฃ ๋๊ตฌ๋ค. GrowWise๊ฐ ๊ธฐ๋กํ๋ ๊ฑด ํ๋ฉด ์๊ฐ์ด ์๋๋ผ 'ํ๋ณต ์๊ฐ'์ด๋ค.
๊ธฐ์ ์ ๋ถ์ฑ, ๊ทธ๋ฆฌ๊ณ ๋ค์ ์คํ๋ฆฐํธ
ํ์ฌ ์๋ ค์ง ์ด์:
- Quest 2 ๋จ์ ํด์๋ 1832ร1920, ํฌ๋น์์ดํฐ๋ ๋ ๋๋ง ๋ฏธ์ง์ โ ์ฃผ๋ณ๋ถ ํ์ง ์ ํ. Quest 3 ์ ๊ทธ๋ ์ด๋ ๊ถ์ฅ.
- ์์ ์ถ์ ์บ๋ฆฌ๋ธ๋ ์ด์ 5ํฌ์ธํธ, ์์ด๋ค ์ง์ค๋ ฅ ์งง์ ์คํจ์จ 15%. 3ํฌ์ธํธ ๊ฐ์ํ ๋ธ๋์น ์คํ ์ค.
- Firestore ์ค์๊ฐ ๋ฆฌ์ค๋ ๊ณผ๊ธ ํญ์ฆ ๋ฐฉ์ง โ
onSnapshot๋์ 5๋ถ ํด๋ง + ๋ก์ปฌ ์บ์ ์ ๋ต์ผ๋ก ์ ํ ์์ . - ๋ค๊ตญ์ด TTS ์์ฑ ํฉ์ฑ ํ์ง ๋ถ๊ท ํ. ํ๊ตญ์ด
ko-KR-Standard-C์์ฐ์ค๋ฌ์ด๋ฐ ์ผ๋ณธ์ดja-JP-Standard-B๋ก๋ด ํค. SSML<prosody>ํ๋ ํ์.
๊ธฐ์ ๋ธ๋ก๊ทธ ๋ ์๋ผ๋ฉด ์ ๊ฒ์ด๋ค. ์ด ์ ๋ ๋ถ์ฑ๋ '์ถ์ ํ ๊ฐ์ ' ํด๋์ ๋ค์ด๊ฐ๋ค. ์ค์ํ ๊ฑด ์์ด๋ค์ด ์ค๋๋ ํค๋์ ์ฐ๊ณ 25๋ถ ๋ฒํ ผ๋ค๋ ์ฌ์ค. ๊ทธ ๋ฐ์ดํฐ๊ฐ GrowWise์ ์์ด๊ณ , ๋ค์ ์ฃผ ์์ฌ๊ฐ "์ค๋ฅธ์ชฝ ๋ 0.1 ์ข์์ก๋ค์" ๋งํ ๋, ๋ด ์ปค๋ฐ ๋ก๊ทธ ํ ์ค์ด ๊ทธ ๋ฌธ์ฅ ์์ ์จ์ด ์๋ค.
ํ๋ฉด, ๋๊ณ ์ผ๊ณ ์ฌ์ด์ ๊ท ํ
Hacktoberfest ๋ฐฐ์ง ํ๋ ๋ฐ์๋ค. 'Touch Grass' ๋ผ๋ฒจ ๋ฌ๋ฆฐ PR ๋จธ์ง. ์๋๋ฐญ ์ฌ์ง ๋์ HMD ์ด ์์ด ๋ท๋ชจ์ต ์ฌ๋ ธ๋ค. ์บก์ : "ํ๋ฉด ๋๋ผ๋ ์ฑ๋ฆฐ์ง์์, ํ๋ฉด ์ผ์ ๋ ๊ณ ์น๋ ์ฝ๋ ์ง๊ธฐ. ๋ ๋ค ํ์ํ๋ค."
๋๊ธ ํ๋ ๋ฌ๋ ธ๋ค. "์ด๊ฒ ์ง์ง ํด์ปค ์ ์ ์ด๋ค. ํ๋ฆฌํ ๋ณด๋ด์ค์ ๊ณ ๋ง์."
๊ทธ๋ ๋ฐค, ๋ฏผ์ค์ด ์ฌ์ฐ๊ณ ๋ชจ๋ํฐ ๋๋ค. ๋ฐฉ ์ ์ด๋์์ง๋ค. ๊ทธ๋ฐ๋ฐ ๋ ๊ฐ์๋ ์ฝ๋ ์กฐ๊ฐ๋ค์ด ๋ ๋ค๋๋ค. u_AmbientLux, contrastRatio, complianceScore. ๊ทธ ๋ณ์๋ค ์์ ์์ด์ ๋ด์ผ์ด ์๋ค. ํ๋ฉด ๋๋ ๋ฐค์๋, ์ด๋ค ํ๋ฉด์ ๋ง์์์์ ๊ณ์ ๋์๊ฐ๋ค. ๊ทธ๊ฒ ๋ด๊ฐ ์ฐ๋ ์ฝ๋์ ์๋ฏธ๋ค.
๋ค์ ์คํ๋ฆฐํธ์ ์ค์ธ ๋ชจ๋ ๋ฐฐํฐ๋ฆฌ ์ต์ ํ ๋ ํ๊ณ ๋ค ์์ . SensorManager ์จ์ดํฌ๋ฝ ์ต์ํ, JobScheduler๋ก ๋ฐฐ์น ์ฒ๋ฆฌ. ํน์ ๋น์ทํ ๋ฌธ์ ํ๊ณ ๊ณ์ ๋ถ, ์ด์ยทPR ํ์ํฉ๋๋ค. ์์ด๋ค ๋ ๊ฑด๊ฐ ์งํค๋ ์ฝ๋, ํจ๊ป ์ง์.
Top comments (0)