/projects/robots/kuka/youbot/libraries/youbot_control/src/arm.c

https://github.com/cyberbotics/webots · C · 203 lines · 163 code · 22 blank · 18 comment · 7 complexity · 3a2bd2b969524571a9752343b0984554 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: Implement the functions defined in arm.h
  18. */
  19. #include "arm.h"
  20. #include <webots/motor.h>
  21. #include <webots/robot.h>
  22. #include <math.h>
  23. #include <stdio.h>
  24. static WbDeviceTag arm_elements[5];
  25. static enum Height current_height = ARM_RESET;
  26. static enum Orientation current_orientation = ARM_FRONT;
  27. void arm_init() {
  28. arm_elements[ARM1] = wb_robot_get_device("arm1");
  29. arm_elements[ARM2] = wb_robot_get_device("arm2");
  30. arm_elements[ARM3] = wb_robot_get_device("arm3");
  31. arm_elements[ARM4] = wb_robot_get_device("arm4");
  32. arm_elements[ARM5] = wb_robot_get_device("arm5");
  33. wb_motor_set_velocity(arm_elements[ARM2], 0.5);
  34. arm_set_height(ARM_RESET);
  35. arm_set_orientation(ARM_FRONT);
  36. }
  37. void arm_reset() {
  38. wb_motor_set_position(arm_elements[ARM1], 0.0);
  39. wb_motor_set_position(arm_elements[ARM2], 1.57);
  40. wb_motor_set_position(arm_elements[ARM3], -2.635);
  41. wb_motor_set_position(arm_elements[ARM4], 1.78);
  42. wb_motor_set_position(arm_elements[ARM5], 0.0);
  43. }
  44. void arm_set_height(enum Height height) {
  45. switch (height) {
  46. case ARM_FRONT_FLOOR:
  47. wb_motor_set_position(arm_elements[ARM2], -0.97);
  48. wb_motor_set_position(arm_elements[ARM3], -1.55);
  49. wb_motor_set_position(arm_elements[ARM4], -0.61);
  50. wb_motor_set_position(arm_elements[ARM5], 0.0);
  51. break;
  52. case ARM_FRONT_PLATE:
  53. wb_motor_set_position(arm_elements[ARM2], -0.62);
  54. wb_motor_set_position(arm_elements[ARM3], -0.98);
  55. wb_motor_set_position(arm_elements[ARM4], -1.53);
  56. wb_motor_set_position(arm_elements[ARM5], 0.0);
  57. break;
  58. case ARM_FRONT_CARDBOARD_BOX:
  59. wb_motor_set_position(arm_elements[ARM2], 0.0);
  60. wb_motor_set_position(arm_elements[ARM3], -0.77);
  61. wb_motor_set_position(arm_elements[ARM4], -1.21);
  62. wb_motor_set_position(arm_elements[ARM5], 0.0);
  63. break;
  64. case ARM_RESET:
  65. wb_motor_set_position(arm_elements[ARM2], 1.57);
  66. wb_motor_set_position(arm_elements[ARM3], -2.635);
  67. wb_motor_set_position(arm_elements[ARM4], 1.78);
  68. wb_motor_set_position(arm_elements[ARM5], 0.0);
  69. break;
  70. case ARM_BACK_PLATE_HIGH:
  71. wb_motor_set_position(arm_elements[ARM2], 0.678);
  72. wb_motor_set_position(arm_elements[ARM3], 0.682);
  73. wb_motor_set_position(arm_elements[ARM4], 1.74);
  74. wb_motor_set_position(arm_elements[ARM5], 0.0);
  75. break;
  76. case ARM_BACK_PLATE_LOW:
  77. wb_motor_set_position(arm_elements[ARM2], 0.92);
  78. wb_motor_set_position(arm_elements[ARM3], 0.42);
  79. wb_motor_set_position(arm_elements[ARM4], 1.78);
  80. wb_motor_set_position(arm_elements[ARM5], 0.0);
  81. break;
  82. case ARM_HANOI_PREPARE:
  83. wb_motor_set_position(arm_elements[ARM2], -0.4);
  84. wb_motor_set_position(arm_elements[ARM3], -1.2);
  85. wb_motor_set_position(arm_elements[ARM4], -M_PI_2);
  86. wb_motor_set_position(arm_elements[ARM5], M_PI_2);
  87. break;
  88. default:
  89. fprintf(stderr, "arm_height() called with a wrong argument\n");
  90. return;
  91. }
  92. current_height = height;
  93. }
  94. void arm_set_orientation(enum Orientation orientation) {
  95. switch (orientation) {
  96. case ARM_BACK_LEFT:
  97. wb_motor_set_position(arm_elements[ARM1], -2.949);
  98. break;
  99. case ARM_LEFT:
  100. wb_motor_set_position(arm_elements[ARM1], -M_PI_2);
  101. break;
  102. case ARM_FRONT_LEFT:
  103. wb_motor_set_position(arm_elements[ARM1], -0.2);
  104. break;
  105. case ARM_FRONT:
  106. wb_motor_set_position(arm_elements[ARM1], 0.0);
  107. break;
  108. case ARM_FRONT_RIGHT:
  109. wb_motor_set_position(arm_elements[ARM1], 0.2);
  110. break;
  111. case ARM_RIGHT:
  112. wb_motor_set_position(arm_elements[ARM1], M_PI_2);
  113. break;
  114. case ARM_BACK_RIGHT:
  115. wb_motor_set_position(arm_elements[ARM1], 2.949);
  116. break;
  117. default:
  118. fprintf(stderr, "arm_set_side() called with a wrong argument\n");
  119. return;
  120. }
  121. current_orientation = orientation;
  122. }
  123. void arm_increase_height() {
  124. current_height++;
  125. if (current_height >= ARM_MAX_HEIGHT)
  126. current_height = ARM_MAX_HEIGHT - 1;
  127. arm_set_height(current_height);
  128. }
  129. void arm_decrease_height() {
  130. current_height--;
  131. if ((int)current_height < 0)
  132. current_height = 0;
  133. arm_set_height(current_height);
  134. }
  135. void arm_increase_orientation() {
  136. current_orientation++;
  137. if (current_orientation >= ARM_MAX_SIDE)
  138. current_orientation = ARM_MAX_SIDE - 1;
  139. arm_set_orientation(current_orientation);
  140. }
  141. void arm_decrease_orientation() {
  142. current_orientation--;
  143. if ((int)current_orientation < 0)
  144. current_orientation = 0;
  145. arm_set_orientation(current_orientation);
  146. }
  147. void arm_set_sub_arm_rotation(enum Arm arm, double radian) {
  148. wb_motor_set_position(arm_elements[arm], radian);
  149. }
  150. double arm_get_sub_arm_length(enum Arm arm) {
  151. switch (arm) {
  152. case ARM1:
  153. return 0.253;
  154. case ARM2:
  155. return 0.155;
  156. case ARM3:
  157. return 0.135;
  158. case ARM4:
  159. return 0.081;
  160. case ARM5:
  161. return 0.105;
  162. }
  163. return 0.0;
  164. }
  165. void arm_ik(double x, double y, double z) {
  166. double x1 = sqrt(x * x + z * z);
  167. double y1 = y + arm_get_sub_arm_length(ARM4) + arm_get_sub_arm_length(ARM5) - arm_get_sub_arm_length(ARM1);
  168. double a = arm_get_sub_arm_length(ARM2);
  169. double b = arm_get_sub_arm_length(ARM3);
  170. double c = sqrt(x1 * x1 + y1 * y1);
  171. double alpha = -asin(z / x1);
  172. double beta = -(M_PI_2 - acos((a * a + c * c - b * b) / (2.0 * a * c)) - atan(y1 / x1));
  173. double gamma = -(M_PI - acos((a * a + b * b - c * c) / (2.0 * a * b)));
  174. double delta = -(M_PI + (beta + gamma));
  175. double epsilon = M_PI_2 + alpha;
  176. wb_motor_set_position(arm_elements[ARM1], alpha);
  177. wb_motor_set_position(arm_elements[ARM2], beta);
  178. wb_motor_set_position(arm_elements[ARM3], gamma);
  179. wb_motor_set_position(arm_elements[ARM4], delta);
  180. wb_motor_set_position(arm_elements[ARM5], epsilon);
  181. }