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& ) {}
43 struct ParamTocEntry {
84 enum BootloaderTarget {
90 MemoryTypeEEPROM = 0x00,
91 MemoryTypeOneWire = 0x01,
92 MemoryTypeLED12 = 0x10,
93 MemoryTypeLOCO = 0x11,
94 MemoryTypeTRAJ = 0x12,
95 MemoryTypeLOCO2 = 0x13,
97 MemoryTypeTester = 0x15,
101 struct MemoryTocEntry {
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(
141 float x,
float y,
float z,
float yawRate);
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);
189 BootloaderTarget target,
191 std::vector<uint8_t>& data);
193 void requestLogToc(
bool forceNoCache=
false);
195 void requestParamToc(
bool forceNoCache=
false);
197 void requestMemoryToc();
199 std::vector<ParamTocEntry>::const_iterator paramsBegin()
const {
200 return m_paramTocEntries.begin();
202 std::vector<ParamTocEntry>::const_iterator paramsEnd()
const {
203 return m_paramTocEntries.end();
206 std::vector<LogTocEntry>::const_iterator logVariablesBegin()
const {
207 return m_logTocEntries.begin();
209 std::vector<LogTocEntry>::const_iterator logVariablesEnd()
const {
210 return m_logTocEntries.end();
213 std::vector<MemoryTocEntry>::const_iterator memoriesBegin()
const {
214 return m_memoryTocEntries.begin();
216 std::vector<MemoryTocEntry>::const_iterator memoriesEnd()
const {
217 return m_memoryTocEntries.end();
221 void setParam(uint16_t
id,
const T&
value) {
223 memcpy(&v, &value,
sizeof(value));
228 void setParamByName(
const char*
group,
const char*
name,
const T& 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();
257 void addSetParam(uint16_t
id,
const T& value) {
259 memcpy(&v, &value,
sizeof(value));
263 void setRequestedParams();
267 T getParam(uint16_t
id)
const {
268 ParamValue v = getParam(
id);
269 return *(
reinterpret_cast<T*
>(&v));
272 const ParamTocEntry* getParamTocEntry(
273 const std::string& group,
274 const std::string& name)
const;
276 void setEmptyAckCallback(
278 m_emptyAckCallback = cb;
281 void setLinkQualityCallback(
282 std::function<
void(
float)> cb) {
283 m_linkQualityCallback = cb;
286 void setConsoleCallback(
287 std::function<
void(
const char*)> cb) {
288 m_consoleCallback = cb;
291 static size_t size(LogType t) {
314 void setGenericPacketCallback(
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);
394 void sendPacketOrTimeout(
398 sendPacketOrTimeoutInternal(
399 reinterpret_cast<const uint8_t*>(&request),
sizeof(request), useSafeLink);
405 std::vector<crtpPacket_t> m_outgoing_packets;
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);
435 const R* getRequestResult(
size_t index)
const {
436 return reinterpret_cast<const R*
>(m_batchRequests[index].ack.data);
478 const LogTocEntry* getLogTocEntry(
479 const std::string& group,
480 const std::string& name)
const;
482 uint8_t registerLogBlock(
485 bool unregisterLogBlock(
488 void setParam(uint16_t
id,
const ParamValue& value);
489 void addSetParam(uint16_t
id,
const ParamValue& value);
492 const ParamValue& getParam(uint16_t
id)
const {
493 return m_paramValues.at(
id);
505 std::vector<LogTocEntry> m_logTocEntries;
506 std::map<uint8_t, std::function<void(crtpLogDataResponse*, uint8_t)> > m_logBlockCb;
508 std::vector<ParamTocEntry> m_paramTocEntries;
509 std::map<uint16_t, ParamValue> m_paramValues;
511 std::vector<MemoryTocEntry> m_memoryTocEntries;
513 std::function<void(const crtpPlatformRSSIAck*)> m_emptyAckCallback;
514 std::function<void(float)> m_linkQualityCallback;
515 std::function<void(const char*)> m_consoleCallback;
516 std::function<void(const ITransport::Ack&)> m_genericPacketCallback;
526 size_t numBytesToMatch;
530 std::vector<batchRequest> m_batchRequests;
531 size_t m_numRequestsFinished;
532 size_t m_numRequestsEnqueued;
540 int m_protocolVersion;
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);
645 void start(uint8_t
period)
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());
677 std::function<void(uint32_t, T*)> m_callback;
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);
790 void start(uint8_t
period)
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;
891 std::vector<Crazyflie::LogType> m_types;
900 const std::string& link_uri);
905 void land(
float height,
float duration, uint8_t
groupMask = 0);
910 void goTo(
float x,
float y,
float z,
float yaw,
float duration, uint8_t
groupMask = 0);
913 void startTrajectory(
919 struct externalPosition
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());
uint8_t responseSize() const
uint32_t remainValidMillisecs
crtpParamTocGetItemRequest request
virtual void error(const std::string &)
virtual void info(const std::string &)
virtual void warning(const std::string &)
static size_t size(LogType t)