nmealib 0.0.4
NMEA 0183/NMEA 2000 parsing library
Loading...
Searching...
No Matches
PGN127251.cpp
Go to the documentation of this file.
2
4
5namespace nmealib {
6namespace nmea2000 {
7
8std::unique_ptr<PGN127251> PGN127251::create(std::unique_ptr<Message2000> baseMessage) {
9 if (baseMessage->getCanFrameLength() != 8) {
10 std::string context = "PGN127251::create()";
11 NMEALIB_RETURN_ERROR(InvalidCanFrameException(context, "CAN frame must be 8 bytes for PGN127251"));
12 }
13
14 const uint8_t sequenceId = baseMessage->getCanFrame()[0];
15 const uint32_t rawRateBits = static_cast<uint32_t>(baseMessage->getCanFrame()[1]) |
16 (static_cast<uint32_t>(baseMessage->getCanFrame()[2]) << 8) |
17 (static_cast<uint32_t>(baseMessage->getCanFrame()[3]) << 16) |
18 (static_cast<uint32_t>(baseMessage->getCanFrame()[4]) << 24);
19 const AngularRate rate = AngularRate::fromRaw(static_cast<int32_t>(rawRateBits));
20 const Byte reserved1 = Byte::fromRaw(baseMessage->getCanFrame()[5]);
21 const Byte reserved2 = Byte::fromRaw(baseMessage->getCanFrame()[6]);
22 const Byte reserved3 = Byte::fromRaw(baseMessage->getCanFrame()[7]);
23
24 return std::unique_ptr<PGN127251>(new PGN127251(std::move(*baseMessage),
25 sequenceId,
26 rate,
27 reserved1,
28 reserved2,
29 reserved3));
30}
31
32PGN127251::PGN127251(Message2000 baseMessage,
33 uint8_t sequenceId,
34 AngularRate rate,
35 Byte reserved1,
36 Byte reserved2,
37 Byte reserved3) noexcept :
38 Message2000(std::move(baseMessage)),
39 sequenceId_(sequenceId),
40 rate_(rate),
41 reserved1_(reserved1),
42 reserved2_(reserved2),
43 reserved3_(reserved3) {}
44
45PGN127251::PGN127251(uint8_t sequenceId,
46 AngularRate rate,
47 Byte reserved1,
48 Byte reserved2,
49 Byte reserved3) noexcept :
50 Message2000(*Message2000::create(rawPayload(sequenceId,
51 rate,
52 reserved1,
53 reserved2,
54 reserved3))),
55 sequenceId_(sequenceId),
56 rate_(rate),
57 reserved1_(reserved1),
58 reserved2_(reserved2),
59 reserved3_(reserved3) {}
60
61std::unique_ptr<Message> PGN127251::clone() const {
62 return std::unique_ptr<PGN127251>(new PGN127251(*this));
63}
64
65std::string PGN127251::getStringContent(bool verbose) const noexcept {
66 std::ostringstream oss;
67
68 if (verbose) {
69 oss << this->toString(true);
70 oss << "\n";
71 oss << "Fields:\n";
72 oss << "\tSequence ID: " << static_cast<int>(sequenceId_) << "\n";
73 oss << "\tRate: " << rate_.toString() << " rad/s\n";
74 oss << "\tReserved1: " << static_cast<int>(reserved1_.getValue()) << "\n";
75 oss << "\tReserved2: " << static_cast<int>(reserved2_.getValue()) << "\n";
76 oss << "\tReserved3: " << static_cast<int>(reserved3_.getValue()) << "\n";
77 } else {
78 oss << this->toString(false);
79 oss << "SeqID=" << static_cast<int>(sequenceId_)
80 << " Rate=" << rate_.toString() << "rad/s"
81 << " R1=" << static_cast<int>(reserved1_.getValue())
82 << " R2=" << static_cast<int>(reserved2_.getValue())
83 << " R3=" << static_cast<int>(reserved3_.getValue());
84 }
85
86 return oss.str();
87}
88
89std::string PGN127251::rawPayload(uint8_t sequenceId,
90 AngularRate rate,
91 Byte reserved1,
92 Byte reserved2,
93 Byte reserved3) noexcept {
94 std::vector<uint8_t> canFrame(8, 0);
95 canFrame[0] = sequenceId;
96
97 const uint32_t rawRateBits = static_cast<uint32_t>(rate.getRaw());
98 canFrame[1] = static_cast<uint8_t>(rawRateBits & 0xFFU);
99 canFrame[2] = static_cast<uint8_t>((rawRateBits >> 8) & 0xFFU);
100 canFrame[3] = static_cast<uint8_t>((rawRateBits >> 16) & 0xFFU);
101 canFrame[4] = static_cast<uint8_t>((rawRateBits >> 24) & 0xFFU);
102 canFrame[5] = reserved1.getRaw();
103 canFrame[6] = reserved2.getRaw();
104 canFrame[7] = reserved3.getRaw();
105
106 const uint32_t canId = (127251U << 8U);
107 std::ostringstream oss;
108 oss << std::hex << std::uppercase << std::setfill('0');
109 oss << std::setw(8) << canId << ":";
110 for (uint8_t b : canFrame) {
111 oss << std::setw(2) << static_cast<int>(b);
112 }
113 return oss.str();
114}
115
116uint8_t PGN127251::getSequenceId() const noexcept {
117 return sequenceId_;
118}
119
121 return rate_;
122}
123
125 return reserved1_;
126}
127
129 return reserved2_;
130}
131
133 return reserved3_;
134}
135
136bool PGN127251::operator==(const PGN127251& other) const noexcept {
137 return Message2000::operator==(other) &&
138 sequenceId_ == other.sequenceId_ &&
139 rate_ == other.rate_ &&
140 reserved1_ == other.reserved1_ &&
141 reserved2_ == other.reserved2_ &&
142 reserved3_ == other.reserved3_;
143}
144
145} // namespace nmea2000
146} // namespace nmealib
static constexpr DataType fromRaw(RawType raw) noexcept
Constructs from a raw value.
Definition dataTypes.h:97
Represents a generic NMEA 2000 message encapsulating a CAN frame.
Definition nmea2000.h:62
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.
Definition nmea2000.cpp:109
virtual bool operator==(const Message2000 &other) const noexcept
Definition nmea2000.cpp:401
Strongly-typed class representing PGN 127251 - Rate of Turn.
Definition PGN127251.h:22
Byte getReserved1() const noexcept
Byte getReserved2() const noexcept
PGN127251(uint8_t sequenceId, AngularRate rate, Byte reserved1=Byte::fromValue(0U), Byte reserved2=Byte::fromValue(0U), Byte reserved3=Byte::fromValue(0U)) noexcept
Definition PGN127251.cpp:45
AngularRate getRate() const noexcept
std::unique_ptr< nmealib::Message > clone() const override
Creates a polymorphic deep copy of this Message2000.
Definition PGN127251.cpp:61
std::string getStringContent(bool verbose) const noexcept override
Returns a human-readable string representation of the message.
Definition PGN127251.cpp:65
bool operator==(const PGN127251 &other) const noexcept
uint8_t getSequenceId() const noexcept
Byte getReserved3() const noexcept
#define NMEALIB_RETURN_ERROR(exceptionExpr)
DataType< ByteTraits > Byte
Custom type representing 8 bits of data (0-255).
Definition dataTypes.h:330
DataType< AngularRateTraits > AngularRate
Custom type representing angular rates in radians per second.
Definition dataTypes.h:395