/projects/robots/boston_dynamics/spot/controllers/spot_moving_demo/spot_moving_demo.c

https://github.com/cyberbotics/webots · C · 172 lines · 120 code · 26 blank · 26 comment · 10 complexity · fe6438e3a0757502c83af583425ec8d3 MD5 · raw file

  1. /*
  2. * Copyright 1996-2020 Cyberbotics Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /*
  17. * Description: Simple controller to present the Spot robot.
  18. */
  19. #include <webots/camera.h>
  20. #include <webots/device.h>
  21. #include <webots/led.h>
  22. #include <webots/motor.h>
  23. #include <webots/robot.h>
  24. #include <math.h>
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #define NUMBER_OF_LEDS 8
  28. #define NUMBER_OF_JOINTS 12
  29. #define NUMBER_OF_CAMERAS 5
  30. // Initialize the robot's information
  31. static WbDeviceTag motors[NUMBER_OF_JOINTS];
  32. static const char *motor_names[NUMBER_OF_JOINTS] = {
  33. "front left shoulder abduction motor", "front left shoulder rotation motor", "front left elbow motor",
  34. "front right shoulder abduction motor", "front right shoulder rotation motor", "front right elbow motor",
  35. "rear left shoulder abduction motor", "rear left shoulder rotation motor", "rear left elbow motor",
  36. "rear right shoulder abduction motor", "rear right shoulder rotation motor", "rear right elbow motor"};
  37. static WbDeviceTag cameras[NUMBER_OF_CAMERAS];
  38. static const char *camera_names[NUMBER_OF_CAMERAS] = {"left head camera", "right head camera", "left flank camera",
  39. "right flank camera", "rear camera"};
  40. static WbDeviceTag leds[NUMBER_OF_LEDS];
  41. static const char *led_names[NUMBER_OF_LEDS] = {"left top led", "left middle up led", "left middle down led",
  42. "left bottom led", "right top led", "right middle up led",
  43. "right middle down led", "right bottom led"};
  44. static void step() {
  45. const double time_step = wb_robot_get_basic_time_step();
  46. if (wb_robot_step(time_step) == -1) {
  47. wb_robot_cleanup();
  48. exit(0);
  49. }
  50. }
  51. // Movement decomposition
  52. static void movement_decomposition(const double *target, double duration) {
  53. const double time_step = wb_robot_get_basic_time_step();
  54. const int n_steps_to_achieve_target = duration * 1000 / time_step;
  55. double step_difference[NUMBER_OF_JOINTS];
  56. double current_position[NUMBER_OF_JOINTS];
  57. for (int i = 0; i < NUMBER_OF_JOINTS; ++i) {
  58. current_position[i] = wb_motor_get_target_position(motors[i]);
  59. step_difference[i] = (target[i] - current_position[i]) / n_steps_to_achieve_target;
  60. }
  61. for (int i = 0; i < n_steps_to_achieve_target; ++i) {
  62. for (int j = 0; j < NUMBER_OF_JOINTS; ++j) {
  63. current_position[j] += step_difference[j];
  64. wb_motor_set_position(motors[j], current_position[j]);
  65. }
  66. step();
  67. }
  68. }
  69. static void lie_down(double duration) {
  70. const double motors_target_pos[NUMBER_OF_JOINTS] = {-0.40, -0.99, 1.59, // Front left leg
  71. 0.40, -0.99, 1.59, // Front right leg
  72. -0.40, -0.99, 1.59, // Rear left leg
  73. 0.40, -0.99, 1.59}; // Rear right leg
  74. movement_decomposition(motors_target_pos, duration);
  75. }
  76. static void stand_up(double duration) {
  77. const double motors_target_pos[NUMBER_OF_JOINTS] = {-0.1, 0.0, 0.0, // Front left leg
  78. 0.1, 0.0, 0.0, // Front right leg
  79. -0.1, 0.0, 0.0, // Rear left leg
  80. 0.1, 0.0, 0.0}; // Rear right leg
  81. movement_decomposition(motors_target_pos, duration);
  82. }
  83. static void sit_down(double duration) {
  84. const double motors_target_pos[NUMBER_OF_JOINTS] = {-0.20, -0.40, -0.19, // Front left leg
  85. 0.20, -0.40, -0.19, // Front right leg
  86. -0.40, -0.90, 1.18, // Rear left leg
  87. 0.40, -0.90, 1.18}; // Rear right leg
  88. movement_decomposition(motors_target_pos, duration);
  89. }
  90. static void give_paw() {
  91. // Stabilize posture
  92. const double motors_target_pos_1[NUMBER_OF_JOINTS] = {-0.20, -0.30, 0.05, // Front left leg
  93. 0.20, -0.40, -0.19, // Front right leg
  94. -0.40, -0.90, 1.18, // Rear left leg
  95. 0.49, -0.90, 0.80}; // Rear right leg
  96. movement_decomposition(motors_target_pos_1, 4);
  97. const double initial_time = wb_robot_get_time();
  98. while (wb_robot_get_time() - initial_time < 8) {
  99. wb_motor_set_position(motors[4], 0.2 * sin(2 * wb_robot_get_time()) + 0.6); // Upperarm movement
  100. wb_motor_set_position(motors[5], 0.4 * sin(2 * wb_robot_get_time())); // Forearm movement
  101. step();
  102. }
  103. // Get back in sitting posture
  104. const double motors_target_pos_2[NUMBER_OF_JOINTS] = {-0.20, -0.40, -0.19, // Front left leg
  105. 0.20, -0.40, -0.19, // Front right leg
  106. -0.40, -0.90, 1.18, // Rear left leg
  107. 0.40, -0.90, 1.18}; // Rear right leg
  108. movement_decomposition(motors_target_pos_2, 4);
  109. }
  110. int main(int argc, char **argv) {
  111. wb_robot_init();
  112. const double time_step = wb_robot_get_basic_time_step();
  113. // Get cameras
  114. for (int i = 0; i < NUMBER_OF_CAMERAS; ++i)
  115. cameras[i] = wb_robot_get_device(camera_names[i]);
  116. // enable the two front cameras
  117. wb_camera_enable(cameras[0], 2 * time_step);
  118. wb_camera_enable(cameras[1], 2 * time_step);
  119. // Get the LEDs and turn them on
  120. for (int i = 0; i < NUMBER_OF_LEDS; ++i) {
  121. leds[i] = wb_robot_get_device(led_names[i]);
  122. wb_led_set(leds[i], 1);
  123. }
  124. // Get the motors (joints) and set initial target position to 0
  125. for (int i = 0; i < NUMBER_OF_JOINTS; ++i)
  126. motors[i] = wb_robot_get_device(motor_names[i]);
  127. while (true) {
  128. lie_down(4.0);
  129. stand_up(4.0);
  130. sit_down(4.0);
  131. give_paw();
  132. stand_up(4.0);
  133. lie_down(3.0);
  134. stand_up(3.0);
  135. lie_down(2.0);
  136. stand_up(2.0);
  137. lie_down(1.0);
  138. stand_up(1.0);
  139. lie_down(0.75);
  140. stand_up(0.75);
  141. lie_down(0.5);
  142. stand_up(0.5);
  143. }
  144. wb_robot_cleanup();
  145. return EXIT_FAILURE;
  146. }