34 "[MavlinkDriver] Mavlink header not found! Please include your mavlink.h \
35implementation before including MavlinkDriver.h"
41#include <mavlink_lib/mavlink_types.h>
64template <
unsigned int PktLength,
unsigned int OutQueueSize,
65 unsigned int MavMsgLength = MAVLINK_MAX_PAYLOAD_LEN>
70 const mavlink_message_t& msg)>;
83 uint16_t sleepAfterSend = 0,
size_t outBufferMaxAge = 1000);
109 bool enqueueMsg(
const mavlink_message_t& msg);
154 static void rcvLauncher(
void* arg)
164 static void sndLauncher(
void* arg)
169 void updateQueueStats(
bool appended);
171 void updateSenderStats(
size_t msgCount,
bool sent);
174 MavHandler onReceive;
177 uint16_t sleepAfterSend;
178 size_t outBufferMaxAge;
179 uint16_t pollingTime = 100;
182 static constexpr size_t MAV_IN_BUFFER_SIZE = 1500;
184 SyncPacketQueue<PktLength, OutQueueSize> outQueue;
185 std::unique_ptr<uint8_t[]> rcvBuffer =
186 std::make_unique<uint8_t[]>(MAV_IN_BUFFER_SIZE);
190 miosix::FastMutex mtxStatus;
193 bool stopFlag =
false;
194 bool sndStarted =
false;
195 bool rcvStarted =
false;
197 miosix::Thread* sndThread =
nullptr;
198 miosix::Thread* rcvThread =
nullptr;
203template <
unsigned int PktLength,
unsigned int OutQueueSize,
204 unsigned int MavMsgLength>
206 Transceiver* device, MavHandler onReceive, uint16_t sleepAfterSend,
207 size_t outBufferMaxAge)
208 : device(device), onReceive(onReceive), sleepAfterSend(sleepAfterSend),
209 outBufferMaxAge(outBufferMaxAge)
214template <
unsigned int PktLength,
unsigned int OutQueueSize,
215 unsigned int MavMsgLength>
223 sndThread = miosix::Thread::create(
224 sndLauncher,
skywardStack(4 * 1024), miosix::MAIN_PRIORITY,
225 reinterpret_cast<void*
>(
this), miosix::Thread::JOINABLE);
227 if (sndThread !=
nullptr)
230 LOG_ERR(logger,
"Could not start sender!");
236 rcvThread = miosix::Thread::create(rcvLauncher,
skywardStack(4 * 1024),
237 miosix::MAIN_PRIORITY,
238 reinterpret_cast<void*
>(
this));
240 if (rcvThread !=
nullptr)
243 LOG_ERR(logger,
"Could not start receiver!");
246 if (sndStarted && rcvStarted)
247 LOG_DEBUG(logger,
"Sender and receiver started");
249 return sndStarted && rcvStarted;
252template <
unsigned int PktLength,
unsigned int OutQueueSize,
253 unsigned int MavMsgLength>
256 return sndStarted && rcvStarted;
259template <
unsigned int PktLength,
unsigned int OutQueueSize,
260 unsigned int MavMsgLength>
269template <
unsigned int PktLength,
unsigned int OutQueueSize,
270 unsigned int MavMsgLength>
272 const mavlink_message_t& msg)
275 uint8_t msgTempBuf[MAVLINK_NUM_NON_PAYLOAD_BYTES + MavMsgLength];
276 int msgLen = mavlink_msg_to_send_buffer(msgTempBuf, &msg);
279 bool appended = outQueue.put(msgTempBuf, msgLen);
282 updateQueueStats(appended);
288template <
unsigned int PktLength,
unsigned int OutQueueSize,
289 unsigned int MavMsgLength>
291 uint8_t* msg,
size_t size)
294 bool appended = outQueue.put(msg, size);
297 updateQueueStats(appended);
303template <
unsigned int PktLength,
unsigned int OutQueueSize,
304 unsigned int MavMsgLength>
308 miosix::Lock<miosix::FastMutex> l(mtxStatus);
312 LOG_ERR(logger,
"Buffer full, the oldest message has been discarded");
313 status.nDroppedPackets++;
318 if (status.nSendQueue > status.maxSendQueue)
319 status.maxSendQueue = status.nSendQueue;
322template <
unsigned int PktLength,
unsigned int OutQueueSize,
323 unsigned int MavMsgLength>
324void MavlinkDriver<PktLength, OutQueueSize, MavMsgLength>::runReceiver()
326 mavlink_message_t msg;
328 uint8_t parseResult = 0;
333 rcvSize = device->receive(rcvBuffer.get(), MAV_IN_BUFFER_SIZE);
339 miosix::Lock<miosix::FastMutex>
l(mtxStatus);
341 for (ssize_t i = 0; i < rcvSize; i++)
345 mavlink_parse_char(MAVLINK_COMM_0,
351 if (parseResult == 1)
355 miosix::Unlock<miosix::FastMutex> unlock(l);
358 "Received message with ID {}, sequence: {} from "
359 "component {} of system {}",
360 msg.msgid, msg.seq, msg.compid, msg.sysid);
363 if (onReceive !=
nullptr)
364 onReceive(
this, msg);
373template <
unsigned int PktLength,
unsigned int OutQueueSize,
374 unsigned int MavMsgLength>
375void MavlinkDriver<PktLength, OutQueueSize, MavMsgLength>::runSender()
378 Packet<PktLength> pkt;
382 outQueue.waitUntilNotEmpty();
384 if (!outQueue.isEmpty())
387 pkt = outQueue.get();
391 if (pkt.isReady() || age >= outBufferMaxAge * 1e3)
395 LOG_DEBUG(logger,
"Sending packet. Size: {} (age: {})",
398 bool sent = device->send(pkt.content.data(), pkt.size());
399 updateSenderStats(pkt.getMsgCount(), sent);
401 miosix::Thread::sleep(sleepAfterSend);
406 miosix::Thread::sleep(50);
412template <
unsigned int PktLength,
unsigned int OutQueueSize,
413 unsigned int MavMsgLength>
414void MavlinkDriver<PktLength, OutQueueSize, MavMsgLength>::updateSenderStats(
415 size_t msgCount,
bool sent)
418 miosix::Lock<miosix::FastMutex>
l(mtxStatus);
419 status.nSendQueue -= msgCount;
423 status.nSendErrors++;
424 LOG_ERR(logger,
"Could not send message");
431template <
unsigned int PktLength,
unsigned int OutQueueSize,
432 unsigned int MavMsgLength>
435 miosix::Lock<miosix::FastMutex> l(mtxStatus);
440template <
unsigned int PktLength,
unsigned int OutQueueSize,
441 unsigned int MavMsgLength>
443 uint16_t newSleepTime)
445 sleepAfterSend = newSleepTime;
#define LOG_ERR(logger,...)
#define LOG_DEBUG(logger,...)
static PrintLogger getLogger(const string &name)
The MavlinkDriver object offers an interface to send and receive from a Transceiver object using an i...
void stop()
Stops sender and receiver threads.
MavlinkDriver(Transceiver *device, MavHandler onReceive=nullptr, uint16_t sleepAfterSend=0, size_t outBufferMaxAge=1000)
Initializes all data structures.
MavlinkStatus getStatus()
Synchronized status getter.
bool isStarted()
Tells whether the driver was started.
bool enqueueRaw(uint8_t *msg, size_t size)
Enqueue a raw packet message into the sync packet queue.
void setSleepAfterSend(uint16_t newSleepTime)
Setter for the sleep after send value.
bool start()
Start the receiving and sending threads.
bool enqueueMsg(const mavlink_message_t &msg)
Non-blocking send function, puts the message in a queue. Message is discarded if the queue is full.
static StackLogger & getInstance()
uint64_t getTimestamp()
Returns the current timer value in microseconds.
This file includes all the types the logdecoder script will decode.
unsigned int skywardStack(unsigned int stack)