Haskell로 4바 연동기 시뮬레이터 만들기

발행: (2026년 6월 10일 AM 06:01 GMT+9)
11 분 소요
원문: Dev.to

출처: Dev.to

대부분의 개발자는 Haskell을 함수형 프로그래밍, 타입 안전성, 컴파일러, 파서, 그리고 아름다운 수학적 추상화의 언어로 알고 있습니다.
하지만 Haskell을 이용해 인터랙티브한 공학 시뮬레이터를 만들 수 있을까요?
그것이 바로 제가 진행한 프로젝트의 동기였습니다:

Four‑Bar Mechanism Haskell Simulator
레포지토리: https://github.com/mohammadijoo/Four-Bar-Mechanism-Haskell

이 프로젝트는 Haskell로 작성된 브라우저 기반 데스크톱 스타일 GUI 애플리케이션입니다. 평면 사바링크(四棒) 메커니즘을 시각화·분류·애니메이션으로 보여주며, 사바링크는 기계공학·운동학·기계 설계에서 가장 고전적인 메커니즘 중 하나입니다.
GUI는 Threepenny‑GUI 로 구현돼 로컬 브라우저 창에서 동작하고, 수학 모델과 메커니즘 로직은 Haskell에 그대로 남아 있습니다.

저에게 흥미로운 부분은 단순히 움직이는 링크를 그리는 것이 아니라, 메커니즘 설계 이론, 계산 기하학, 함수형 프로그래밍을 하나의 작은 교육용 시뮬레이터에 결합한 것이었습니다.


사바링크(四棒)란?

사바링크는 네 개의 강체 링크가 네 개의 회전 조인트(리볼루트 조인트)로 연결된 폐쇄 루프 기계 시스템입니다.
이 프로젝트에서 네 개의 링크는 다음과 같습니다:

기호이름설명
g고정 링크피벗 A와 B 사이의 고정 거리
a입력 링크A에서 움직이는 피벗 C 로 회전하는 링크
b출력 링크고정 피벗 B에서 움직이는 피벗 D 로 연결되는 링크
f플로팅(연결) 링크움직이는 피벗 C와 D 를 연결하는 링크

고정 피벗은 다음 위치에 놓입니다:
A = (0, 0), B = (g, 0)

입력 링크는 각도 α 로 회전합니다. 따라서 점 C는 바로 다음과 같이 계산됩니다:
C = (g·cosα, g·sinα)

점 D는 좀 더 흥미롭습니다. 두 개의 거리 제약을 만족해야 합니다:

|D − C| = f
|D − B| = b

시뮬레이터는 원 교차법을 이용해 점 D의 위치를 구합니다.

  • 반지름 f 로 C를 중심으로 한 원
  • 반지름 b 로 B를 중심으로 한 원

두 원이 교차하는 지점이 메커니즘을 닫을 수 있는 위치이며, 이것이 시뮬레이터의 기본 기하학적 핵심입니다.

사바링크는 다양한 실제 기계 시스템에 등장합니다. 몇 가지 예시:

적용 분야사바링크의 역할
엔진회전·진동 운동 변환
서스펜션 시스템제한된 운동 가이드
로봇 그리퍼개폐 경로 제어
펌프회전 운동을 왕복 운동으로 변환
보행 메커니즘반복적인 다리 움직임 생성
와이퍼모터 회전을 휩쓸기 운동으로 변환
공작기계반복 가능한 제한 운동 제공

사바링크는 시각적으로 이해하기 쉬울 정도로 단순하지만, 실제 메커니즘 설계 개념을 가르치기에 충분히 풍부합니다. 그래서 기계공학·기계 설계 과목에서 자주 등장합니다.

평면 메커니즘은 Kutzbach‑Grübler 자유도 방정식으로 분석할 수 있습니다.

[ M = 3(n-1) - 2j_1 - j_2 ]

기호의미
M자유도(운동 가능성)
n링크 수
j_1회전 조인트 등 하위 쌍(lower pair) 수
j_2고차 쌍(higher pair) 수

이상적인 평면 사바링크에 대해선 n = 4, j_1 = 4, j_2 = 0 이므로

[ M = 3(4-1) - 2·4 - 0 = 9 - 8 = 1 ]

즉, 사바링크는 정확히 1 자유도를 가집니다. 입력 각도가 정해지면 루프 폐쇄 제약에 의해 나머지 구성은 자동으로 결정됩니다(단, 선택된 조립 분기(branch) 제외). 이것은 “하나의 입력 움직임이 전체 메커니즘을 구동한다”는 멋진 결과입니다.

시뮬레이터는 링크 길이와 입력 각도로부터 메커니즘 위치를 계산합니다.

  1. 먼저 BC 사이 거리 d = |B - C| 를 구합니다.
  2. 메커니즘이 닫히려면 두 원이 교차해야 하므로 조립 조건은

[ |f - b| \le d \le f + b ]

이 조건을 만족하지 않으면 실존하는 점 D 가 없으며, 해당 입력 각도에서는 메커니즘을 조립할 수 없습니다.
조건을 만족하면 보통 두 개의 D 후보가 나오며, 이는 메커니즘의 두 조립 분기를 의미합니다. GUI에서는 Flip branch 버튼이나 F 키로 두 분기 사이를 전환할 수 있습니다.

프로젝트에서 가장 마음에 드는 부분: 애니메이션이 미리 그려진 시각 효과가 아니라, 시뮬레이터가 실제로 링크 기하학을 풀어낸다는 점입니다.

그라쇼프(Grashof) 조건

사바링크 설계에서 가장 중요한 아이디어 중 하나는 그라쇼프 조건입니다. 네 링크 길이를 짧은 순서대로 정렬하면

[ s \le p \le q \le l ]

(s = 최단 링크, l = 최장 링크)

그라쇼프 지수는

[ G = s + l - p - q ]

조건의미
G ≤ 0그라쇼프 메커니즘 (적어도 하나의 링크가 완전 회전 가능)
G > 0비그라쇼프 메커니즘

그라쇼프 메커니즘이면 입력 링크가 연속 회전할 수 있는지, 아니면 앞뒤로 흔들리는지(rocking) 판단할 수 있어 설계 초기 단계에서 중요한 질문에 답을 줍니다.

시뮬레이터는 또한 메커니즘이 물리적으로 조립 가능한지 검사합니다. 유효성 지수는

[ V = l - s - p - q ]

유효한 사바링크는 V ≤ 0 을 만족해야 합니다. V > 0 이면 최장 링크가 나머지 세 링크의 합보다 길어 루프를 닫을 수 없습니다. 따라서 시뮬레이터는 운동 유형뿐 아니라 링크 길이가 유효한 메커니즘을 구성하는지도 알려줍니다.

시뮬레이터는 다음과 같은 세 가지 초과값을 계산합니다:

[ \begin{aligned} T_1 &= g + f - b - a \ T_2 &= b + g - f - a \ T_3 &= f + b - g - a \end{aligned} ]

이 값들의 부호를 통해 상세한 링크 상태를 분류하고, GUI 에서는 간단한 운동 유형을 다음과 같이 표시합니다:

분류의미
crank‑crank두 관련 링크 모두 완전 회전 가능
crank‑rocker입력은 완전 회전, 출력은 흔들림
rocker‑crank입력은 흔들림, 출력은 완전 회전
rocker‑rocker두 링크 모두 흔들림

이렇게 프로젝트는 단순한 움직이는 도식이 아니라 작은 메커니즘 분류 도구가 됩니다.

왜 Haskell인가?

기계 시뮬레이터를 구현할 때 대부분은 Python, MATLAB, C++, JavaScript, Julia 등을 선택합니다. 하지만 바로 그 점이 이 프로젝트를 흥미롭게 만들었습니다. Haskell 은 순수 수학 로직과 부수 효과가 있는 애플리케이션 코드를 명확히 분리하는 데 뛰어납니다.

프로젝트 구조는 다음과 같습니다:

  • 메커니즘 모델 – 순수 Haskell 모듈 src/FourBar.hs
    • Linkage, Pose, excesses, grashofIndex, validityIndex, classifyMotion,
0 조회
Back to Blog

관련 글

더 보기 »

Eidentic 소개

Today we're releasing Eidentic, an open-source TypeScript SDK for building AI agents with self-improving memory and the production fundamentals built in — not b...

Typescript의 타입

Introdução Tipos são uma forma de definir a “forma” ou o contrato dos dados que estamos usando no código. Pensando em Javascript puro, ele é dinâmico: você pode...