/MoneyPit2/control/main.cpp

https://github.com/jwatte/robotcode · C++ · 191 lines · 153 code · 35 blank · 3 comment · 23 complexity · fd1da2f348abe3f4301e95a726a3b064 MD5 · raw file

  1. #include <stdio.h>
  2. #include <USBLink.h>
  3. #include <Settings.h>
  4. #include <util.h>
  5. #include <stdlib.h>
  6. #include <unistd.h>
  7. #include <sys/fcntl.h>
  8. #include <boost/shared_ptr.hpp>
  9. #include <boost/thread.hpp>
  10. #include <boost/lexical_cast.hpp>
  11. #include <UscServo.h>
  12. #include <FL/Fl.H>
  13. #include <FL/Fl_Window.H>
  14. #include <FL/Fl_Value_Slider.H>
  15. #include <FL/Fl_Button.H>
  16. #include <FL/Fl_Value_Output.H>
  17. #define CMD_BEEP (0x10 | 0x01) // cmd 1, sizeix 1
  18. #define CMD_MOTOR_SPEEDS (0x20 | 0x02) // cmd 2, sizeix 2
  19. //#define CMD_SERVO_TIMES (0x30 | 0x05) // cmd 3, sizeix 5
  20. //#define CMD_WRITE_SERVOS (0x30 | 0x00) // cmd 3, sizeix 0
  21. #define RET_CURRENT_VALUES (0x40 | 0x08 | 0x02) // ret 4, RET, sizeix 2
  22. #define RET_COUNTER_VALUES (0x50 | 0x08 | 0x05) // ret 5, RET, sizeix 5
  23. boost::shared_ptr<Module> usb_;
  24. boost::shared_ptr<boost::thread> usbThread_;
  25. unsigned char lastSeq_;
  26. unsigned char nextSeq_;
  27. UscServo * uscServo_;
  28. short servosteer[4] = { 0, 0, 0, 0 };
  29. unsigned short servocenters[4] = { 6000, 6000, 6000, 6000 };
  30. unsigned char motorpower[2] = { 0x80, 0x80 };
  31. unsigned char currents[2];
  32. unsigned short counters[4];
  33. Fl_Valuator * valueDisplay_[4];
  34. void setservo(int i, short steer) {
  35. uscServo_->steer(i, steer);
  36. }
  37. void setallservos() {
  38. for (int i = 0; i != 4; ++i) {
  39. setservo(i, servosteer[i]);
  40. }
  41. }
  42. void setpower(USBLink *link) {
  43. unsigned char buf[4] = {
  44. 0,
  45. CMD_MOTOR_SPEEDS,
  46. motorpower[0],
  47. motorpower[1]
  48. };
  49. link->raw_send(buf, 4);
  50. }
  51. void usb_thread_fn() {
  52. sched_param parm = { .sched_priority = 25 };
  53. if (pthread_setschedparam(pthread_self(), SCHED_RR, &parm) < 0) {
  54. std::string err(strerror(errno));
  55. std::cerr << "USBLink::thread_fn(): pthread_setschedparam(): " << err << std::endl;
  56. }
  57. USBLink *link = usb_->cast_as<USBLink>();
  58. double steer_time = read_clock();
  59. while (true) {
  60. link->step();
  61. while (true) {
  62. // drain receive queue
  63. size_t sz = 0;
  64. unsigned char const *ptr = link->begin_receive(sz);
  65. if (!ptr) {
  66. link->end_receive(0);
  67. break;
  68. }
  69. unsigned char const *end = ptr + sz;
  70. lastSeq_ = *ptr;
  71. ++ptr;
  72. while (ptr < end) {
  73. switch (*ptr) {
  74. case RET_CURRENT_VALUES:
  75. memcpy(currents, ptr+1, 2);
  76. ptr += 3;
  77. break;
  78. case RET_COUNTER_VALUES:
  79. memcpy(counters, ptr+1, 8);
  80. ptr += 9;
  81. for (int i = 0; i != 4; ++i) {
  82. valueDisplay_[i]->value(counters[i]);
  83. valueDisplay_[i]->redraw();
  84. }
  85. break;
  86. default:
  87. link->end_receive(sz);
  88. throw std::runtime_error("unknown command received from USB: "
  89. + hexnum(*ptr));
  90. }
  91. }
  92. link->end_receive(sz);
  93. }
  94. double now = read_clock();
  95. if (now - steer_time > 0.05) {
  96. setallservos();
  97. setpower(link);
  98. steer_time = now;
  99. }
  100. usleep(3000);
  101. }
  102. }
  103. void idle_func() {
  104. usleep(5000);
  105. }
  106. void slider_cb(Fl_Widget *vs, void *ii) {
  107. int i = (int)((size_t)ii & 0x3);
  108. double d = static_cast<Fl_Valuator *>(vs)->value();
  109. servosteer[i] = (short)d;
  110. setservo(i, servosteer[i]);
  111. }
  112. void speed_cb(Fl_Widget *vs, void *ii) {
  113. int i = (int)((size_t)ii & 0x3);
  114. double d = static_cast<Fl_Valuator *>(vs)->value();
  115. if (i == 0 || i == 3) {
  116. motorpower[0] = motorpower[1] = (unsigned char)(128 - d);
  117. }
  118. else if (i == 1) {
  119. motorpower[0] = (unsigned char)(d + 128);
  120. }
  121. else if (i == 2) {
  122. motorpower[1] = (unsigned char)(d + 128);
  123. }
  124. }
  125. void open_servos(boost::shared_ptr<Settings> const &set) {
  126. uscServo_ = new UscServo(0x1ffb, 0x0089, servocenters);
  127. }
  128. int main() {
  129. boost::shared_ptr<Settings> set(Settings::load("robot.json"));
  130. open_servos(set);
  131. usb_ = USBLink::open(set, boost::shared_ptr<Logger>());
  132. usbThread_ = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(usb_thread_fn)));
  133. Fl_Window *w = new Fl_Window(800, 500, "Control");
  134. for (int i = 0; i < 4; ++i) {
  135. Fl_Value_Slider *vs = new Fl_Value_Slider(10, 10+35*i, 300, 25);
  136. vs->type(FL_HORIZONTAL);
  137. vs->bounds(-1000, 1000);
  138. vs->value(0);
  139. vs->callback(slider_cb, (void *)(size_t)i);
  140. }
  141. Fl_Value_Slider *vs = new Fl_Value_Slider(350, 10, 30, 300);
  142. vs->type(FL_VERTICAL);
  143. vs->bounds(-127, 127);
  144. vs->value(0);
  145. vs->callback(speed_cb, (void *)0);
  146. for (int i = 0; i < 4; ++i) {
  147. Fl_Value_Output *vo = new Fl_Value_Output(400, 10+35*i, 100, 25);
  148. valueDisplay_[i] = vo;
  149. }
  150. w->end();
  151. w->show();
  152. Fl::set_idle(idle_func);
  153. Fl::run();
  154. delete uscServo_;
  155. return 0;
  156. }