update frame : add new ts time
This commit is contained in:
parent
2c483f54c0
commit
4ed7d6d6b0
|
|
@ -1,5 +1,6 @@
|
|||
// app/ControlState.cpp
|
||||
#include "ControlState.hpp"
|
||||
#include <chrono>
|
||||
|
||||
// ============================================================
|
||||
// GLOBAL INSTANCE
|
||||
|
|
@ -58,5 +59,14 @@ ControlSnapshot ControlState::snapshot()
|
|||
s.brake = g_state.brake_.load(std::memory_order_acquire);
|
||||
s.direction = g_state.direction_.load(std::memory_order_acquire);
|
||||
|
||||
// Timestamp (ms) — used for latency / stale-frame detection
|
||||
s.ts_ms = static_cast<u32>(
|
||||
std::chrono::duration_cast<
|
||||
std::chrono::milliseconds
|
||||
>(
|
||||
std::chrono::steady_clock::now().time_since_epoch()
|
||||
).count()
|
||||
);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
using u8 = uint8_t;
|
||||
using u32 = uint32_t;
|
||||
using s16 = int16_t;
|
||||
using u16 = uint16_t;
|
||||
|
||||
|
||||
// ============================================================
|
||||
// DIRECTION
|
||||
|
|
@ -26,11 +28,12 @@ enum class Direction : u8
|
|||
// ============================================================
|
||||
struct ControlSnapshot
|
||||
{
|
||||
u32 seq;
|
||||
u16 seq;
|
||||
s16 steering;
|
||||
u8 throttle;
|
||||
u8 brake;
|
||||
Direction direction;
|
||||
u32 ts_ms;
|
||||
};
|
||||
|
||||
// ============================================================
|
||||
|
|
@ -65,7 +68,8 @@ private:
|
|||
std::atomic<u8> throttle_{0};
|
||||
std::atomic<u8> brake_{0};
|
||||
std::atomic<Direction> direction_{Direction::STOP};
|
||||
std::atomic<u32> seq_{0};
|
||||
std::atomic<u16> seq_{0};
|
||||
|
||||
};
|
||||
|
||||
// ============================================================
|
||||
|
|
|
|||
|
|
@ -94,20 +94,26 @@ bool parse_frame(
|
|||
std::vector<u8>
|
||||
FrameCodec::build_fullstate_frame(const ControlSnapshot& snap)
|
||||
{
|
||||
static u8 rolling_msg_id = 0;
|
||||
|
||||
FullStatePdu pdu{};
|
||||
pdu.steering = snap.steering;
|
||||
pdu.throttle = snap.throttle;
|
||||
pdu.brake = snap.brake;
|
||||
pdu.steering = static_cast<s16>(snap.steering);
|
||||
pdu.throttle = static_cast<u8>(snap.throttle);
|
||||
pdu.brake = static_cast<u8>(snap.brake);
|
||||
pdu.direction = static_cast<u8>(snap.direction);
|
||||
|
||||
pdu.seq = static_cast<u16>(snap.seq);
|
||||
pdu.ts_ms = snap.ts_ms;
|
||||
|
||||
return build_frame_from_pdu(
|
||||
&pdu,
|
||||
sizeof(pdu),
|
||||
static_cast<u8>(PduType::FULL_STATE),
|
||||
static_cast<u8>(snap.seq & 0xFF)
|
||||
rolling_msg_id++
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
bool FrameCodec::decode_frame(
|
||||
const u8* buf,
|
||||
size_t len,
|
||||
|
|
|
|||
|
|
@ -33,10 +33,13 @@ enum class PduType : u8
|
|||
* ================================ */
|
||||
struct FullStatePdu
|
||||
{
|
||||
s16 steering; // steering angle
|
||||
u8 throttle; // throttle %
|
||||
u8 brake; // brake %
|
||||
u8 direction; // enum Direction
|
||||
s16 steering; // -1000 .. +1000
|
||||
u8 throttle; // 0 .. 100
|
||||
u8 brake; // 0 .. 100
|
||||
u8 direction; // enum Direction
|
||||
|
||||
u16 seq; // FULL 16-bit sequence
|
||||
u32 ts_ms; // sender timestamp (ms)
|
||||
};
|
||||
|
||||
/* ================================
|
||||
|
|
|
|||
|
|
@ -133,29 +133,40 @@ int main(int argc, char* argv[])
|
|||
|
||||
// ----- COM TX (20 ms) -----
|
||||
std::thread t_com_tx([transport] {
|
||||
std::cout << "[RUN] COM TX\n";
|
||||
ControlSnapshot last{};
|
||||
bool first = true;
|
||||
|
||||
while (g_running.load()) {
|
||||
|
||||
ControlSnapshot snap =
|
||||
ControlSnapshot cur =
|
||||
ControlState::snapshot();
|
||||
|
||||
auto frame =
|
||||
FrameCodec::build_fullstate_frame(snap);
|
||||
|
||||
if (transport->isReady()) {
|
||||
// for (unsigned char b : frame) {
|
||||
// printf("%02X ", b);
|
||||
// }
|
||||
// printf("\n");
|
||||
transport->sendBinary(frame);
|
||||
if (!first &&
|
||||
cur.steering == last.steering &&
|
||||
cur.throttle == last.throttle &&
|
||||
cur.brake == last.brake &&
|
||||
cur.direction == last.direction)
|
||||
{
|
||||
std::this_thread::sleep_for(
|
||||
std::chrono::milliseconds(20));
|
||||
continue;
|
||||
}
|
||||
|
||||
auto frame =
|
||||
FrameCodec::build_fullstate_frame(cur);
|
||||
|
||||
if (transport->isReady())
|
||||
transport->sendBinary(frame);
|
||||
|
||||
last = cur;
|
||||
first = false;
|
||||
|
||||
std::this_thread::sleep_for(
|
||||
std::chrono::milliseconds(20));
|
||||
std::chrono::milliseconds(20)); // 50Hz
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// --------------------------------------------------------
|
||||
// 6️⃣ MAIN IDLE LOOP
|
||||
// --------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Reference in New Issue