Newer
Older
casic_unitree_dog / src / methane_serial_port.cpp
//
// Created by pengx on 2025/3/18.
//

#include "methane_serial_port.hpp"
#include <iomanip>
#include <iostream>

#include "tcp_service.hpp"

void handle_response(const std::vector<uint8_t> &buffer) {
    const auto x = buffer[2];
    const auto y = buffer[3];
    const auto z = buffer[4];
    const auto w = buffer[5];
    const auto result = x * (1 << 24) + y * (1 << 16) + z * (1 << 8) + w;
    TcpService::getInstance().update_gas_value(result);
}

MethaneSerialPort::MethaneSerialPort(
    boost::asio::io_service &io_service, const std::string &port_name, const int baud_rate
): io_service_(io_service), port_(io_service, port_name), timer_(io_service) {
    port_.set_option(serial_port_base::baud_rate(baud_rate));
    port_.set_option(serial_port_base::character_size(8));
    port_.set_option(serial_port_base::parity(serial_port_base::parity::none));
    port_.set_option(serial_port_base::stop_bits(serial_port_base::stop_bits::one));

    std::cout << "MethaneSerialPort init success" << std::endl;

    start_timer();
}

void MethaneSerialPort::start_timer() {
    timer_.expires_from_now(boost::posix_time::seconds(3));
    timer_.async_wait([this](const boost::system::error_code &error) {
        if (!error) {
            read_from_port();
        }
    });
}

//CC 05 00 00 00 00 0D 77
void MethaneSerialPort::read_from_port() {
    // 检查缓冲区中是否有足够的数据
    if (buffer_.size() >= 8) {
        std::istream is(&buffer_);
        std::vector<uint8_t> response(8);
        is.read(reinterpret_cast<char *>(response.data()), 8);

        // 检查数据包的头和尾
        if (response[0] == 0xCC && response[7] == 0x77) {
            // 数据包完整且正确
            std::cout << "received 8 bytes: ";
            for (size_t i = 0; i < 8; ++i) {
                std::cout << std::hex
                        << std::uppercase
                        << std::setw(2)
                        << std::setfill('0')
                        << static_cast<int>(response[i])
                        << " ";
            }
            std::cout << std::endl;

            handle_response(response);

            // 清空 buffer_,确保不缓存数据
            buffer_.consume(8);
        } else {
            // 数据包不完整或不正确,丢弃该数据包
            buffer_.consume(1); // 丢弃第一个字节并重新开始
        }

        // 重新启动定时器
        start_timer();
        return;
    }

    async_read(
        port_, buffer_, boost::asio::transfer_at_least(1),
        [this](const boost::system::error_code &error, const size_t) mutable {
            if (!error) {
                read_from_port(); // 递归调用以继续检查数据
            } else {
                // 清空 buffer_,即使发生错误
                buffer_.consume(buffer_.size());
                start_timer();
            }
        });
}