Newer
Older
orange2022 / src / turtlebot3 / turtlebot3_teleop / nodes / turtlebot3_teleop_key
@koki koki on 20 Sep 2022 6 KB update
  1. #!/usr/bin/env python
  2.  
  3. # Copyright (c) 2011, Willow Garage, Inc.
  4. # All rights reserved.
  5. #
  6. # Redistribution and use in source and binary forms, with or without
  7. # modification, are permitted provided that the following conditions are met:
  8. #
  9. # * Redistributions of source code must retain the above copyright
  10. # notice, this list of conditions and the following disclaimer.
  11. # * Redistributions in binary form must reproduce the above copyright
  12. # notice, this list of conditions and the following disclaimer in the
  13. # documentation and/or other materials provided with the distribution.
  14. # * Neither the name of the Willow Garage, Inc. nor the names of its
  15. # contributors may be used to endorse or promote products derived from
  16. # this software without specific prior written permission.
  17. #
  18. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  19. # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21. # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  22. # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  23. # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  24. # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  25. # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  26. # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  27. # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  28. # POSSIBILITY OF SUCH DAMAGE.
  29.  
  30. import rospy
  31. from geometry_msgs.msg import Twist
  32. import sys, select, os
  33. if os.name == 'nt':
  34. import msvcrt, time
  35. else:
  36. import tty, termios
  37.  
  38. BURGER_MAX_LIN_VEL = 1.6
  39. BURGER_MAX_ANG_VEL = 2.84
  40.  
  41. WAFFLE_MAX_LIN_VEL = 0.26
  42. WAFFLE_MAX_ANG_VEL = 1.82
  43.  
  44. LIN_VEL_STEP_SIZE = 0.1
  45. ANG_VEL_STEP_SIZE = 0.1
  46.  
  47. msg = """
  48. Control Your TurtleBot3!
  49. ---------------------------
  50. Moving around:
  51. w
  52. a s d
  53. x
  54.  
  55. w/x : increase/decrease linear velocity (Burger : ~ 0.22, Waffle and Waffle Pi : ~ 0.26)
  56. a/d : increase/decrease angular velocity (Burger : ~ 2.84, Waffle and Waffle Pi : ~ 1.82)
  57.  
  58. space key, s : force stop
  59.  
  60. CTRL-C to quit
  61. """
  62.  
  63. e = """
  64. Communications Failed
  65. """
  66.  
  67. def getKey():
  68. if os.name == 'nt':
  69. timeout = 0.1
  70. startTime = time.time()
  71. while(1):
  72. if msvcrt.kbhit():
  73. if sys.version_info[0] >= 3:
  74. return msvcrt.getch().decode()
  75. else:
  76. return msvcrt.getch()
  77. elif time.time() - startTime > timeout:
  78. return ''
  79.  
  80. tty.setraw(sys.stdin.fileno())
  81. rlist, _, _ = select.select([sys.stdin], [], [], 0.1)
  82. if rlist:
  83. key = sys.stdin.read(1)
  84. else:
  85. key = ''
  86.  
  87. termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
  88. return key
  89.  
  90. def vels(target_linear_vel, target_angular_vel):
  91. return "currently:\tlinear vel %s\t angular vel %s " % (target_linear_vel,target_angular_vel)
  92.  
  93. def makeSimpleProfile(output, input, slop):
  94. if input > output:
  95. output = min( input, output + slop )
  96. elif input < output:
  97. output = max( input, output - slop )
  98. else:
  99. output = input
  100.  
  101. return output
  102.  
  103. def constrain(input, low, high):
  104. if input < low:
  105. input = low
  106. elif input > high:
  107. input = high
  108. else:
  109. input = input
  110.  
  111. return input
  112.  
  113. def checkLinearLimitVelocity(vel):
  114. if turtlebot3_model == "burger":
  115. vel = constrain(vel, -BURGER_MAX_LIN_VEL, BURGER_MAX_LIN_VEL)
  116. elif turtlebot3_model == "waffle" or turtlebot3_model == "waffle_pi":
  117. vel = constrain(vel, -WAFFLE_MAX_LIN_VEL, WAFFLE_MAX_LIN_VEL)
  118. else:
  119. vel = constrain(vel, -BURGER_MAX_LIN_VEL, BURGER_MAX_LIN_VEL)
  120.  
  121. return vel
  122.  
  123. def checkAngularLimitVelocity(vel):
  124. if turtlebot3_model == "burger":
  125. vel = constrain(vel, -BURGER_MAX_ANG_VEL, BURGER_MAX_ANG_VEL)
  126. elif turtlebot3_model == "waffle" or turtlebot3_model == "waffle_pi":
  127. vel = constrain(vel, -WAFFLE_MAX_ANG_VEL, WAFFLE_MAX_ANG_VEL)
  128. else:
  129. vel = constrain(vel, -BURGER_MAX_ANG_VEL, BURGER_MAX_ANG_VEL)
  130.  
  131. return vel
  132.  
  133. if __name__=="__main__":
  134. if os.name != 'nt':
  135. settings = termios.tcgetattr(sys.stdin)
  136.  
  137. rospy.init_node('turtlebot3_teleop')
  138. pub = rospy.Publisher('cmd_vel', Twist, queue_size=10)
  139.  
  140. turtlebot3_model = rospy.get_param("model", "burger")
  141.  
  142. status = 0
  143. target_linear_vel = 0.0
  144. target_angular_vel = 0.0
  145. control_linear_vel = 0.0
  146. control_angular_vel = 0.0
  147.  
  148. try:
  149. print(msg)
  150. while not rospy.is_shutdown():
  151. key = getKey()
  152. if key == 'w' :
  153. target_linear_vel = checkLinearLimitVelocity(target_linear_vel + LIN_VEL_STEP_SIZE)
  154. status = status + 1
  155. print(vels(target_linear_vel,target_angular_vel))
  156. elif key == 'x' :
  157. target_linear_vel = checkLinearLimitVelocity(target_linear_vel - LIN_VEL_STEP_SIZE)
  158. status = status + 1
  159. print(vels(target_linear_vel,target_angular_vel))
  160. elif key == 'a' :
  161. target_angular_vel = checkAngularLimitVelocity(target_angular_vel + ANG_VEL_STEP_SIZE)
  162. status = status + 1
  163. print(vels(target_linear_vel,target_angular_vel))
  164. elif key == 'd' :
  165. target_angular_vel = checkAngularLimitVelocity(target_angular_vel - ANG_VEL_STEP_SIZE)
  166. status = status + 1
  167. print(vels(target_linear_vel,target_angular_vel))
  168. elif key == ' ' or key == 's' :
  169. target_linear_vel = 0.0
  170. control_linear_vel = 0.0
  171. target_angular_vel = 0.0
  172. control_angular_vel = 0.0
  173. print(vels(target_linear_vel, target_angular_vel))
  174. else:
  175. if (key == '\x03'):
  176. break
  177.  
  178. if status == 20 :
  179. print(msg)
  180. status = 0
  181.  
  182. twist = Twist()
  183.  
  184. control_linear_vel = makeSimpleProfile(control_linear_vel, target_linear_vel, (LIN_VEL_STEP_SIZE/2.0))
  185. twist.linear.x = control_linear_vel; twist.linear.y = 0.0; twist.linear.z = 0.0
  186.  
  187. control_angular_vel = makeSimpleProfile(control_angular_vel, target_angular_vel, (ANG_VEL_STEP_SIZE/2.0))
  188. twist.angular.x = 0.0; twist.angular.y = 0.0; twist.angular.z = control_angular_vel
  189.  
  190. pub.publish(twist)
  191.  
  192. except:
  193. print(e)
  194.  
  195. finally:
  196. twist = Twist()
  197. twist.linear.x = 0.0; twist.linear.y = 0.0; twist.linear.z = 0.0
  198. twist.angular.x = 0.0; twist.angular.y = 0.0; twist.angular.z = 0.0
  199. pub.publish(twist)
  200.  
  201. if os.name != 'nt':
  202. termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)