8std::unique_ptr<PGN129025> PGN129025::create(std::unique_ptr<Message2000> baseMessage) {
9 if (baseMessage->getCanFrameLength() != 8) {
10 std::string context =
"PGN129025::create()";
11 NMEALIB_RETURN_ERROR(InvalidCanFrameException(context,
"CAN frame must be 8 bytes for PGN129025"));
14 const int32_t latitudeRaw =
static_cast<int32_t
>(
15 static_cast<uint32_t
>(baseMessage->getCanFrame()[0]) |
16 (
static_cast<uint32_t
>(baseMessage->getCanFrame()[1]) << 8) |
17 (
static_cast<uint32_t
>(baseMessage->getCanFrame()[2]) << 16) |
18 (
static_cast<uint32_t
>(baseMessage->getCanFrame()[3]) << 24));
20 const int32_t longitudeRaw =
static_cast<int32_t
>(
21 static_cast<uint32_t
>(baseMessage->getCanFrame()[4]) |
22 (
static_cast<uint32_t
>(baseMessage->getCanFrame()[5]) << 8) |
23 (
static_cast<uint32_t
>(baseMessage->getCanFrame()[6]) << 16) |
24 (
static_cast<uint32_t
>(baseMessage->getCanFrame()[7]) << 24));
29 return std::unique_ptr<PGN129025>(
new PGN129025(std::move(*baseMessage), latitude, longitude));
32PGN129025::PGN129025(Message2000 baseMessage,
35 Message2000(std::move(baseMessage)),
37 longitude_(longitude) {}
43 longitude_(longitude) {}
46 return std::unique_ptr<PGN129025>(
new PGN129025(*
this));
50 std::ostringstream oss;
53 oss << this->toString(
true);
56 oss <<
"\tLatitude: " << latitude_.toString() <<
"°\n";
57 oss <<
"\tLongitude: " << longitude_.toString() <<
"°\n";
59 oss << this->toString(
false);
60 oss <<
"Latitude=" << latitude_.toString() <<
"°"
61 <<
" Longitude=" << longitude_.toString() <<
"°";
67std::string PGN129025::rawPayload(
Latitude latitude,
69 std::vector<uint8_t> canFrame(8, 0);
71 const auto latitudeRaw =
static_cast<uint32_t
>(latitude.
getRaw());
72 canFrame[0] =
static_cast<uint8_t
>(latitudeRaw & 0xFF);
73 canFrame[1] =
static_cast<uint8_t
>((latitudeRaw >> 8) & 0xFF);
74 canFrame[2] =
static_cast<uint8_t
>((latitudeRaw >> 16) & 0xFF);
75 canFrame[3] =
static_cast<uint8_t
>((latitudeRaw >> 24) & 0xFF);
77 const auto longitudeRaw =
static_cast<uint32_t
>(longitude.
getRaw());
78 canFrame[4] =
static_cast<uint8_t
>(longitudeRaw & 0xFF);
79 canFrame[5] =
static_cast<uint8_t
>((longitudeRaw >> 8) & 0xFF);
80 canFrame[6] =
static_cast<uint8_t
>((longitudeRaw >> 16) & 0xFF);
81 canFrame[7] =
static_cast<uint8_t
>((longitudeRaw >> 24) & 0xFF);
83 const uint32_t canId = (129025U << 8U);
84 std::ostringstream oss;
85 oss << std::hex << std::uppercase << std::setfill(
'0');
86 oss << std::setw(8) << canId <<
":";
87 for (uint8_t b : canFrame) {
88 oss << std::setw(2) << static_cast<int>(b);
103 latitude_ == other.latitude_ &&
104 longitude_ == other.longitude_;
RawType getRaw() const noexcept
Converts physical value to raw integer representation.
static constexpr DataType fromRaw(RawType raw) noexcept
Constructs from a raw value.
Represents a generic NMEA 2000 message encapsulating a CAN frame.
static std::unique_ptr< Message2000 > create(std::string raw, TimePoint ts=std::chrono::system_clock::now())
Protected factory — parses "CANID:data" (and variant formats) into a Message2000.
virtual bool operator==(const Message2000 &other) const noexcept
Strongly-typed class representing PGN 129025 - Position, Rapid Update.
std::string getStringContent(bool verbose) const noexcept override
Returns a human-readable string representation of the message.
bool operator==(const PGN129025 &other) const noexcept
Longitude getLongitude() const noexcept
PGN129025(Latitude latitude, Longitude longitude) noexcept
Latitude getLatitude() const noexcept
std::unique_ptr< nmealib::Message > clone() const override
Creates a polymorphic deep copy of this Message2000.
#define NMEALIB_RETURN_ERROR(exceptionExpr)
DataType< LongitudeTraits > Longitude
Custom type representing longitudes in degrees.
DataType< LatitudeTraits > Latitude
Custom type representing latitudes in degrees.