Skip to content

Dashboard

thingsub edited this page Dec 22, 2025 · 8 revisions

Plotto Dashboard Code

0. 개요

본 문서는 로봇 드로잉 시스템 PlottoDashboard.js 파일을 설명합니다.
Dashboard는 사용자 입력을 수집하여 Spine 모듈에 전달하고, Sketch 모듈을 통해 결과를 시각적으로 확인할 수 있도록 하는 중간 제어 인터페이스 역할을 수행합니다.

이 문서에서는 대시보드를 구성하는 버튼, 슬라이더, 파일 입력 위젯을 중심으로 각 UI 요소가 수행하는 기능과 시스템 내 위치를 설명합니다.


1. 전역변수

자세히 보기
  • init (boolean)

    • 시스템 초기화 여부를 나타내는 변수
    • 기본값: false. 대시보드가 처음 로드될 때 true로 설정됨.
  • angles (배열 [J1, J2])

    • 로봇의 두 관절(Joint 1과 Joint 2)의 각도를 저장하는 배열
    • 기본값: [0, 0] (각각 J1과 J2의 초기 각도)
  • targetAngles (배열 [J1, J2])

    • 목표 각도를 저장하는 배열. 슬라이더와 키보드 입력에 따라 업데이트됨.
    • 기본값: [0, 0]
  • penIsDown (boolean)

    • 펜의 상태를 나타내는 변수. 펜이 내려가면 true, 올라가면 false.
    • 기본값: false
  • KEY_STEP (number)

    • 키보드 입력에 의한 각도 변화량을 설정하는 변수.
    • 기본값: 1.5
  • lastSvgName (string)

    • 최근 드래그 앤 드롭으로 불러온 파일 이름(SVG 또는 TXT plot).
    • 대시보드 상단 UI에 표시됨. 예: "SVG: 파일명 | Loading..."
  • lastSvgSize (number)

    • 최근 불러온 파일의 크기(byte).
    • UI 상태 표시와 용량 확인 용도로 사용됨.
  • lastSvgStatus (string)

    • 최근 파일의 로드 상태 또는 처리 결과를 나타냄.
    • 예: "Loading...", "SVG Loaded ✅", "TXT empty/invalid ❌".
  • $('pen').d (number)

    • 펜 장치의 상태를 나타냄.
    • 0 = 펜 Up, 1 = 펜 Down.
    • 대시보드의 Pen Up/Down 버튼과 연동됨.
  • $("encoder.joint_1").d, $("encoder.joint_2").d (number)

    • 관절 1, 2의 엔코더 값.
    • .d에 값을 할당하면 목표 각도를 설정 가능.
    • degToStep(angle) 함수를 통해 각도를 스텝 단위로 변환 후 적용.
  • plotto (object)

    • SVG나 경로 데이터를 저장하고 처리하는 전역 객체.
    • 주요 기능:
      • plotto.buildFromSvgText(svgText) → SVG 텍스트 파싱 후 plotto.motionJson 생성
      • plotto.plot → 인코딩된 경로 데이터(byte 배열) 저장
  • startJsonPlayback() (function)

    • plotto.motionJson에 저장된 드로잉 경로 명령을 읽어 로봇팔이 움직이도록 재생 시작.
  • trailLayer (object)

    • 그림 시각화 레이어(canvas).
    • trailLayer.clear() → 화면에 남은 궤적 초기화(Erase 기능).
  • drawMode (number)

    • 현재 드로잉 모드를 나타냄.
    • 0 = 수동(Manual), 1 = 일반 자동 드로잉, 2 = 고속 드로잉(Fast), 3 = 전체 즉시 드로잉(All)
  • currentAngleJoint1, currentAngleJoint2 (number)

    • SVG 경로 재생 중 현재 관절 각도 상태.
    • 자동 드로잉 중 일시정지/갱신 시 참조.
  • bakeAllToTrailLayer() (function)

    • drawMode=3("SVG Draw All")에서 사용.
    • 전체 경로를 애니메이션 없이 trailLayer에 한 번에 그려 최종 그림 시각화.

위 전역 변수들과 객체들은 서로 연계되어 UI와 로봇팔 동작 상태를 추적하고 제어합니다. 다음으로 주요 함수들을 살펴보겠습니다.


2. UI 요소 생성

2.1. 슬라이더 및 버튼

대시보드에서는 슬라이더를 통해 두 개의 관절(J1, J2)의 각도를 실시간으로 조절할 수 있습니다. 이 값은 angles 배열에 저장되어, 로봇의 실제 동작을 제어합니다.

슬라이더

createSlider(parent, cfg, id, min, max, initial);

주어진 부모 SVG 요소 내에 슬라이더를 생성하는 함수입니다.

-180 30

파라미터 설명
parent 부모 SVG 요소
cfg [width, x, y], 슬라이더의 폭과 위치
id 슬라이더 요소의 ID
min 최소값
max 최대값
initial 초기값

버튼

createButton(parent, cfg, id, label, onClick);

SVG 내에 HTML 버튼을 생성하는 함수입니다.

SVG Draw

파라미터 설명
parent 부모 SVG 요소
cfg [width, x, y], 버튼의 폭과 위치
id 버튼 요소의 ID
label 버튼 위에 표시할 텍스트
onClick 클릭 이벤트 핸들러 함수(옵션)

두 유틸리티 함수를 통해 대시보드 UI에 간편하게 생성하고, 위치를 일괄적으로 관리할 수 있습니다.

2.2. dashboard() 함수

dashboard() 함수는 컨트롤 패널(UI)을 초기화하고 구성하는 역할을 합니다. 호출 시에 미리 준비된 w2popup 팝업 창 내부에 대시보드 내용을 채우게 됩니다. 주요 동작은 다음과 같습니다.

팝업 크기 설정 및 이벤트

w2popup.resize(470, 610);
window.onresize = () => {
  w2popup.resize(470, 610);
};

팝업 크기를 지정합니다. 현재는 창 크기 변경 시에도 동일하게 유지합니다.

SVG 컨테이너 초기화

const popup_box = select("#dashboard");
popup_box.html(""); // 기존 내용 초기화
popup_box.style("user_select", "none");

대시보드용 <div> 영역을 선택하고 내용을 비웁니다.

SVG/파일 드래그앤드롭 안내 영역

사용자가 SVG 파일 등을 드롭하여 로딩할 수 있도록 상단에 안내 박스를 표시합니다. 현재는 파란색 점선 경계(stroke-dasharray: 6 4)로 드롭 영역을 강조하고 있습니다.

관절 제어 슬라이더 추가

슬라이더 관절 종류 범위 초기값 조작
J1 어깨 -30° ~ 180°
-180 30
J2 팔꿈치 -100° ~ 15°
-100 15

슬라이더 값 변경 시에는 두 관절 모두 동일하게 <div>에 실시간 표시되고, targetAngles 배열의 해당 관절 값이 갱신됩니다.

대시보드 버튼

대시보드의 버튼들은 모두 이전에 정의한 createButton() 함수를 통해 생성할 수 있습니다.

버튼 ID 버튼 라벨 기능 요약
pen_toggle_btn Pen Down / Up 펜 상태 토글
클릭 시 penIsDown 값을 반전시키고, 펜 장치($('pen').d)와 버튼 라벨을 갱신
erase_btn Erase 현재 그려진 경로를 초기화
trailLayer.clear() 호출로 화면에 남은 궤적 제거
svg_draw_btn SVG Draw 불러온 SVG 경로를 따라 자동 드로잉.
drawMode = 1 설정 후 startJsonPlayback() 호출.
draw_manual_btn Draw Manual 수동 드로잉 모드 전환
drawMode = 0으로 설정하고, 펜을 올린 상태로 초기화. 슬라이더/키보드로 직접 관절 제어 가능
svg_draw_fast_btn SVG Draw Fast 불러온 SVG 경로를 고속으로 재생
drawMode = 2, 펜 올림, startJsonPlayback() 호출
svg_draw_all_btn SVG Draw All 전체 경로를 한 번에 시각화
drawMode = 3, 펜 올림, startJsonPlayback()bakeAllToTrailLayer() 호출
download_txt_btn Download TXT 현재 경로 데이터를 TXT 파일로 다운로드
downloadPlotTxtDecSpace("motion_plot.txt") 호출

각 버튼은 클릭 시 내부 상태를 갱신하고, 필요 시 UI나 로봇팔 동작과 연동됩니다.

3. 키보드 이벤트 처리: 화살표 키로 관절 제어

키 입력 처리

window.addEventListener("keydown", (e) => { ... })

화살표 키 입력을 통해 관절 각도를 실시간으로 조절하는 이벤트 리스너입니다.

  • J1 관절 (좌/우 회전)

    • ArrowLefttargetAngles[0] -= KEY_STEP
    • ArrowRighttargetAngles[0] += KEY_STEP
    • 범위 제한: -30° ~ 180°
  • J2 관절 (상/하 회전)

    • ArrowUptargetAngles[1] += KEY_STEP
    • ArrowDowntargetAngles[1] -= KEY_STEP
    • 범위 제한: -100° ~ 15°

처리 흐름

순서 절차
1. 감지 키 입력 감지 후 변경 여부(changed) 확인
2. 변경 방향키에 따라 targetAngles 값 증가/감소
3. 제한 각도 값 제한 적용 (clamping)
4. 갱신 슬라이더(#angle_J1, #angle_J2)와 값 표시(#angle_J?_val) 실시간 업데이트
5. 방지 e.preventDefault() 호출로 스크롤 등 기본 동작 방지

화살표 키 입력으로도 슬라이더와 동일하게 targetAngles가 업데이트되며, 이후 로봇팔이 제어 루프에서 목표 각도로 움직입니다.

4. 실시간 관절 제어 루프: control() 함수

5. 파일 드래그 앤 드롭 처리: setupSvgDragDrop(popup_box_selection) 함수

6. 플롯 데이터 저장: downloadPlotTxtDecSpace(filename)

7. SVG 경로 재구성 함수: window.rebuildFromSvgText(svgText)

8. 코드의 전반적인 작동 흐름

마지막으로, 위의 구성 요소들이 함께 어떻게 동작하는지 전체 흐름을 설명합니다:

  1. 초기화 및 UI 표시

    애플리케이션이 시작되면 dashboard() 함수가 호출되어 제어 패널 UI가 화면에 나타납니다.
    (예: 사용자가 메뉴에서 "Control Panel"을 열거나, 페이지가 로드되면서 자동으로 팝업이 뜨는 시나리오)

    • 대시보드에는 J1/J2 슬라이더, Pen 버튼, Erase 버튼, 여러 드로잉 모드 버튼, 파일 드롭 영역 등이 구성됨
    • 초기 상태:
      • 로봇팔의 현재 각도가 슬라이더에 반영
      • 펜은 기본 상태
      • 경로는 로드되지 않은 상태
  2. 사용자 조작 대기

    이제 사용자 입력을 기다리는 상태가 됩니다. 사용자는 다음과 같은 행동을 할 수 있습니다:

  3. 슬라이더 조작

    • J1 또는 J2 슬라이더를 드래그 → targetAngles 변경
    • control() 루프를 통해 로봇 관절이 해당 각도로 이동
    • 슬라이더 옆의 수치도 실시간 갱신
  4. 키보드 입력

    • 화살표 키 누르기: 좌/우 → J1, 상/하 → J2
    • 즉시 targetAngles 변경, 슬라이더 UI도 갱신
    • control()을 통해 부드럽게 움직임
  5. Pen 토글 버튼 클릭

    • 펜 올리기/내리기
    • 내부적으로 $('pen').d 값 0/1로 반영
    • 이후 로봇팔 움직임에서 펜 상태 반영
    • UI 버튼 텍스트도 변경
  6. Erase 버튼 클릭

    • 현재까지 그려진 경로 모두 삭제
    • 화면에서 선 사라짐, trailLayer 초기화
  7. 파일 드래그 & 드롭

    • SVG 파일 또는 이전 저장된 TXT 파일 처리 (setupSvgDragDrop)

    SVG 파일:

    • plotto.buildFromSvgTextplotto.motionJson 생성
    • 필요 시 startJsonPlayback 호출 → 경로 데이터 준비 완료
    • UI 상태 텍스트: "SVG Loaded ✅"

    TXT 파일:

    • plotDecode로 바이트 해석 → plotto.plotplotto.motionJson 채움
    • startJsonPlayback 호출
    • UI 상태 텍스트: "TXT Plot Loaded ✅ (... cmds)"
  8. 드로잉 모드 버튼 클릭

    • SVG나 TXT 로드 후 다양한 모드 선택 가능
    버튼 drawMode 동작
    SVG Draw 1 모션 재생 시작, 로봇팔 일정 속도로 펜 내려 그림, 엔코더 초기화 진행
    SVG Draw Fast 2 모션 재생, 매우 빠른 속도로 펜 이동/그림
    SVG Draw All 3 모션 재생 없이 결과 한꺼번에 표시, 로봇팔 내부 상태 동기화
    Draw Manual 0 사용자 수동 제어 모드, 펜 기본적으로 들어올린 상태 시작
  9. 메인 루프 동작

    • 화면이 열려 있는 동안 control() 함수 지속 실행
    • 항상 현재 UI 입력 상태(targetAngles, 슬라이더 값) 읽어서 로봇팔 명령 반영
    • 실제 각도(angles)를 목표각에 가깝게 변화
  10. 드로잉 자동 재생 시

    • startJsonPlayback 활성화, drawMode = 1/2/3
    • 자동 재생 로직이 targetAngles$("encoder.joint_*").d를 시간에 따라 갱신
    • control()은 해당 값을 하드웨어에 반영
  11. 수동 모드

    • control()이 슬라이더/키보드 입력을 받아 움직임 처리
    • 사용자가 조작하는 대로 관절 이동
  12. 상태 업데이트 및 종료

    • 그림 완료 후 또는 앱 종료 시 팝업(w2popup) 닫기 가능
    • 필요 시 키 이벤트 해제 또는 기타 마무리 작업 확장 가능
    • "Download TXT" 버튼으로 motion 경로를 파일로 저장 가능 → 나중에 드롭하면 동일 그림 재현

결론

개발자는 이 구조를 바탕으로 필요한 부분을 수정하거나 기능을 추가할 수 있습니다.

예를 들어, plotDecode나 plotEncode 함수의 개선, useSimpleFK 기능 구현, 속도 조절 슬라이더(angle_speed) 추가 등 확장 여지가 있습니다.

이 문서를 통해 각 부분의 동작 원리를 파악하여, 향후 개발과 디버깅에 활용하시기 바랍니다.

감사합니다.

Clone this wiki locally