MyApp으로 나만의 로봇앱 만들기¶
MyApp은 PhysiCar를 제어하는 나만의 웹 앱입니다. 5000 포트로 실행하면 앱의
MYAPP 탭(/myapp/)에 나타납니다.
1. 최소 앱¶
/home/physicar/physicar_ws에 app.py를 만듭니다:
# app.py (최초 1회: pip install flask requests)
import requests
from flask import Flask, Response
app = Flask(__name__)
ROBOT = "http://localhost:8000" # 로봇의 로컬 Web API
@app.route("/")
def home():
return """
<button onclick="fetch('./forward')">전진</button>
<button onclick="fetch('./stop')">정지</button>
<img src="./photo">
"""
@app.route("/forward")
def forward(): requests.post(f"{ROBOT}/speed", json={"value": 0.5}); return {"ok": True}
@app.route("/stop")
def stop(): requests.post(f"{ROBOT}/speed", json={"value": 0.0}); return {"ok": True}
@app.route("/photo")
def photo(): return Response(requests.get(f"{ROBOT}/camera").content, mimetype="image/jpeg")
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
상대 경로를 쓰세요
nginx는 앱을 /myapp/ 아래에서 서빙하며 접두사를 뗍니다 — 링크·fetch()를 /...가
아니라 ./...로 쓰세요.
2. Web API로 제어¶
로봇의 로컬 Web API(8000 포트)가 모든 걸 움직입니다:
requests.post(f"{ROBOT}/speed", json={"value": 0.5}) # m/s
requests.post(f"{ROBOT}/steering", json={"value": 0.2}) # rad (좌 +)
jpeg = requests.get(f"{ROBOT}/camera").content # JPEG 바이트
state = requests.get(f"{ROBOT}/states").json() # 속도·배터리 등
3. AI 두뇌 달기¶
로그인한 사용자의 세션으로 chat API를 호출합니다.
사용자가 PhysiCar 앱에 로그인하면 내 앱으로 오는 모든 요청에 physicar_session 쿠키가
실려 옵니다(AI 사용량은 그 사용자의 크레딧에서 차감):
import base64
from flask import request
@app.post("/ask")
def ask():
token = request.cookies.get("physicar_session") # PhysiCar 앱 로그인 시 심어짐
b64 = base64.b64encode(requests.get(f"{ROBOT}/camera").content).decode()
r = requests.post("https://api.physicar.ai/chat",
headers={"Authorization": f"Bearer {token}"},
json={"user_message": {"contents": [
{"type": "image", "mime": "image/jpeg", "base64": b64},
{"type": "text", "text": "앞에 사람 있어? yes 또는 no."}]},
"prompt": {"model": "gemini-flash"}})
answer = r.json().get("text") or ""
if "yes" in answer.lower():
requests.post(f"{ROBOT}/speed", json={"value": 0.3})
return {"answer": answer}
토큰은 요청마다 읽으세요
physicar_session 쿠키는 요청마다 읽으세요 — 토큰 하나를 전역으로 캐시하면
공유 로봇에서 모두의 요청이 한 계정으로 과금됩니다.
브라우저에서도
nginx가 모든 /myapp/ HTML 페이지에 작은 헬퍼를 자동 주입하므로, 페이지의
자바스크립트에서도 window.physicarSession.token()으로 같은 토큰을 바로 읽을 수
있습니다 — 별도 설정이 없습니다.
4. 부팅 시 자동 시작¶
실행 명령을 /opt/physicar/userdata/myapp.sh에 넣습니다:
로봇은 이 파일을 서비스로 실행합니다: 부팅 시 myapp.sh가 있으면 자동으로 시작되고,
출력은 바로 옆의 myapp.log에 기록됩니다. 스크립트는 내 작업 폴더에서 실행되지
않으니 안에서는 절대 경로를 쓰세요. 앱이 5000 포트에 응답하기 전까지 MYAPP
탭에는 "MyApp is not running" 페이지가 뜨고, 앱이 뜨면 자동으로 새로고침됩니다.
재부팅 없이 반영하려면 /settings/myapp 아래의 관리 API를 쓰세요(/docs에서 전부 볼 수
있습니다 — 스크립트 교체·삭제, 로그 스트림):
curl -X POST http://localhost:8000/settings/myapp/restart # /start, /stop 도 있음
curl "http://localhost:8000/settings/myapp/log?tail=50" # 로그 읽기
점검: 5000 포트, 상대 경로, 실행 명령은 /opt/physicar/userdata/myapp.sh에.
🛠 미션: Follow-me 또는 문 앞 인사 로봇을 만들어보세요. 같은 앱이 실물 키트에서도 그대로 돌아갑니다.
더 알아보기
로봇 엔드포인트 → Web API. AI 요청 → Chat API 규격.