odrive.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. #include "odrive.h"
  2. #include <stdio.h>
  3. const char* default_config =
  4. "w config.brake_resistance 0\n"
  5. "w config.dc_bus_undervoltage_trip_level 8\n"
  6. "w config.dc_bus_overvoltage_trip_level 34\n"
  7. "w config.dc_max_negative_current -5\n"
  8. "w config.max_regen_current 0\n"
  9. "w axis0.motor.config.pole_pairs 4\n"
  10. "w axis0.motor.config.calibration_current 5\n"
  11. "w axis0.motor.config.resistance_calib_max_voltage 4\n"
  12. "w axis0.motor.config.motor_type 0\n"
  13. "w axis0.motor.config.current_lim 5\n"
  14. "w axis0.motor.config.requested_current_range 20\n"
  15. "w axis0.encoder.config.mode 0\n"
  16. "w axis0.encoder.config.use_index 1\n"
  17. "w axis0.encoder.config.cpr 4000\n"
  18. "w axis0.controller.config.control_mode 3\n"
  19. "w axis0.controller.config.vel_limit 65536000\n"
  20. "w axis0.controller.config.pos_gain 20\n"
  21. "w axis0.motor_thermistor.config.poly_coefficient_0 551.8902587890625\n"
  22. "w axis0.motor_thermistor.config.poly_coefficient_1 -753.2103271484375\n"
  23. "w axis0.motor_thermistor.config.poly_coefficient_2 436.8048095703125\n"
  24. "w axis0.motor_thermistor.config.poly_coefficient_3 -42.3204460144043\n"
  25. "w axis0.motor_thermistor.config.temp_limit_lower 75\n"
  26. "w axis0.motor_thermistor.config.temp_limit_upper 90\n"
  27. "w axis0.motor_thermistor.config.enabled 1\n";
  28. ODrive::ODrive(Stream& serial_in) : serial(serial_in) {}
  29. void ODrive::setPosition(float position) { setPosition(position, 0.0f, 0.0f); }
  30. void ODrive::setPosition(float position, float velocity_feedforward) {
  31. setPosition(position, velocity_feedforward, 0.0f);
  32. }
  33. void ODrive::setPosition(float position, float velocity_feedforward,
  34. float current_feedforward) {
  35. serial.printf("p 0 %f %f %f\n", position, velocity_feedforward,
  36. current_feedforward);
  37. }
  38. void ODrive::setVelocity(float velocity) { setVelocity(velocity, 0.0f); }
  39. void ODrive::setVelocity(float velocity, float current_feedforward) {
  40. serial.printf("v 0 %f %f\n", velocity, current_feedforward);
  41. }
  42. void ODrive::setCurrent(float current) { serial.printf("c 0 %f\n", current); }
  43. void ODrive::setGain(float pos, float vel, float vel_integrator) {
  44. writeConfig("axis0.controller.config.pos_gain", pos);
  45. writeConfig("axis0.controller.config.vel_gain", vel);
  46. writeConfig("axis0.controller.config.vel_integrator_gain", vel_integrator);
  47. }
  48. void ODrive::setControlMode(int32_t mode) {
  49. writeConfig("axis0.controller.config.control_mode", mode);
  50. }
  51. void ODrive::setControlInputPos(float pos) {
  52. writeConfig("axis0.controller.input_pos", pos);
  53. }
  54. void ODrive::trapezoidalMove(float position) {
  55. serial.printf("t 0 %f\n", position);
  56. }
  57. bool ODrive::runState(int32_t requested_state, uint32_t timeout) {
  58. uint32_t time_start = millis();
  59. int32_t state = -1;
  60. writeConfig("axis0.requested_state", requested_state);
  61. state = readConfigInt("axis0.requested_state");
  62. while (state != requested_state && millis() - time_start < timeout) {
  63. delay(100);
  64. state = readConfigInt("axis0.requested_state");
  65. }
  66. return state == requested_state;
  67. }
  68. float ODrive::getVelocity() {
  69. return readConfigFloat("axis0.encoder.vel_estimate");
  70. }
  71. float ODrive::getVbusVoltage() { return readConfigFloat("vbus_voltage"); }
  72. float ODrive::getPhaseCurrent() {
  73. return readConfigFloat("axis0.motor.current_control.Iq_measured");
  74. }
  75. float ODrive::getBusCurrent() {
  76. return readConfigFloat("axis0.motor.current_control.Ibus");
  77. }
  78. int32_t ODrive::getEncoderShadowCount() {
  79. return readConfigInt("axis0.encoder.shadow_count");
  80. }
  81. float ODrive::getEncoderPosEstimate() {
  82. return readConfigInt("axis0.encoder.pos_estimate");
  83. }
  84. float ODrive::getMotorTemp() {
  85. return readConfigFloat("axis0.motor_thermistor.temperature");
  86. }
  87. void ODrive::eraseConfig() { writeToDeive("se\n"); }
  88. void ODrive::saveConfig() { writeToDeive("ss\n"); }
  89. void ODrive::reboot() { writeToDeive("sr\n"); }
  90. void ODrive::setDefaultConfig() {
  91. writeToDeive("\n");
  92. writeToDeive(default_config);
  93. saveConfig();
  94. }
  95. bool ODrive::checkError(int32_t* axis, int32_t* motor_thermistor,
  96. int32_t* encoder, int32_t* controller) {
  97. int32_t errors[4] = {0, 0, 0, 0};
  98. errors[0] = readConfigInt("axis0.error");
  99. errors[1] = readConfigInt("axis0.motor_thermistor.error");
  100. errors[2] = readConfigInt("axis0.encoder.error");
  101. errors[3] = readConfigInt("axis0.controller.error");
  102. if (axis) {
  103. *axis = errors[0];
  104. }
  105. if (motor_thermistor) {
  106. *motor_thermistor = errors[1];
  107. }
  108. if (encoder) {
  109. *encoder = errors[2];
  110. }
  111. if (controller) {
  112. *controller = errors[3];
  113. }
  114. if (errors[0] || errors[1] || errors[2] || errors[3]) {
  115. return true;
  116. }
  117. return false;
  118. }
  119. void ODrive::readFlush() {
  120. while (serial.available()) {
  121. serial.read();
  122. }
  123. }
  124. String ODrive::readString() {
  125. String str = "";
  126. unsigned long timeout_start = millis();
  127. for (;;) {
  128. while (!serial.available()) {
  129. if (millis() - timeout_start >= READ_TIMEOUT) {
  130. return str;
  131. }
  132. }
  133. char c = serial.read();
  134. if (c == '\n') {
  135. break;
  136. }
  137. str += c;
  138. }
  139. return str;
  140. }
  141. float ODrive::readFloat() { return readString().toFloat(); }
  142. int32_t ODrive::readInt() { return readString().toInt(); }
  143. void ODrive::writeToDeive(const char* data) {
  144. if (data == NULL) {
  145. return;
  146. }
  147. serial.write(data);
  148. }
  149. void ODrive::writeConfig(const char* config, float value) {
  150. char* out_string = NULL;
  151. int result = asprintf(&out_string, "w %s %f\n", config, value);
  152. if (result != -1) {
  153. writeToDeive(out_string);
  154. free(out_string);
  155. }
  156. }
  157. void ODrive::writeConfig(const char* config, int32_t value) {
  158. char* out_string = NULL;
  159. int result = asprintf(&out_string, "w %s %d\n", config, value);
  160. if (result != -1) {
  161. writeToDeive(out_string);
  162. free(out_string);
  163. }
  164. }
  165. int32_t ODrive::readConfigInt(const char* config) {
  166. char* out_string = NULL;
  167. int result = asprintf(&out_string, "r %s\n", config);
  168. if (result != -1) {
  169. readFlush();
  170. writeToDeive(out_string);
  171. free(out_string);
  172. }
  173. return readInt();
  174. }
  175. float ODrive::readConfigFloat(const char* config) {
  176. char* out_string = NULL;
  177. int result = asprintf(&out_string, "r %s\n", config);
  178. if (result != -1) {
  179. readFlush();
  180. writeToDeive(out_string);
  181. free(out_string);
  182. }
  183. return readFloat();
  184. }