├── .gitignore
├── CMakeLists.txt
├── LICENSE
├── README.md
├── bittle_teleop_robot.launch
├── bittle_teleop_server.launch
├── package.xml
├── scripts
└── bittle_driver.py
└── test_bittle.launch
/.gitignore:
--------------------------------------------------------------------------------
1 | devel/
2 | logs/
3 | build/
4 | bin/
5 | lib/
6 | msg_gen/
7 | srv_gen/
8 | msg/*Action.msg
9 | msg/*ActionFeedback.msg
10 | msg/*ActionGoal.msg
11 | msg/*ActionResult.msg
12 | msg/*Feedback.msg
13 | msg/*Goal.msg
14 | msg/*Result.msg
15 | msg/_*.py
16 | build_isolated/
17 | devel_isolated/
18 |
19 | # Generated by dynamic reconfigure
20 | *.cfgc
21 | /cfg/cpp/
22 | /cfg/*.py
23 |
24 | # Ignore generated docs
25 | *.dox
26 | *.wikidoc
27 |
28 | # eclipse stuff
29 | .project
30 | .cproject
31 |
32 | # qcreator stuff
33 | CMakeLists.txt.user
34 |
35 | srv/_*.py
36 | *.pcd
37 | *.pyc
38 | qtcreator-*
39 | *.user
40 |
41 | /planning/cfg
42 | /planning/docs
43 | /planning/src
44 |
45 | *~
46 |
47 | # Emacs
48 | .#*
49 |
50 | # Catkin custom files
51 | CATKIN_IGNORE
52 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.0.2)
2 | project(bittle_driver)
3 |
4 | ## Compile as C++11, supported in ROS Kinetic and newer
5 | # add_compile_options(-std=c++11)
6 |
7 | ## Find catkin macros and libraries
8 | ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
9 | ## is used, also find other catkin packages
10 | find_package(catkin REQUIRED COMPONENTS
11 | rospy
12 | std_msgs
13 | )
14 |
15 | ## System dependencies are found with CMake's conventions
16 | # find_package(Boost REQUIRED COMPONENTS system)
17 |
18 |
19 | ## Uncomment this if the package has a setup.py. This macro ensures
20 | ## modules and global scripts declared therein get installed
21 | ## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
22 | # catkin_python_setup()
23 |
24 | ################################################
25 | ## Declare ROS messages, services and actions ##
26 | ################################################
27 |
28 | ## To declare and build messages, services or actions from within this
29 | ## package, follow these steps:
30 | ## * Let MSG_DEP_SET be the set of packages whose message types you use in
31 | ## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
32 | ## * In the file package.xml:
33 | ## * add a build_depend tag for "message_generation"
34 | ## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET
35 | ## * If MSG_DEP_SET isn't empty the following dependency has been pulled in
36 | ## but can be declared for certainty nonetheless:
37 | ## * add a exec_depend tag for "message_runtime"
38 | ## * In this file (CMakeLists.txt):
39 | ## * add "message_generation" and every package in MSG_DEP_SET to
40 | ## find_package(catkin REQUIRED COMPONENTS ...)
41 | ## * add "message_runtime" and every package in MSG_DEP_SET to
42 | ## catkin_package(CATKIN_DEPENDS ...)
43 | ## * uncomment the add_*_files sections below as needed
44 | ## and list every .msg/.srv/.action file to be processed
45 | ## * uncomment the generate_messages entry below
46 | ## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
47 |
48 | ## Generate messages in the 'msg' folder
49 | # add_message_files(
50 | # FILES
51 | # Message1.msg
52 | # Message2.msg
53 | # )
54 |
55 | ## Generate services in the 'srv' folder
56 | # add_service_files(
57 | # FILES
58 | # Service1.srv
59 | # Service2.srv
60 | # )
61 |
62 | ## Generate actions in the 'action' folder
63 | # add_action_files(
64 | # FILES
65 | # Action1.action
66 | # Action2.action
67 | # )
68 |
69 | ## Generate added messages and services with any dependencies listed here
70 | # generate_messages(
71 | # DEPENDENCIES
72 | # std_msgs
73 | # )
74 |
75 | ################################################
76 | ## Declare ROS dynamic reconfigure parameters ##
77 | ################################################
78 |
79 | ## To declare and build dynamic reconfigure parameters within this
80 | ## package, follow these steps:
81 | ## * In the file package.xml:
82 | ## * add a build_depend and a exec_depend tag for "dynamic_reconfigure"
83 | ## * In this file (CMakeLists.txt):
84 | ## * add "dynamic_reconfigure" to
85 | ## find_package(catkin REQUIRED COMPONENTS ...)
86 | ## * uncomment the "generate_dynamic_reconfigure_options" section below
87 | ## and list every .cfg file to be processed
88 |
89 | ## Generate dynamic reconfigure parameters in the 'cfg' folder
90 | # generate_dynamic_reconfigure_options(
91 | # cfg/DynReconf1.cfg
92 | # cfg/DynReconf2.cfg
93 | # )
94 |
95 | ###################################
96 | ## catkin specific configuration ##
97 | ###################################
98 | ## The catkin_package macro generates cmake config files for your package
99 | ## Declare things to be passed to dependent projects
100 | ## INCLUDE_DIRS: uncomment this if your package contains header files
101 | ## LIBRARIES: libraries you create in this project that dependent projects also need
102 | ## CATKIN_DEPENDS: catkin_packages dependent projects also need
103 | ## DEPENDS: system dependencies of this project that dependent projects also need
104 | catkin_package(
105 | # INCLUDE_DIRS include
106 | # LIBRARIES test_module_1
107 | # CATKIN_DEPENDS hot_word_detection rospy std_msgs
108 | # DEPENDS system_lib
109 | )
110 |
111 | ###########
112 | ## Build ##
113 | ###########
114 |
115 | ## Specify additional locations of header files
116 | ## Your package locations should be listed before other locations
117 | include_directories(
118 | # include
119 | ${catkin_INCLUDE_DIRS}
120 | )
121 |
122 | ## Declare a C++ library
123 | # add_library(${PROJECT_NAME}
124 | # src/${PROJECT_NAME}/test_module_1.cpp
125 | # )
126 |
127 | ## Add cmake target dependencies of the library
128 | ## as an example, code may need to be generated before libraries
129 | ## either from message generation or dynamic reconfigure
130 | # add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
131 |
132 | ## Declare a C++ executable
133 | ## With catkin_make all packages are built within a single CMake context
134 | ## The recommended prefix ensures that target names across packages don't collide
135 | # add_executable(${PROJECT_NAME}_node src/test_module_1_node.cpp)
136 |
137 | ## Rename C++ executable without prefix
138 | ## The above recommended prefix causes long target names, the following renames the
139 | ## target back to the shorter version for ease of user use
140 | ## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
141 | # set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")
142 |
143 | ## Add cmake target dependencies of the executable
144 | ## same as for the library above
145 | # add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
146 |
147 | ## Specify libraries to link a library or executable target against
148 | # target_link_libraries(${PROJECT_NAME}_node
149 | # ${catkin_LIBRARIES}
150 | # )
151 |
152 | #############
153 | ## Install ##
154 | #############
155 |
156 | # all install targets should use catkin DESTINATION variables
157 | # See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
158 |
159 | ## Mark executable scripts (Python etc.) for installation
160 | ## in contrast to setup.py, you can choose the destination
161 | # catkin_install_python(PROGRAMS
162 | # scripts/my_python_script
163 | # DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
164 | # )
165 |
166 | ## Mark executables for installation
167 | ## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html
168 | # install(TARGETS ${PROJECT_NAME}_node
169 | # RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
170 | # )
171 |
172 | ## Mark libraries for installation
173 | ## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html
174 | # install(TARGETS ${PROJECT_NAME}
175 | # ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
176 | # LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
177 | # RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
178 | # )
179 |
180 | ## Mark cpp header files for installation
181 | # install(DIRECTORY include/${PROJECT_NAME}/
182 | # DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
183 | # FILES_MATCHING PATTERN "*.h"
184 | # PATTERN ".svn" EXCLUDE
185 | # )
186 |
187 | ## Mark other files for installation (e.g. launch and bag files, etc.)
188 | # install(FILES
189 | # # myfile1
190 | # # myfile2
191 | # DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
192 | # )
193 |
194 | #############
195 | ## Testing ##
196 | #############
197 |
198 | ## Add gtest based cpp test target and link libraries
199 | # catkin_add_gtest(${PROJECT_NAME}-test test/test_test_module_1.cpp)
200 | # if(TARGET ${PROJECT_NAME}-test)
201 | # target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
202 | # endif()
203 |
204 | ## Add folders to be run by python nosetests
205 | # catkin_add_nosetests(test)
206 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 AIWintermuteAI
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # bittle_ROS
2 | ROS driver for Petoi Bittle Teleoperation
3 |
--------------------------------------------------------------------------------
/bittle_teleop_robot.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/bittle_teleop_server.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | bittle_driver
4 | 0.1.0
5 | The bittle driver package
6 |
7 |
8 |
9 |
10 | ubuntu
11 |
12 |
13 |
14 |
15 |
16 | TODO
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | catkin
52 | rospy
53 | std_msgs
54 | rospy
55 | std_msgs
56 | rospy
57 | std_msgs
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/scripts/bittle_driver.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | import rospy
3 | import serial
4 | import struct
5 | import sys
6 | import time
7 | import math
8 | from std_msgs.msg import String
9 | from geometry_msgs.msg import Twist
10 |
11 | dir_dict = {1:'kwk', -1:'kbk', 2:'kcrR', 3:'kcrL', 0:'kbalance'}
12 |
13 | class Driver:
14 |
15 | def __init__(self, port='/dev/ttyS0'):
16 | self.dir = 0
17 | rospy.init_node('cmd_vel_listener')
18 | rospy.Subscriber("/cmd_vel", Twist, self.callback)
19 | self.ser = serial.Serial(
20 | port=port,
21 | baudrate=115200, # the newest OpenCat code uses 115200
22 | parity=serial.PARITY_NONE,
23 | stopbits=serial.STOPBITS_ONE,
24 | bytesize=serial.EIGHTBITS,
25 | timeout=1
26 | )
27 |
28 | def callback(self, msg):
29 | rospy.loginfo("Received a /cmd_vel message!")
30 | rospy.loginfo("Linear Components: [%f, %f, %f]"%(msg.linear.x, msg.linear.y, msg.linear.z))
31 | rospy.loginfo("Angular Components: [%f, %f, %f]"%(msg.angular.x, msg.angular.y, msg.angular.z))
32 |
33 | if msg.linear.x > 0:
34 | dir = 1
35 | elif msg.linear.x < 0:
36 | dir = -1
37 | elif msg.angular.z > 0:
38 | dir = 2
39 | elif msg.angular.z < 0:
40 | dir = 3
41 | else:
42 | dir = 0
43 |
44 | if self.dir != dir:
45 | self.wrapper([dir_dict[dir],0])
46 | self.dir = dir
47 |
48 | def run(self):
49 | rospy.spin()
50 |
51 | def wrapper(self, task): #Structure is [token, var=[], time]
52 | print(task)
53 | if len(task)==2:
54 | self.serialWriteByte([task[0]])
55 | elif isinstance(task[1][0],int):
56 | self.serialWriteNumToByte(task[0],task[1])
57 | else:
58 | self.serialWriteByte(task[1])
59 | time.sleep(task[-1])
60 |
61 | def serialWriteNumToByte(self, token, var=[]): # Only to be used for c m u b i l o within Python
62 | #print("Num Token "); print(token);print(" var ");print(var);print("\n\n");
63 | if token == 'l' or token=='i':
64 | var=list(map(lambda x:int(x), var))
65 | instrStr=token+struct.pack('b' * len(var), *var)+'~'
66 | elif token =='c' or token =='m' or token =='u' or token =='b':
67 | instrStr = token + str(var[0])+" "+str(var[1])+'\n'
68 | print("!!!!"+ instrStr)
69 | self.ser.write(instrStr.encode())
70 |
71 | def serialWriteByte(self, var=[]):
72 | token = var[0][0]
73 | if (token == 'c' or token == 'm' or token=='b' or token=='u') and len(var)>=2:
74 | instrStr=""
75 | for element in var:
76 | instrStr=instrStr +element+" "
77 | elif token == 'l' or token=='i' :
78 | if(len(var[0])>1):
79 | var.insert(1,var[0][1:])
80 | var[1:]=list(map(lambda x:int(x), var[1:]))
81 | instrStr = token+struct.pack('b' * len(var[1:]), *var[1:])+'~'
82 | elif token == 'w' or token == 'k':
83 | instrStr = var[0] + '\n'
84 | else:
85 | instrStr = token
86 | print("!!!!!!! "+instrStr)
87 | self.ser.write(instrStr.encode())
88 |
89 | if __name__ == '__main__':
90 | driver = Driver()
91 | driver.run()
92 |
--------------------------------------------------------------------------------
/test_bittle.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------