C++ API Reference#

What you’ll do

  • C++ SDK의 public 인터페이스(헤더/클래스/동작/반환값)를 빠르게 찾아볼 수 있습니다.

Prerequisites

Next


1. Overview#

  • Scope: inc에 정의된 공개 C++ API

Public headers

  • inc/KMC_protocol.hpp

  • inc/KMC_serial_port.hpp

  • inc/KMC_uart_client.hpp

  • inc/KMC_driver.hpp

Namespaces

  • KMC_HARDWARE

  • KMC_HARDWARE::protocol

Units

  • velocity: \(\mathrm{m/s}\)

  • angular rate: \(\mathrm{rad/s}\)

  • curvature: \(\mathrm{m}^{-1}\)

  • rate: \(\mathrm{Hz}\)

  • voltage: \(\mathrm{V}\)

  • current: \(\mathrm{A}\)

  • temperature: \(^\circ\mathrm{C}\)

  • angle: \(^\circ\)

  • speed: \(\mathrm{rpm}\)

  • time: \(\mathrm{ms}\), \(\mu\mathrm{s}\)

  • baud rate: \(\mathrm{bps}\)


2. Driver (Main Interface)#

2.1 Driver::Options#

Field

Type

Default

Unit

Description

port

std::string

""

-

Device path (e.g., /dev/ttyKMC)

serial

SerialPortOptions

defaults

-

Serial options (see SerialPortOptions)

control_rate_hz

double

100.0

\(\mathrm{Hz}\)

0xA5 control stream rate

vehicle_speed_rate_hz

double

50.0

\(\mathrm{Hz}\)

0xB3 speed request rate

poll_battery

bool

false

-

Enable battery polling

battery_rate_hz

double

1.0

\(\mathrm{Hz}\)

Battery polling rate

poll_allstate

bool

false

-

Enable all-state polling

allstate_rate_hz

double

10.0

\(\mathrm{Hz}\)

All-state polling rate

allstate_motor_left

uint8_t

0

-

Left motor ID

allstate_motor_right

uint8_t

1

-

Right motor ID

command_timeout_ms

int

300

\(\mathrm{ms}\)

If no setCommand() update within this time, send (0,0)

stop_burst_count

int

3

-

Repeat count of (0,0) on stop()

realtime_priority

int

-1

-

Linux SCHED_FIFO priority (1-99), -1 disables

cpu_affinity

int

-1

-

Linux CPU affinity index, -1 disables

max_queue

size_t

1024

-

Max receive queue size (drop oldest on overflow)

2.2 Driver API#

  • bool start(const Options& opt)

    • Open port, flush input, start I/O thread.

  • void stop()

    • Stop I/O thread, send safety stop, close port.

  • bool isRunning() const

    • I/O thread running state.

  • void setCommand(float velocity_mps, float omega_rps)

    • Input: \(v\) (\(\mathrm{m/s}\)), \(\omega\) (\(\mathrm{rad/s}\)).

    • Internal: \(\kappa = \omega / v\) (if \(|v| \le 10^{-3}\), then \(\kappa = 0\)).

    • 0xA5 uses \((v,\kappa)\).

  • void setCommandCurvature(float velocity_mps, float curvature_1pm)

    • Input: \(v\) (\(\mathrm{m/s}\)), \(\kappa\) (\(\mathrm{m}^{-1}\)).

  • std::optional<Message> tryPopMessage()

    • Non-blocking queue pop.

  • bool waitPopMessage(Message& out, int timeout_ms)

    • Blocking pop with timeout (\(\mathrm{ms}\)).

  • bool requestBatteryOnce(uint8_t motor_id = 0)

    • Send one 0xAF battery request.

  • bool requestAllStateOnce(uint8_t motor_id)

    • Send one 0xAF all-state request.

명령 입력 매핑

  • UART 명령 입력(프레임 ID: 0xA5) payload는 \((v,\kappa)\)로 고정입니다.

  • setCommand(v, omega)는 내부에서 \(\kappa=\omega/v\)로 변환해 전송합니다(\(|v| \le 10^{-3}\)이면 \(\kappa=0\)).

2.3 Driver I/O Loop Behavior (Implementation Detail)#

  • 0xA5 at control_rate_hz.

  • 0xB3 at vehicle_speed_rate_hz.

  • 0xAF auxiliary/diagnostic requests when poll_battery / poll_allstate enabled.

  • Parsed frames are pushed to the queue.

  • If command_timeout_ms expires, (0,0) is sent instead of the last command.


3. Data Structures (Messages)#

Message type:

std::variant<VehicleSpeed, BatteryVoltage, AllState, AfResponse>

VehicleSpeed#

Field

Type

Unit

Description

mps

float

\(\mathrm{m/s}\)

Vehicle speed

BatteryVoltage#

Field

Type

Unit

Description

volt

float

\(\mathrm{V}\)

Battery voltage

AllState#

Field

Type

Unit

Description

id

uint32_t

-

Motor ID

position_deg

float

\(^\circ\)

Motor position

speed_rpm

float

\(\mathrm{rpm}\)

Mechanical speed

current_A

float

\(\mathrm{A}\)

Current

temperature_C

float

\(^\circ\mathrm{C}\)

Temperature

error_code

uint32_t

-

Error bitmask

reserved_0

float

-

Reserved

reserved_1

float

-

Reserved

reserved_2

float

-

Reserved

AfResponse (Raw 0xAF)#

Field

Type

Unit

Description

motor_id

uint8_t

-

Response motor ID

rw

uint8_t

-

RW_READ / RW_WRITE

ids

std::vector<uint8_t>

-

ID list

data_f32

std::vector<float>

-

float32 LE decode

data_u32

std::vector<uint32_t>

-

Same bytes as u32 LE


4. UartClient (Low-Level)#

Thread safety: internal mutex.

Open/Close#

  • bool open(const std::string& port_name, int baudrate = 115200)

  • bool open(const std::string& port_name, const SerialPortOptions& opts)

  • void close()

  • bool isOpen() const

  • void flushInput()

Main Interface (명령 입력/속도 요청)#

  • bool sendPcControl(float velocity_mps, float curvature_1pm)

    • Input: \(v\) (\(\mathrm{m/s}\)), \(\kappa\) (\(\mathrm{m}^{-1}\)).

    • 명령 입력 프레임을 전송합니다. (프로토콜: 0xA5, 응답 없음)

  • bool requestVehicleSpeed()

    • 속도 요청을 전송합니다(프로토콜: 0xB3, 1 byte). 응답은 비동기입니다.

Auxiliary/Diagnostic (보조 명령)#

  • bool requestAllState(uint8_t motor_id)

  • bool requestBatteryVoltage(uint8_t motor_id = 0)

  • bool writeSpeedERPM(uint8_t motor_id, float erpm)

    • Input: electrical RPM.

  • bool writeServoPulseUs(uint8_t motor_id, float pulse_us)

    • Input: pulse width (\(\mu\mathrm{s}\)).

  • bool systemReset(uint8_t motor_id)

Polling#

  • std::optional<Message> poll(int timeout_ms)

    • timeout_ms = 0 is non-blocking.

    • Parse internal RX buffer; read from OS buffer if needed.

Parsing Rules#

  • Sync on 0xAF or 0xB3 header.

  • 0xB3: fixed 5 bytes, return VehicleSpeed.

  • 0xAF: parse to AfResponse, then map to BatteryVoltage or AllState on known patterns.


5. SerialPort (Internal)#

5.1 SerialPortOptions#

Field

Type

Default

Unit

Description

baudrate

int

115200

\(\mathrm{bps}\)

UART baud rate

hw_flow_control

bool

true

-

RTS/CTS enabled

rts_always_on

bool

true

-

Keep RTS asserted

5.2 SerialPort API#

  • bool open(const std::string& port_name, const SerialPortOptions& opts)

  • bool open(const std::string& port_name, int baudrate)

  • void close()

  • bool isOpen() const

  • void flushInput()

  • int writeAll(const uint8_t* data, size_t len)

    • Returns bytes written; -1 on error.

  • int readSome(uint8_t* data, size_t max_len, int timeout_ms)

    • Returns bytes read; 0 on timeout; -1 on error.

Thread safety: no internal synchronization; guarded by UartClient mutex.


6. Protocol (Frames and Constants)#

Frame IDs (Header Bytes)#

ID

Meaning

0xA5

PC control command frame (velocity + curvature)

0xB3

Vehicle speed request/response frame

0xAF

Auxiliary/diagnostic/utility read/write frame

Constants#

Packet headers (1 byte):

Name

Value

Description

HEADER_GENERAL

0xAF

Auxiliary/diagnostic/utility read/write

HEADER_PC_CONTROL

0xA5

Control command

HEADER_VEHICLE_SPEED

0xB3

Speed request/response

Read/Write flags:

Name

Value

Description

RW_READ

0x00

Read request

RW_WRITE

0x01

Write request and read response

Supported 0xAF IDs:

Name

Value

Description

ID_SYSTEM_RESET

0x00

Device reset

ID_SPEED

0x03

Speed command (ERPM)

ID_SERVO_PULSE

0x05

Servo pulse width (\(\mu\mathrm{s}\))

ID_ALL_STATE

0x06

All-state

ID_BATTERY_VOLTAGE

0x07

Battery voltage

Size limits:

Name

Value

Description

MAX_IDS

16

Max IDs per 0xAF frame

ALL_STATE_FIELD_COUNT

9

All-state field count

Frame Formats (little-endian)#

All float values are float32 little-endian.

0xA5 control frame:

[0]  HEADER_PC_CONTROL (0xA5)
[1]  velocity_mps (float32 LE, m/s)
[5]  curvature_1pm (float32 LE, m^-1)

0xB3 request/response:

  • Request: single byte HEADER_VEHICLE_SPEED.

  • Response: 5 bytes header + float32 speed.

[0]  HEADER_VEHICLE_SPEED (0xB3)
[1]  speed_mps (float32 LE, m/s)

0xAF (auxiliary/diagnostic read/write):

[0]  HEADER_GENERAL (0xAF)
[1]  motor_id
[2]  RW_READ or RW_WRITE
[3]  n_id
[4..] ids[0..n_id-1]
[4+n_id..] data_f32[0..n_id-1] (only when RW_WRITE)

Notes:

  • Read requests: RW_READ, no data.

  • Read responses: RW_WRITE, include data.

Helpers#

  • appendU8(out, v)

  • appendU32LE(out, v)

  • readU32LE(p)

  • appendFloatLE(out, value)

  • readFloatLE(p)


7. Notes#

  • All floats are float32 little-endian.

  • Writes are best-effort; no ACKs.


8. Minimal Usage#

Driver (v, omega):

KMC_HARDWARE::Driver drv;
KMC_HARDWARE::Driver::Options opt;
opt.port = "/dev/ttyKMC";
opt.control_rate_hz = 100.0;
drv.start(opt);
drv.setCommand(0.5f, 0.2f); // v=0.5 m/s, omega=0.2 rad/s

Driver (v, curvature):

drv.setCommandCurvature(0.5f, 0.4f); // k = 0.4 m^-1

UartClient:

KMC_HARDWARE::UartClient client;
client.open("/dev/ttyKMC", 115200);
client.sendPcControl(0.5f, 0.4f); // v, curvature
client.requestVehicleSpeed();
if (auto msg = client.poll(50)) {
  if (auto* vs = std::get_if<KMC_HARDWARE::VehicleSpeed>(&*msg)) {
    // use vs->mps
  }
}