15 #define ENABLE_SAFELINK 0 23 virtual void info(
const std::string& ) {}
24 virtual void warning(
const std::string& ) {}
25 virtual void error(
const std::string& ) {}
90 MemoryTypeEEPROM = 0x00,
91 MemoryTypeOneWire = 0x01,
92 MemoryTypeLED12 = 0x10,
93 MemoryTypeLOCO = 0x11,
94 MemoryTypeTRAJ = 0x12,
95 MemoryTypeLOCO2 = 0x13,
97 MemoryTypeTester = 0x15,
115 const std::string& link_uri,
116 Logger& logger = EmptyLogger,
117 std::function<
void(
const char*)> consoleCb =
nullptr);
119 int getProtocolVersion();
121 std::string getFirmwareVersion();
123 std::string getDeviceTypeName();
133 void sendFullStateSetpoint(
134 float x,
float y,
float z,
135 float vx,
float vy,
float vz,
136 float ax,
float ay,
float az,
137 float qx,
float qy,
float qz,
float qw,
138 float rollRate,
float pitchRate,
float yawRate);
140 void sendVelocityWorldSetpoint(
143 void sendHoverSetpoint(
149 void sendPositionSetpoint(
159 void emergencyStop();
161 void emergencyStopWatchdog();
163 void sendExternalPositionUpdate(
168 void sendExternalPoseUpdate(
169 float x,
float y,
float z,
170 float qx,
float qy,
float qz,
float qw);
176 uint64_t rebootToBootloader();
178 void rebootFromBootloader();
187 const std::vector<uint8_t>&
data);
191 std::vector<uint8_t>&
data);
193 void requestLogToc(
bool forceNoCache=
false);
195 void requestParamToc(
bool forceNoCache=
false);
197 void requestMemoryToc();
200 return m_paramTocEntries.begin();
202 std::vector<ParamTocEntry>::const_iterator
paramsEnd()
const {
203 return m_paramTocEntries.end();
207 return m_logTocEntries.begin();
210 return m_logTocEntries.end();
214 return m_memoryTocEntries.begin();
217 return m_memoryTocEntries.end();
223 memcpy(&v, &value,
sizeof(value));
233 reinterpret_cast<const uint8_t*>(&request), request.
size(), request.
responseSize() - 1);
235 auto response = getRequestResult<crtpParamSetByNameResponse>(0);
239 std::stringstream sstr;
240 sstr <<
"Couldn't set parameter " << group <<
"." << name <<
"!";
241 if (error == ENOENT) {
242 sstr <<
"No such variable." << std::endl;
243 }
else if (error == EINVAL) {
244 sstr <<
"Wrong type." << std::endl;
245 }
else if (error == EACCES) {
246 sstr <<
"Variable is readonly." << std::endl;
248 sstr <<
" Error: " << (int)error << std::endl;
250 throw std::runtime_error(sstr.str());
254 void startSetParamRequest();
259 memcpy(&v, &value,
sizeof(value));
263 void setRequestedParams();
269 return *(
reinterpret_cast<T*
>(&v));
273 const std::string&
group,
274 const std::string&
name)
const;
278 m_emptyAckCallback = cb;
282 std::function<
void(
float)> cb) {
283 m_linkQualityCallback = cb;
287 std::function<
void(
const char*)> cb) {
288 m_consoleCallback = cb;
316 m_genericPacketCallback = cb;
324 m_outgoing_packets.push_back(packet);
327 void transmitPackets();
332 void takeoff(
float height,
float duration, uint8_t groupMask = 0);
334 void land(
float height,
float duration, uint8_t groupMask = 0);
336 void stop(uint8_t groupMask = 0);
338 void goTo(
float x,
float y,
float z,
float yaw,
float duration,
bool relative =
false, uint8_t groupMask = 0);
340 void uploadTrajectory(
342 uint32_t pieceOffset,
343 const std::vector<poly4d>& pieces);
345 void startTrajectory(
346 uint8_t trajectoryId,
350 uint8_t groupMask = 0);
354 std::vector<uint8_t>&
data);
357 void sendPacketInternal(
370 reinterpret_cast<const uint8_t*>(&request),
sizeof(request), result, useSafeLink);
373 bool sendPacketInternal(
384 reinterpret_cast<const uint8_t*>(&request),
sizeof(request), useSafeLink);
387 void sendPacketOrTimeoutInternal(
391 float timeout = 1.0);
398 sendPacketOrTimeoutInternal(
399 reinterpret_cast<const uint8_t*>(&request),
sizeof(request), useSafeLink);
407 void startBatchRequest();
409 void addRequestInternal(
412 size_t numBytesToMatch);
417 size_t numBytesToMatch)
420 reinterpret_cast<const uint8_t*>(&request),
sizeof(request), numBytesToMatch);
424 bool crtpMode =
true,
426 float baseTime = 2.0,
427 float timePerRequest = 0.2);
436 return reinterpret_cast<const R*
>(m_batchRequests[index].ack.data);
479 const std::string& group,
480 const std::string& name)
const;
482 uint8_t registerLogBlock(
485 bool unregisterLogBlock(
493 return m_paramValues.at(
id);
506 std::map<uint8_t, std::function<void(crtpLogDataResponse*, uint8_t)> >
m_logBlockCb;
552 std::list<std::pair<std::string, std::string> > variables,
553 std::function<
void(uint32_t, T*)>& callback)
555 , m_callback(callback)
558 m_id = m_cf->registerLogBlock([=](
crtpLogDataResponse* r, uint8_t s) { this->handleData(r, s);});
559 if (m_cf->m_log_use_V2) {
560 std::vector<logBlockItemV2> logBlockItems;
562 for (
auto&& pair : variables) {
567 std::stringstream sstr;
568 sstr <<
"Can't configure that many variables in a single log block!" 569 <<
" Ignoring " << pair.first <<
"." << pair.second << std::endl;
570 throw std::runtime_error(sstr.str());
572 logBlockItems.push_back({
static_cast<uint8_t
>(entry->
type), entry->
id});
576 std::stringstream sstr;
577 sstr <<
"Could not find " << pair.first <<
"." << pair.second <<
" in log toc!";
578 throw std::runtime_error(sstr.str());
583 size_t requests = ceil(logBlockItems.size() / 9.0f);
585 for (
size_t r = 0; r < requests; ++r) {
586 size_t numElements = std::min<size_t>(logBlockItems.size() - i, 9);
591 m_cf->sendPacketOrTimeoutInternal(reinterpret_cast<const uint8_t*>(&request), 3 + 3*numElements);
596 m_cf->sendPacketOrTimeoutInternal(reinterpret_cast<const uint8_t*>(&request), 3 + 3*numElements);
611 for (
auto&& pair : variables) {
619 std::stringstream sstr;
620 sstr <<
"Could not find " << pair.first <<
"." << pair.second <<
" in log toc!";
621 throw std::runtime_error(sstr.str());
625 m_cf->startBatchRequest();
626 m_cf->addRequestInternal(reinterpret_cast<const uint8_t*>(&request), 3 + 2*i, 2);
627 m_cf->handleRequests();
631 std::stringstream sstr;
632 sstr <<
"Could not create log block! Result: " << (int)r->result <<
" " << (
int)m_id <<
" " << (int)r->requestByte1 <<
" " << (
int)r->command;
633 throw std::runtime_error(sstr.str());
641 m_cf->unregisterLogBlock(m_id);
648 m_cf->startBatchRequest();
649 m_cf->addRequest(request, 2);
650 m_cf->handleRequests();
656 m_cf->startBatchRequest();
657 m_cf->addRequest(request, 2);
658 m_cf->handleRequests();
663 if (size ==
sizeof(T)) {
665 T* t = (T*)response->
data;
666 m_callback(time_in_ms, t);
669 std::stringstream sstr;
670 sstr <<
"Size doesn't match! Is: " << (size_t)size <<
" expected: " <<
sizeof(T);
671 throw std::runtime_error(sstr.str());
688 const std::vector<std::string>& variables,
690 std::function<
void(uint32_t, std::vector<double>*,
void* userData)>& callback)
692 , m_userData(userData)
693 , m_callback(callback)
696 m_id = m_cf->registerLogBlock([=](
crtpLogDataResponse* r, uint8_t s) { this->handleData(r, s);});
697 if (m_cf->m_log_use_V2) {
702 for (
auto&& var : variables) {
703 auto pos = var.find(
".");
704 std::string first = var.substr(0, pos);
705 std::string second = var.substr(pos+1);
710 std::stringstream sstr;
711 sstr <<
"Can't configure that many variables in a single log block!" 712 <<
" Ignoring " << first <<
"." << second << std::endl;
713 throw std::runtime_error(sstr.str());
719 m_types.push_back(entry->
type);
721 std::stringstream sstr;
722 sstr <<
"Can only log up to 9 variables at a time!" 723 <<
" Ignoring " << first <<
"." << second << std::endl;
724 throw std::runtime_error(sstr.str());
729 std::stringstream sstr;
730 sstr <<
"Could not find " << first <<
"." << second <<
" in log toc!";
731 throw std::runtime_error(sstr.str());
734 m_cf->startBatchRequest();
735 m_cf->addRequestInternal(reinterpret_cast<const uint8_t*>(&request), 3 + 3*i, 2);
736 m_cf->handleRequests();
740 throw std::runtime_error(
"Could not create log block!");
747 for (
auto&& var : variables) {
748 auto pos = var.find(
".");
749 std::string first = var.substr(0, pos);
750 std::string second = var.substr(pos+1);
755 std::stringstream sstr;
756 sstr <<
"Can't configure that many variables in a single log block!" 757 <<
" Ignoring " << first <<
"." << second << std::endl;
758 throw std::runtime_error(sstr.str());
763 m_types.push_back(entry->
type);
767 std::stringstream sstr;
768 sstr <<
"Could not find " << first <<
"." << second <<
" in log toc!";
769 throw std::runtime_error(sstr.str());
772 m_cf->startBatchRequest();
773 m_cf->addRequestInternal(reinterpret_cast<const uint8_t*>(&request), 3 + 2*i, 2);
774 m_cf->handleRequests();
778 throw std::runtime_error(
"Could not create log block!");
786 m_cf->unregisterLogBlock(m_id);
793 m_cf->startBatchRequest();
794 m_cf->addRequest(request, 2);
795 m_cf->handleRequests();
801 m_cf->startBatchRequest();
802 m_cf->addRequest(request, 2);
803 m_cf->handleRequests();
809 std::vector<double>
result;
811 for (
size_t i = 0; i < m_types.size(); ++i)
818 memcpy(&value, &response->
data[pos],
sizeof(uint8_t));
819 result.push_back(value);
820 pos +=
sizeof(uint8_t);
826 memcpy(&value, &response->
data[pos],
sizeof(int8_t));
827 result.push_back(value);
828 pos +=
sizeof(int8_t);
834 memcpy(&value, &response->
data[pos],
sizeof(uint16_t));
835 result.push_back(value);
836 pos +=
sizeof(uint16_t);
842 memcpy(&value, &response->
data[pos],
sizeof(int16_t));
843 result.push_back(value);
844 pos +=
sizeof(int16_t);
850 memcpy(&value, &response->
data[pos],
sizeof(uint32_t));
851 result.push_back(value);
852 pos +=
sizeof(uint32_t);
858 memcpy(&value, &response->
data[pos],
sizeof(int32_t));
859 result.push_back(value);
860 pos +=
sizeof(int32_t);
866 memcpy(&value, &response->
data[pos],
sizeof(
float));
867 result.push_back(value);
868 pos +=
sizeof(float);
874 memcpy(&value, &response->
data[pos],
sizeof(
double));
875 result.push_back(value);
876 pos +=
sizeof(double);
883 m_callback(time_in_ms, &result, m_userData);
889 std::function<void(uint32_t, std::vector<double>*,
void*)> m_callback;
900 const std::string& link_uri);
903 void takeoff(
float height,
float duration, uint8_t groupMask = 0);
905 void land(
float height,
float duration, uint8_t groupMask = 0);
907 void stop(uint8_t groupMask = 0);
910 void goTo(
float x,
float y,
float z,
float yaw,
float duration, uint8_t groupMask = 0);
913 void startTrajectory(
914 uint8_t trajectoryId,
917 uint8_t groupMask = 0);
927 void sendExternalPositions(
928 const std::vector<externalPosition>& data);
942 void sendExternalPoses(
943 const std::vector<externalPose>& data);
945 void emergencyStop();
947 void emergencyStopWatchdog();
956 sendPacket(reinterpret_cast<const uint8_t*>(&request), request.
size());
void setEmptyAckCallback(std::function< void(const crtpPlatformRSSIAck *)> cb)
std::vector< crtpPacket_t > m_outgoing_packets
LogBlockGeneric(Crazyflie *cf, const std::vector< std::string > &variables, void *userData, std::function< void(uint32_t, std::vector< double > *, void *userData)> &callback)
const R * getRequestResult(size_t index) const
std::vector< batchRequest > m_batchRequests
std::vector< MemoryTocEntry >::const_iterator memoriesBegin() const
Crazyradio::Datarate m_datarate
std::vector< MemoryTocEntry > m_memoryTocEntries
uint8_t responseSize() const
uint32_t remainValidMillisecs
void setGenericPacketCallback(std::function< void(const ITransport::Ack &)> cb)
LogBlock(Crazyflie *cf, std::list< std::pair< std::string, std::string > > variables, std::function< void(uint32_t, T *)> &callback)
void setConsoleCallback(std::function< void(const char *)> cb)
void setParamByName(const char *group, const char *name, const T &value)
void queueOutgoingPacket(const crtpPacket_t &packet)
std::vector< ParamTocEntry >::const_iterator paramsBegin() const
void handleData(crtpLogDataResponse *response, uint8_t size)
std::function< void(const crtpPlatformRSSIAck *)> m_emptyAckCallback
void sendPacket(const R &request, ITransport::Ack &result, bool useSafeLink=ENABLE_SAFELINK)
std::vector< MemoryTocEntry >::const_iterator memoriesEnd() const
std::function< void(uint32_t, T *)> m_callback
size_t m_numRequestsEnqueued
void setParam(uint16_t id, const T &value)
std::vector< ParamTocEntry >::const_iterator paramsEnd() const
std::map< uint8_t, std::function< void(crtpLogDataResponse *, uint8_t)> > m_logBlockCb
void setParam(const char *group, const char *name, const T &value)
const ParamValue & getParam(uint16_t id) const
void start(uint8_t period)
std::vector< LogTocEntry >::const_iterator logVariablesEnd() const
void sendPacket(const R &request, bool useSafeLink=ENABLE_SAFELINK)
crtpParamTocGetItemRequest request
virtual void error(const std::string &)
std::vector< uint8_t > request
std::vector< LogTocEntry >::const_iterator logVariablesBegin() const
size_t m_numRequestsFinished
virtual void info(const std::string &)
virtual void warning(const std::string &)
std::vector< LogTocEntry > m_logTocEntries
std::vector< Crazyflie::LogType > m_types
std::vector< ParamTocEntry > m_paramTocEntries
T getParam(uint16_t id) const
static size_t size(LogType t)
Crazyradio::Datarate m_datarate
void handleData(crtpLogDataResponse *response, uint8_t)
void start(uint8_t period)
void addRequest(const R &request, size_t numBytesToMatch)
std::map< uint16_t, ParamValue > m_paramValues
std::function< void(const char *)> m_consoleCallback
std::function< void(float)> m_linkQualityCallback
void sendPacketOrTimeout(const R &request, bool useSafeLink=ENABLE_SAFELINK)
void setLinkQualityCallback(std::function< void(float)> cb)
void addSetParam(uint16_t id, const T &value)
std::function< void(const ITransport::Ack &)> m_genericPacketCallback