UartClient Read Speed#

What you’ll do

  • 속도 요청을 보내고, poll()로 응답을 받아 출력합니다.

Prerequisites

Next


이 튜토리얼에서는 low-level class UartClient를 사용하여 차량의 현재 속도를 속도 요청으로 읽고 출력하는 방법을 다룹니다. 요청 전송 → poll() 수신 → 출력 순서를 단계별로 구현합니다.

참고

  • Driver: I/O 스레드/수신 큐/타임아웃 포함 (주행/모니터링 기본 경로)

  • UartClient: 요청 전송/수신 대기/파싱/주기를 직접 구현할 때


1. 목표#

  1. 속도 요청을 전송

  2. poll()VehicleSpeed를 받아 출력

  3. 지정한 주기로 반복


2. 단계별 구현 가이드#

단계 0) include 및 main 뼈대#

#include "KMC_uart_client.hpp"

#include <chrono>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <thread>
#include <variant>

int main(int argc, char **argv) {
  const std::string port = (argc > 1) ? argv[1] : "/dev/ttyKMC";
  int seconds = (argc > 2) ? std::atoi(argv[2]) : 5;
  if (seconds <= 0) seconds = 5;
  double rate_hz = (argc > 3) ? std::atof(argv[3]) : 20.0;
  if (rate_hz <= 0.0) rate_hz = 20.0;

단계 1) 포트 열기 + flush#

UartClient는 low-level 클래스이므로 포트를 직접 열고 초기화해야 합니다.

  KMC_HARDWARE::UartClient client;
  if (!client.open(port, 115200)) {
    std::fprintf(stderr, "Failed to open port: %s\n", port.c_str());
    return 1;
  }
  client.flushInput();

단계 2) 주기적인 요청 및 수신 루프#

이 예제에서는 정해진 주기(period)마다 요청을 보냅니다.

  while (std::chrono::steady_clock::now() - t0 < std::chrono::seconds(seconds)) {
    const auto cycle_start = std::chrono::steady_clock::now();

    // 1. B3 요청 보내기 (1바이트 송신)
    client.requestVehicleSpeed();

    // 2. 응답 대기 및 파싱
    // 최대 50ms 동안 대기하며 응답을 확인합니다.
    auto msg = client.poll(50);

    if (msg) {
      // std::variant 타입인 msg에서 VehicleSpeed 타입을 확인합니다.
      if (auto* vs = std::get_if<KMC_HARDWARE::VehicleSpeed>(&*msg)) {
        std::printf("VehicleSpeed: %.3f m/s\n", vs->mps);
      }
    } else {
      std::printf("VehicleSpeed: (no response)\n");
    }

    // 3. 주기 유지 (Sleep)
    const auto elapsed = std::chrono::steady_clock::now() - cycle_start;
    if (elapsed < period) {
      std::this_thread::sleep_for(period - elapsed);
    }
  }

3. Result#

아래 코드는 SDK 리포지토리의 examples/UartClient_Advanced/read_speed.cpp와 동일한 내용입니다.

#include "KMC_uart_client.hpp"

#include <chrono>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <thread>
#include <variant>

int main(int argc, char **argv) {
  const std::string port = (argc > 1) ? argv[1] : "/dev/ttyKMC";
  int seconds = (argc > 2) ? std::atoi(argv[2]) : 5;
  if (seconds <= 0) seconds = 5;
  double rate_hz = (argc > 3) ? std::atof(argv[3]) : 20.0;
  if (rate_hz <= 0.0) rate_hz = 20.0;

  KMC_HARDWARE::UartClient client;
  if (!client.open(port, 115200)) {
    std::fprintf(stderr, "Failed to open port: %s\n", port.c_str());
    return 1;
  }
  client.flushInput();

  const auto period = std::chrono::duration<double>(1.0 / rate_hz);
  const auto t0 = std::chrono::steady_clock::now();

  while (std::chrono::steady_clock::now() - t0 <
         std::chrono::seconds(seconds)) {
    const auto cycle_start = std::chrono::steady_clock::now();
    client.requestVehicleSpeed();

    auto msg = client.poll(50);
    if (msg) {
      if (auto* vs = std::get_if<KMC_HARDWARE::VehicleSpeed>(&*msg)) {
        std::printf("VehicleSpeed: %.3f m/s\n", vs->mps);
      }
    } else {
      std::printf("VehicleSpeed: (no response)\n");
    }

    const auto elapsed = std::chrono::steady_clock::now() - cycle_start;
    if (elapsed < period) {
      std::this_thread::sleep_for(period - elapsed);
    }
  }

  return 0;
}