TPIK  1.0
Task Priority Inverse Kinematics
Loading...
Searching...
No Matches
futils.h
Go to the documentation of this file.
1
16#ifndef FUTILS_H_
17#define FUTILS_H_
18
19#include <iostream>
20#include <fstream>
21#include <sstream>
22#include <string>
23#include <cstdio>
24#include <cstring>
25#include <cstdlib>
26#include <ctime>
27#include <vector>
28#include <unistd.h>
29#include <map>
30#include <sys/types.h>
31#include <sys/socket.h>
32#include <netinet/in.h>
33#include <arpa/inet.h>
34#include <fcntl.h>
35#include <sys/stat.h>
36#include <pwd.h>
37#include <iomanip>
38#include <algorithm>
39#include <memory>
40#include <stdexcept>
41#include <array>
42
43#ifdef DEBUG_PRINT
44# define dout std::cerr
45# define d_out(x) (std::cerr << x << std::endl)
46#else
47# define dout 0 && std::cerr
48# define d_out(x) 0 && std::cerr
49#endif
50
82#if defined(__linux__) || defined(linux)
83
84namespace tc
85{
86const char* const none = "\033[0m";
87const char* const black = "\033[0;30m";
88const char* const grayD = "\033[1;30m";
89const char* const red = "\033[0;31m";
90const char* const redL = "\033[1;31m";
91const char* const green = "\033[0;32m";
92const char* const greenL = "\033[1;32m";
93const char* const brown = "\033[0;33m";
94const char* const yellow = "\033[1;33m";
95const char* const blu = "\033[0;34m";
96const char* const bluL = "\033[1;34m";
97const char* const mag = "\033[0;35m";
98const char* const magL = "\033[1;35m";
99const char* const cyan = "\033[0;36m";
100const char* const cyanL = "\033[1;36m";
101const char* const grayL = "\033[0;37m";
102const char* const white = "\033[1;37m";
103}
104#endif
105
106/*enum class LogEntities {
107 Controller, Driver, Logger, UDPReceiver, UDPSender, Generic
108 };
109
110 inline std::string DebugMsg(const LogEntities entity, const std::string inputMsg, const std::string generic = "") {
111 std::stringstream strstr;
112 switch (entity) {
113 case LogEntities::Controller:
114 strstr << tc::cyanL << "[controller] ";
115 break;
116 case LogEntities::Driver:
117 strstr << tc::magL << "[driver] ";
118 break;
119 case LogEntities::Logger:
120 strstr << tc::grnL << "[logger] ";
121 break;
122 case LogEntities::UDPReceiver:
123 strstr << tc::bluL << "[udpReceiver] ";
124 break;
125 case LogEntities::UDPSender:
126 strstr << tc::bluL << "[udpSender] ";
127 break;
128 case LogEntities::Generic:
129 std::string fillerString;
130 if (generic == "")
131 fillerString = "generic";
132 strstr << tc::white << "[" << generic << fillerString << "] ";
133 break;
134 }
135 strstr << tc::none << inputMsg;
136 return strstr.str();
137 }*/
138
139namespace futils
140{
141
142template<class Object>
143void PrettyPrint(const Object& A, std::string name, const char* color = tc::white)
144{
145 std::cout << color << name << tc::none << std::endl << A << std::endl;
146}
147
154inline int MakeDir(const char *path)
155{
161 int ret;
162 //struct stat buf;
163 //std::string file(path);
164 //if (stat(path, &buf) == 0){
165 ret = mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO);
166 if (ret != 0) {
167 if (errno != EEXIST) {
168 std::cerr << tc::redL << "Could not create directory " << path << " (error: " << strerror(errno) << ")\n";
169 return false;
170 } else {
171 return true;
172 }
173 }
174 chmod(path, S_IRWXU | S_IRWXG | S_IRWXO);
175 return true;
176 //}
177}
178
180
188{
189 Spinner(int frequency) :
190 freq(frequency), spinIndex(0), spin_chars("/-\\|")
191 {
192 clock_gettime(CLOCK_MONOTONIC, &last);
193 period = 1 / static_cast<double>(freq + 1E-6);
194 //std::cout << "period: " << period << "s" << std::endl;
195 }
196
197 void operator()(void)
198 {
199
200 clock_gettime(CLOCK_MONOTONIC, &now);
201 double timeElapsed = (now.tv_sec - last.tv_sec) + (now.tv_nsec - last.tv_nsec) / 1E9;
202
203 //std::cout << "timeElapsed: " << timeElapsed << std::endl;
204 if (period - timeElapsed < 1E-3) {
205 //std::cout << "fabs(freq - timeElapsed): " << fabs(freq - timeElapsed) << std::endl;
206 //printf("\e[?25l"); /* hide the cursor */
207 putchar(' ');
208 putchar(spin_chars[spinIndex % spin_chars.length()]);
209 putchar(' ');
210 fflush(stdout);
211 putchar('\r');
212 spinIndex++;
213 last = now;
214 }
215
216 }
217
218private:
219 struct timespec last, now;
220 int freq;
221 double period;
222 unsigned long spinIndex;
223 std::string spin_chars;
224};
225
232struct Dotter
233{
234 Dotter(int freq) :
235 spinIndex(0), spin_chars("... .. .. .. .... .... .")
236 {
237 clock_gettime(CLOCK_MONOTONIC, &last);
238 period = 1 / static_cast<double>(freq);
239 //std::cout << "period: " << period << "s" << std::endl;
240 }
241
242 void operator()(void)
243 {
244
245 clock_gettime(CLOCK_MONOTONIC, &now);
246 double timeElapsed = (now.tv_sec - last.tv_sec) + (now.tv_nsec - last.tv_nsec) / 1E9;
247
248 //std::cout << "timeElapsed: " << timeElapsed << std::endl;
249 if (period - timeElapsed < 1E-3) {
250 //std::cout << "fabs(freq - timeElapsed): " << fabs(freq - timeElapsed) << std::endl;
251 //putchar(' ');
252 putchar(spin_chars[spinIndex % spin_chars.length()]);
253 putchar(spin_chars[(spinIndex % spin_chars.length()) + 1]);
254 putchar(spin_chars[(spinIndex % spin_chars.length()) + 2]);
255 putchar(spin_chars[(spinIndex % spin_chars.length()) + 3]);
256 putchar(' ');
257 fflush(stdout);
258 putchar('\r');
259 spinIndex += 4;
260 last = now;
261 }
262
263 }
264
265private:
266 struct timespec last, now;
267 //int freq;
268 double period;
269 unsigned long spinIndex;
270 std::string spin_chars;
271};
272
277struct Timer
278{
280 running(false), elapsedTime(0), lapTime(0)
281 {
282 clock_gettime(CLOCK_MONOTONIC, &now);
283 lap = now;
284 }
285
286 void Start()
287 {
288 clock_gettime(CLOCK_MONOTONIC, &start);
289 lap = start;
290 running = true;
291 }
292
293 void Stop()
294 {
295 lapTime = 0;
296 running = false;
297 }
298
302 double Elapsed()
303 {
304 if (running) {
305 clock_gettime(CLOCK_MONOTONIC, &now);
306 elapsedTime = (now.tv_sec - start.tv_sec) + (now.tv_nsec - start.tv_nsec) / 1E9;
307 return elapsedTime;
308 } else {
309 return 0.0;
310 }
311 }
312
316 double Lap()
317 {
318 clock_gettime(CLOCK_MONOTONIC, &now);
319 lapTime = (now.tv_sec - lap.tv_sec) + (now.tv_nsec - lap.tv_nsec) / 1E9;
320 laps.push_back(lapTime);
321 lap = now;
322 return lapTime;
323 }
324
326 {
327 clock_gettime(CLOCK_MONOTONIC, &now);
328 lapTime = (now.tv_sec - lap.tv_sec) + (now.tv_nsec - lap.tv_nsec) / 1E9;
329 return lapTime;
330 }
331
332 std::vector<double> laps;
334
335private:
336 struct timespec start, lap, now;
337 double elapsedTime, lapTime;
338};
339
341{
342 Percentage(int iterations) :
343 numIterations(iterations), currentIteration(0), currentPerc(0.0)
344 {
345 }
346
347 void operator()(void)
348 {
349 currentIteration++;
350 currentPerc = ((double) currentIteration * 100.0 / (double) numIterations);
351 std::cout << "\r" << std::setprecision(3) << "Progress: " << currentPerc << "% ";
352 }
353
354private:
355 int numIterations;
356 int currentIteration;
357 double currentPerc;
358};
359
360template<typename T>
361inline std::string toStringPointDecimal(T val)
362{
363 std::string s = std::to_string(val);
364 std::replace(s.begin(), s.end(), ',', '.');
365 return s;
366}
367
368/*
369 template<typename T>
370 inline std::string toStringPointDecimal(T val, const int precision = 0){
371 std::streamsize defaultPrecision = std::cout.precision();
372 if(precision != 0){
373 std::setprecision(static_cast<std::streamsize>(precision));
374 }
375 std::ostringstream oss;
376 oss << std::setprecision(precision) << val;
377 std::string s = oss.str();
378 std::replace(s.begin(), s.end(), ',', '.');
379 std::setprecision(defaultPrecision);
380 return s;
381 }
382 */
383template<typename T>
384void PrintArray(T arr, const int size, const char delimiter)
385{
386 for (int i = 0; i < size; ++i) {
387 std::cout << arr[i];
388 if (i < (size - 1)) {
389 std::cout << delimiter << " ";
390 }
391 }
392}
393
394template<typename T>
395void PrintCMATArray(T arr, const int size, const char delimiter)
396{
397 for (int i = 1; i <= size; ++i) {
398 std::cout << arr(i);
399 if (i < size) {
400 std::cout << delimiter << " ";
401 }
402 }
403}
404
405template<typename T>
406std::string ArrayToString(T arr, const int size, const char delimiter)//, const int precision = 0)
407{
408 std::string arrayText;
409 for (int i = 0; i < size; ++i) {
410 arrayText = arrayText + toStringPointDecimal(arr[i]);
411 if (i < (size - 1)) {
412 arrayText = arrayText + delimiter + " ";
413 }
414 }
415 return arrayText;
416}
417
418template<typename T>
419std::string CMATArrayToString(T arr, const int size, const char delimiter)
420{
421 std::string arrayText;
422 for (int i = 1; i <= size; ++i) {
423 arrayText = arrayText + toStringPointDecimal(arr(i));
424 if (i < size) {
425 arrayText = arrayText + delimiter + " ";
426 }
427 }
428 return arrayText;
429}
430
431template<typename T>
432void PrintSTLVector(T vecObj, const char delimiter, const std::string preText = "")
433{
434 std::cout << preText << " ";
435 for (typename T::iterator itr = vecObj.begin(); itr != vecObj.end(); ++itr) {
436 std::cout << *itr;
437 if (itr != (vecObj.end() - 1)) {
438 std::cout << delimiter << " ";
439 }
440 }
441}
442
443template<typename T>
444std::string STLVectorToString(T vecObj, const char delimiter, const std::string preText = "")
445{
446 std::string vectorText;
447 vectorText = preText + " ";
448 for (typename T::iterator itr = vecObj.begin(); itr != vecObj.end(); ++itr) {
449 vectorText = vectorText + toStringPointDecimal(*itr);
450 if (itr != (vecObj.end() - 1)) {
451 vectorText = vectorText + delimiter + " ";
452 }
453 }
454 return vectorText;
455}
456
457template<typename T>
458void PrintSTLVectOfVects(T vecObj, const char delimiter)
459{
460 for (typename T::iterator itr = vecObj.begin(); itr != vecObj.end(); ++itr) {
461 std::cout << "#" << itr - vecObj.begin() << ": ";
462 PrintSTLVector(*itr, delimiter);
463 std::cout << "\n";
464 }
465}
466
472inline std::string GetCurrentDateFormatted()
473{
474 std::time_t t = std::time(NULL);
475 char mbstr[20];
476 std::strftime(mbstr, sizeof(mbstr), "%Y-%m-%d_%H.%M.%S", std::localtime(&t));
477 std::string currentDate(mbstr);
478
479 return currentDate;
480}
481
482template<typename K, typename V>
483using MapIterator = typename std::map<K,V>::const_iterator;
484
485template<typename K, typename V>
486bool FindMapKeyByValue(const std::map<K, V> myMap, const V value, K &key)
487{
488 bool keyWasFound = false;
490 for (it = myMap.begin(); it != myMap.end(); ++it) {
491 if (it->second == value) {
492 key = it->first;
493 keyWasFound = true;
494 break;
495 }
496 }
497 return keyWasFound;
498}
499
501template<typename T>
502struct square
503{
504 T operator()(const T& Left, const T& Right) const
505 {
506 return (Left + Right * Right);
507 }
508};
509
510#if defined(__linux__) || defined(linux)
516inline std::string get_selfpath()
517{
518 char buff[2048];
519 ssize_t len = ::readlink("/proc/self/exe", buff, sizeof(buff) - 1);
520 if (len != -1) {
521 buff[len] = '\0';
522 std::string path(buff);
523 std::string::size_type t = path.find_last_of("/"); // Here we find the last "/"
524 path = path.substr(0, t); // and remove the rest (exe name)
525 return path;
526 } else {
527 printf("Cannot determine executable path! [Exiting]\n");
528 exit(-1);
529 }
530}
531
535inline std::string get_homepath()
536{
537 const char *homedir;
538
539 if ((homedir = getenv("HOME")) == NULL) {
540 homedir = getpwuid(getuid())->pw_dir;
541 }
542 return homedir;
543
544}
545
546inline bool does_file_exists(const std::string& name)
547{
548 struct stat buffer;
549 return (stat(name.c_str(), &buffer) == 0);
550}
551
552inline std::string exec(const char* cmd)
553{
554 std::array<char, 128> buffer;
555 std::string result;
556 std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
557 if (!pipe)
558 throw std::runtime_error("popen() failed!");
559 while (!feof(pipe.get())) {
560 if (fgets(buffer.data(), 128, pipe.get()) != NULL)
561 result += buffer.data();
562 }
563 return result;
564}
565
566inline void ParseIPString(const std::string input_Str, unsigned char ip[4])
567{
568 std::string ipString = input_Str, ip_chunk;
569 std::string::size_type t1;
570 for (int i = 0; i < 3; ++i) {
571 t1 = ipString.find_first_of(".");
572 ip_chunk = ipString.substr(0, t1);
573 ip[i] = static_cast<unsigned char>(stod(ip_chunk, &t1));
574 ipString = ipString.substr(t1 + 1, ipString.size());
575 }
576 ip[3] = static_cast<unsigned char>(stod(ipString, &t1));
577}
578
579inline void paddr(unsigned char *a)
580{
581 printf("%d.%d.%d.%d\n", a[0], a[1], a[2], a[3]);
582}
583
584class UDPSenderSocket
585{
586public:
587 UDPSenderSocket() :
588 sockfd(0)
589 {
590 slen = sizeof(si_server);
591 }
592
593 UDPSenderSocket(char ip[], char port[]) :
594 UDPSenderSocket()
595 {
596 Configure(ip, port);
597 }
598
599
600 void Configure(char ip[], char port[])
601 {
602 if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
603 perror("UPDSenderSocket - socket creation failed");
604 exit(1);
605 }
606
607 uint16_t serverPort = static_cast<uint16_t>(stod(std::string(port)));
608 ConfigureSenderSocket(si_server, ip, serverPort);
609 }
610
611 template<typename TP>
612 int Send(TP dataToSend, std::size_t dataSize)
613 {
614 return sendto(sockfd, dataToSend, dataSize, 0, (struct sockaddr *) &si_server, slen);
615
616 }
617
618private:
619 bool ConfigureSenderSocket(struct sockaddr_in &si_out, char *ip, uint16_t port)
620 {
621
622 // zero out the structure
623 memset((char *) &si_out, 0, sizeof(si_out));
624 si_out.sin_family = AF_INET;
625 si_out.sin_port = htons(port);
626
627 if (inet_aton(ip, &si_out.sin_addr) == 0) {
628 fprintf(stderr, "inet_aton() failed\n");
629 exit(1);
630 }
631
632 return true;
633 }
634
635 struct sockaddr_in si_server;
636 int sockfd;
637 socklen_t slen;
638};
639
640class UPDReceiverSocket
641{
642public:
643 UPDReceiverSocket() :
644 sockfd_(0)
645 {
646 slen_ = sizeof(si_client_);
647 }
648
649 UPDReceiverSocket(char port[], bool nonBlocking) :
650 UPDReceiverSocket()
651 {
652 Configure(port, nonBlocking);
653 }
654
655 void Configure(char port[], bool nonBlocking)
656 {
657 uint16_t port_ = static_cast<uint16_t>(stod(std::string(port)));
658 ConfigureReceiverSocket(sockfd_, si_client_, port_, nonBlocking);
659 }
660
661 template<typename TP>
662 int Receive(TP data, std::size_t dataSize)
663 {
664 return recvfrom(sockfd_, data, dataSize, 0, (struct sockaddr *) &si_client_, &slen_);
665
666 }
667
668private:
669 bool ConfigureReceiverSocket(int &sockfd, struct sockaddr_in &si_in, uint16_t port, bool nonBlocking)
670 {
674 if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
675 perror("socket");
676 exit(1);
677 }
678
679 // zero out the structure
680 memset((char *) &si_in, 0, sizeof(si_in));
681 si_in.sin_family = AF_INET;
682 si_in.sin_port = htons(port);
683 si_in.sin_addr.s_addr = htonl(INADDR_ANY);
684
685 //bind socket to port
686 if (bind(sockfd, (struct sockaddr*) &si_in, sizeof(si_in)) == -1) {
687 perror("bind error");
688 exit(1);
689 }
690
691 if (nonBlocking) {
692 // Put the socket in non-blocking mode:
693 if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL) | O_NONBLOCK) < 0) {
694 perror("Error in putting the socket in non blocking mode");
695 exit(1);
696 }
697 }
698
699 return true;
700 }
701
702 struct sockaddr_in si_client_;
703 int sockfd_;
704 socklen_t slen_; // = sizeof(si_tool);
705};
706
707#endif /* Linux functions*/
708
709 inline bool CopyFile(const std::string& inputFile, const std::string& outputFile)
710 {
711 bool ret(false);
712
713 if (does_file_exists(inputFile)) {
714 std::ifstream src(inputFile, std::ios::binary);
715 std::ofstream dst;
716 dst.open(outputFile, std::ios::binary);
717 chmod(outputFile.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
718 dst << src.rdbuf();
719 dst.close();
720 ret = true;
721 } else {
722 std::cout << "Error in FUTILS::CopyFile(), file='" << inputFile << "' does not exist!" << std::endl;
723 }
724
725 return ret;
726 }
727
742 {
743 std::vector<double> prevState_;
744 std::vector<double> filteredData_;
747 double alpha_;
748
750 {
751 Reset();
752 }
753
754 void Reset()
755 {
756 isRunning_ = false;
757 }
758
759 void Init(const int dataSize, const double alpha)
760 {
761 dataSize_ = dataSize;
762 prevState_.resize(dataSize);
763 filteredData_.resize(dataSize);
764 alpha_ = alpha;
765
766 initialised_ = true;
767 }
768
769 std::vector<double>& Filter(const std::vector<double> array)
770 {
771 // If the filter is not yet running we don't have any previous state so
772 // we use the current one as a pseudo-previous state.
773 if (initialised_) {
774 if (!isRunning_) {
775 for (int i = 0; i < dataSize_; ++i) {
776 prevState_.at(i) = array.at(i);
777 }
778 isRunning_ = true;
779 }
780
781 for (int i = 0; i < dataSize_; ++i) {
782 filteredData_.at(i) = alpha_ * array.at(i) + (1 - alpha_) * prevState_.at(i);
783 }
784 return filteredData_;
785 } else {
786 std::cout << "Error: FirstOrderFilter::Init(dataSize, alpha) was not called!\n" << "Exiting..."
787 << std::endl;
788 exit(EXIT_FAILURE);
789 }
790 }
791 };
792
793} /* namespace FUTILS */
794
795#endif /* FUTILS_H_ */
796
Definition futils.h:140
std::string toStringPointDecimal(T val)
Definition futils.h:361
void PrintSTLVector(T vecObj, const char delimiter, const std::string preText="")
Definition futils.h:432
void PrintSTLVectOfVects(T vecObj, const char delimiter)
Definition futils.h:458
void PrintCMATArray(T arr, const int size, const char delimiter)
Definition futils.h:395
bool CopyFile(const std::string &inputFile, const std::string &outputFile)
Definition futils.h:709
int MakeDir(const char *path)
Create folder if not existing.
Definition futils.h:154
std::string CMATArrayToString(T arr, const int size, const char delimiter)
Definition futils.h:419
typename std::map< K, V >::const_iterator MapIterator
Definition futils.h:483
std::string ArrayToString(T arr, const int size, const char delimiter)
Definition futils.h:406
std::string GetCurrentDateFormatted()
Definition futils.h:472
void PrettyPrint(const Object &A, std::string name, const char *color=tc::white)
Definition futils.h:143
void PrintArray(T arr, const int size, const char delimiter)
Definition futils.h:384
bool FindMapKeyByValue(const std::map< K, V > myMap, const V value, K &key)
Definition futils.h:486
std::string STLVectorToString(T vecObj, const char delimiter, const std::string preText="")
Definition futils.h:444
Definition futils.h:233
Dotter(int freq)
Definition futils.h:234
void operator()(void)
Definition futils.h:242
Definition futils.h:742
double alpha_
Definition futils.h:747
bool initialised_
Definition futils.h:745
bool isRunning_
Definition futils.h:745
std::vector< double > prevState_
Definition futils.h:743
FirstOrderFilter()
Definition futils.h:749
int dataSize_
Definition futils.h:746
void Reset()
Definition futils.h:754
void Init(const int dataSize, const double alpha)
Definition futils.h:759
std::vector< double > filteredData_
Definition futils.h:744
std::vector< double > & Filter(const std::vector< double > array)
Definition futils.h:769
Definition futils.h:341
void operator()(void)
Definition futils.h:347
Percentage(int iterations)
Definition futils.h:342
My first functor!!! :D.
Definition futils.h:188
Spinner(int frequency)
Definition futils.h:189
void operator()(void)
Definition futils.h:197
Definition futils.h:278
bool running
Definition futils.h:333
double GetCurrentLapTime()
Definition futils.h:325
Timer()
Definition futils.h:279
std::vector< double > laps
Definition futils.h:332
double Elapsed()
Definition futils.h:302
double Lap()
Definition futils.h:316
void Start()
Definition futils.h:286
void Stop()
Definition futils.h:293
Functor for getting sum of previous result and square of current element (inner product can be used i...
Definition futils.h:503
T operator()(const T &Left, const T &Right) const
Definition futils.h:504