wheel.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*
  2. * Copyright (c) 2019, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2019-07-17 Wu Han The first version
  9. */
  10. #include "wheel.h"
  11. #define DBG_SECTION_NAME "wheel"
  12. #define DBG_LEVEL DBG_LOG
  13. #include <rtdbg.h>
  14. wheel_t wheel_create(motor_t w_motor, encoder_t w_encoder, controller_t w_controller, float radius, rt_uint16_t gear_ratio)
  15. {
  16. //radius must not be zero, protect:
  17. if(radius == 0.0f)
  18. {
  19. return RT_NULL;
  20. }
  21. // 1. Malloc memory for wheel
  22. wheel_t new_wheel = (wheel_t) rt_malloc(sizeof(struct wheel));
  23. if(new_wheel == RT_NULL)
  24. {
  25. LOG_E("Falied to allocate memory for new wheel");
  26. return RT_NULL;
  27. }
  28. // 2. Initialize wheel
  29. new_wheel -> w_motor = w_motor;
  30. new_wheel -> w_encoder = w_encoder;
  31. new_wheel -> w_controller = w_controller;
  32. new_wheel -> radius = radius;
  33. new_wheel -> gear_ratio = gear_ratio;
  34. // 3. pre compute the speed to rpm transform ;)
  35. new_wheel -> speed_to_rpm = 1.0f / (radius * 2.0f * 60.0f * PI);
  36. return new_wheel;
  37. }
  38. rt_err_t wheel_destroy(wheel_t whl)
  39. {
  40. RT_ASSERT(whl != RT_NULL);
  41. LOG_D("Free wheel");
  42. motor_destroy(whl->w_motor);
  43. encoder_destroy(whl->w_encoder);
  44. controller_destroy(whl->w_controller);
  45. rt_free(whl);
  46. return RT_EOK;
  47. }
  48. rt_err_t wheel_enable(wheel_t whl)
  49. {
  50. RT_ASSERT(whl != RT_NULL);
  51. LOG_D("Enabling wheel");
  52. // Enable PWM for motor
  53. motor_enable(whl->w_motor);
  54. // Enable Encoder's interrupt
  55. encoder_enable(whl->w_encoder);
  56. // Enable control
  57. controller_enable(whl->w_controller);
  58. return RT_EOK;
  59. }
  60. rt_err_t wheel_disable(wheel_t whl)
  61. {
  62. RT_ASSERT(whl != RT_NULL);
  63. LOG_D("Disabling wheel");
  64. // Disable PWM for motor
  65. motor_disable(whl->w_motor);
  66. // Disable Encoder's interrupt
  67. encoder_disable(whl->w_encoder);
  68. // Disable control
  69. controller_disable(whl->w_controller);
  70. return RT_EOK;
  71. }
  72. rt_err_t wheel_reset(wheel_t whl)
  73. {
  74. RT_ASSERT(whl != RT_NULL);
  75. // Reset Controller
  76. controller_reset(whl->w_controller);
  77. // Reset Motor
  78. motor_reset(whl->w_motor);
  79. // Reset Encoder
  80. encoder_reset(whl->w_encoder);
  81. return RT_EOK;
  82. }
  83. /** speed = rpm x 60 x 2 x PI x radius **/
  84. /** so : rpm = speed x 1.0f / (radius x 60 x 2 x PT) */
  85. /** then : rpm = speed * speed_to_rpm_transform --> precomputed */
  86. rt_err_t wheel_set_speed(wheel_t whl, float speed)
  87. {
  88. RT_ASSERT(whl != RT_NULL);
  89. return wheel_set_rpm(whl, (rt_int16_t) (speed * whl->speed_to_rpm));
  90. }
  91. rt_err_t wheel_set_rpm(wheel_t whl, rt_int16_t rpm)
  92. {
  93. RT_ASSERT(whl != RT_NULL);
  94. controller_set_target(whl->w_controller, rpm);
  95. if(whl->w_controller->target == rpm)
  96. {
  97. return RT_EOK;
  98. }
  99. else
  100. {
  101. return RT_ERROR;
  102. }
  103. }
  104. void wheel_update(wheel_t whl)
  105. {
  106. RT_ASSERT(whl != RT_NULL);
  107. // Get current rpm
  108. whl->rpm = encoder_measure_rpm(whl->w_encoder);
  109. // Automatic control calculation
  110. controller_update(whl->w_controller, whl->rpm);
  111. // Set speed
  112. motor_run(whl->w_motor, whl->w_controller->output);
  113. }
  114. void wheel_stop(wheel_t whl)
  115. {
  116. RT_ASSERT(whl != RT_NULL);
  117. motor_stop(whl->w_motor);
  118. }