C++ API Reference#
What you’ll do
C++ SDK의 public 인터페이스(헤더/클래스/동작/반환값)를 빠르게 찾아볼 수 있습니다.
Prerequisites
UART 프로토콜 규격을 알고 있으면 이해가 쉽습니다: UART Protocol Reference
Next
제어 의미/부호/단위: Vehicle Control Model
1. Overview#
Scope:
inc에 정의된 공개 C++ API
Public headers
inc/KMC_protocol.hppinc/KMC_serial_port.hppinc/KMC_uart_client.hppinc/KMC_driver.hpp
Namespaces
KMC_HARDWAREKMC_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 |
|---|---|---|---|---|
|
|
|
- |
Device path (e.g., |
|
|
defaults |
- |
Serial options (see SerialPortOptions) |
|
|
|
\(\mathrm{Hz}\) |
0xA5 control stream rate |
|
|
|
\(\mathrm{Hz}\) |
0xB3 speed request rate |
|
|
|
- |
Enable battery polling |
|
|
|
\(\mathrm{Hz}\) |
Battery polling rate |
|
|
|
- |
Enable all-state polling |
|
|
|
\(\mathrm{Hz}\) |
All-state polling rate |
|
|
|
- |
Left motor ID |
|
|
|
- |
Right motor ID |
|
|
|
\(\mathrm{ms}\) |
If no |
|
|
|
- |
Repeat count of (0,0) on |
|
|
|
- |
Linux SCHED_FIFO priority (1-99), -1 disables |
|
|
|
- |
Linux CPU affinity index, -1 disables |
|
|
|
- |
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() constI/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_allstateenabled.Parsed frames are pushed to the queue.
If
command_timeout_msexpires, (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 |
|---|---|---|---|
|
|
\(\mathrm{m/s}\) |
Vehicle speed |
BatteryVoltage#
Field |
Type |
Unit |
Description |
|---|---|---|---|
|
|
\(\mathrm{V}\) |
Battery voltage |
AllState#
Field |
Type |
Unit |
Description |
|---|---|---|---|
|
|
- |
Motor ID |
|
|
\(^\circ\) |
Motor position |
|
|
\(\mathrm{rpm}\) |
Mechanical speed |
|
|
\(\mathrm{A}\) |
Current |
|
|
\(^\circ\mathrm{C}\) |
Temperature |
|
|
- |
Error bitmask |
|
|
- |
Reserved |
|
|
- |
Reserved |
|
|
- |
Reserved |
AfResponse (Raw 0xAF)#
Field |
Type |
Unit |
Description |
|---|---|---|---|
|
|
- |
Response motor ID |
|
|
- |
RW_READ / RW_WRITE |
|
|
- |
ID list |
|
|
- |
float32 LE decode |
|
|
- |
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() constvoid 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 = 0is non-blocking.Parse internal RX buffer; read from OS buffer if needed.
Parsing Rules#
Sync on
0xAFor0xB3header.0xB3: fixed 5 bytes, returnVehicleSpeed.0xAF: parse toAfResponse, then map toBatteryVoltageorAllStateon known patterns.
5. SerialPort (Internal)#
5.1 SerialPortOptions#
Field |
Type |
Default |
Unit |
Description |
|---|---|---|---|---|
|
|
|
\(\mathrm{bps}\) |
UART baud rate |
|
|
|
- |
RTS/CTS enabled |
|
|
|
- |
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() constvoid 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 |
|---|---|
|
PC control command frame (velocity + curvature) |
|
Vehicle speed request/response frame |
|
Auxiliary/diagnostic/utility read/write frame |
Constants#
Packet headers (1 byte):
Name |
Value |
Description |
|---|---|---|
|
|
Auxiliary/diagnostic/utility read/write |
|
|
Control command |
|
|
Speed request/response |
Read/Write flags:
Name |
Value |
Description |
|---|---|---|
|
|
Read request |
|
|
Write request and read response |
Supported 0xAF IDs:
Name |
Value |
Description |
|---|---|---|
|
|
Device reset |
|
|
Speed command (ERPM) |
|
|
Servo pulse width (\(\mu\mathrm{s}\)) |
|
|
All-state |
|
|
Battery voltage |
Size limits:
Name |
Value |
Description |
|---|---|---|
|
|
Max IDs per 0xAF frame |
|
|
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
}
}