├── Ch1 ROS Node & Topic
├── README.md
├── ROS_Node_Concept.png
├── ROS_Node_Description.png
├── ROS_Topic_Concept.png
├── ROS_Topic_Concept2.png
└── ROS_Topic_Description.png
├── Ch2 ROS Service
├── Python_Service_Example.png
├── Python_Service_Example2.png
├── Python_Service_Example3.png
├── README.md
├── ROS_Service_Client.png
├── ROS_Service_Command.png
├── ROS_Service_Concept.png
├── ROS_Service_Concept2.png
├── ROS_Service_Concept3.png
├── ROS_Service_Server.png
├── Service_Call_Example.png
├── Service_Call_Example2.png
└── Service_Msg_Type.png
├── Ch3 ROS Custom Message
├── README.md
├── ROS_Message1.png
├── ROS_Message2.png
├── ROS_Message3.png
├── ROS_Message_Concept.PNG
└── ROS_Message_Concept2.PNG
├── Ch4 ROS Params & Launch Files
├── README.md
├── ROS_Launch_file_concept.PNG
├── ROS_Parameters.PNG
├── ROS_Parameters2.PNG
└── ROS_Parameters_concept.PNG
├── Ch5 ROS Bag & OOP
└── README.md
├── Ch6 ROS Gazebo
├── Ch1 Launch Your First Gazebo World Using ROS
│ └── README.md
├── Ch10 Launch RViz using a configuration file
│ └── README.md
├── Ch11 Use joint_state_publisher
│ └── README.md
├── Ch12 Create custom gazebo model using heightmap
│ └── README.md
├── Ch2 Add gazebo models to a simulation
│ └── README.md
├── Ch3 Spawn a robot in gazebo
│ └── README.md
├── Ch4 Create a gazebo model using SDF
│ └── README.md
├── Ch5 Use a mesh file to create a gazebo model
│ ├── README.md
│ ├── cordless_drill.stl
│ └── robot_car.stl
├── Ch6 Use an image file as texture for gazebo model
│ ├── README.md
│ └── seamless_texture.png
├── Ch7 Create a robot using URDF
│ └── README.md
├── Ch8 Visualize a robot URDF using RVIZ
│ └── README.md
└── Ch9 Create a robot using URDF(Advance & RVIZ)
│ └── README.md
├── Ch7 ROS Virtual RobotX
├── Ch01_Adding_Course_Elements.md
├── Ch02_Custom_WAM-V_Thruster_Sensor_Configuration.md
├── Ch03_Propulsion_Configurations.md
├── Ch04_Adding_Sensors.md
├── Ch05_Thruster_Articulation.md
├── Ch06_Driving.md
├── Ch07_Visualizing_with_RViz.md
├── Ch08_Plugin_Parameters.md
├── Ch09_Custom_Dock.md
└── figure
│ ├── driving_debug_before.png
│ └── keyboard_debug_after.png
├── README.md
└── src
├── my_robot_bringup
├── CMakeLists.txt
├── launch
│ └── number_app.launch
└── package.xml
├── my_robot_msgs
├── CMakeLists.txt
├── msg
│ └── HardwareStatus.msg
├── package.xml
└── srv
│ ├── ComputeDiskArea.srv
│ └── SetLed.srv
└── my_robot_tutorials
├── CMakeLists.txt
├── package.xml
├── scripts
├── add_two_ints_client.py
├── add_two_ints_server.py
├── battery.py
├── hw_status_publisher.py
├── led_panel.py
├── my_first_node.py
├── number_counter.py
├── number_publisher.py
├── oop_number_counter.py
├── robot_news_radio_transmitter.py
└── smartphone.py
└── src
├── add_two_ints_client.cpp
├── add_two_ints_server.cpp
├── my_first_node.cpp
├── number_counter.cpp
├── number_publisher.cpp
├── oop_number_counter.cpp
├── robot_news_radio_transmitter.cpp
└── smartphone_node.cpp
/Ch1 ROS Node & Topic/README.md:
--------------------------------------------------------------------------------
1 | # Chapter **1.** ROS Node and Topic
2 |
3 | ## Install ROS and Setup Your Environment
4 |
5 | * [__Installation (ROS Melodic)__][0]
6 |
7 | [0]: http://wiki.ros.org/melodic/Installation/Ubuntu
8 |
9 | * __Update packages :__
10 | ```console
11 | [alonzo@study ~]$ sudo apt-get update
12 | [alonzo@study ~]$ sudo apt-get install ros-melodic-packagename
13 | ```
14 |
15 | ## ROS package
16 | 1. Create a workspace
17 | ```console
18 | [alonzo@study ~]$ mkdir ~/catkin_ws
19 | [alonzo@study ~]$ mkdir ~/catkin_ws/src
20 | [alonzo@study ~]$ cd ~/catkin_ws
21 | [alonzo@study ~]$ catkin_make
22 | [alonzo@study ~]$ vim ~/.bashrc
23 | # > Add: source ~/catkin_ws/devel/setup.bash (For exe files based on developer's workspace)
24 | # Note : source /opt/ros/melodic/setup.bash (For ros global application such as catkin_make, roscore)
25 | [alonzo@study ~]$ source ~/.bashrc
26 | ```
27 | 2. Create packages
28 | ```console
29 | [alonzo@study ~/catkin_ws/src]$ catkin_create_pkg {name of package} {dependencies}
30 | [alonzo@study ~/catkin_ws/src]$ catkin_create_pkg my_robot_tutorials roscpp rospy std_msgs
31 | [alonzo@study ~/catkin_ws/src]$ ls ./my_robot_tutorials
32 | # > CMakeLists.txt include/ package.xml src/
33 | [alonzo@study ~/catkin_ws/src]$ cd ~/catkin_ws
34 | [alonzo@study ~/catkin_ws]$ catkin_make
35 | ```
36 |
37 | ## ROS Node
38 |
39 |
40 |
41 |

42 |

43 |
44 |
45 |
46 | * __Python Node:__
47 | 1. Create python node
48 | ```console
49 | [alonzo@study ~/catkin_ws/src/package_name]$ mkdir scripts
50 | [alonzo@study ~/catkin_ws/src/package_name/scripts]$ touch my_first_node.py
51 | [alonzo@study ~/catkin_ws/src/package_name/scripts]$ chmod a+x my_first_node.py
52 | [alonzo@study ~/catkin_ws/src/package_name/scripts]$ vim my_first_node.py
53 | ```
54 | 2. Edit python node
55 | ```python
56 | #! /usr/bin/env python
57 |
58 | import rospy
59 |
60 | if __name__ == '__main__':
61 |
62 | rospy.init_node('my_first_python_node') # input your node's name
63 |
64 | rospy.loginfo("This node has been started") # log features for ros
65 |
66 | rate = rospy.Rate(10) # 10 Hz
67 |
68 | while not rospy.is_shutdown():
69 | rospy.loginfo("Hello")
70 | rate.sleep()
71 |
72 | rospy.loginfo("Exit now")
73 | ```
74 | 3. Run python node
75 | ```console
76 | [alonzo@study ~/catkin_ws/src/package_name/scripts]$ roscore # Run roscore anywhere
77 | [alonzo@study ~/catkin_ws/src/package_name/scripts]$ python my_first_node.py
78 | Note : rosrun package_name my_first_node.py
79 | ```
80 |
81 | * __C++ Node:__
82 | 1. Create C++ node
83 | ```cpp
84 | [alonzo@study ~/catkin_ws/src/package_name/src]$ touch my_first_cpp_node.cpp
85 | [alonzo@study ~/catkin_ws/src/package_name/src]$ vim CMakeList.txt
86 | # > Add:
87 | # > add_executable({exe_name} src/my_first_cpp_node.cpp)
88 | # > target_link_libraries({exe_name} ${catkin_LIBRARIES})
89 | [alonzo@study ~/catkin_ws]$ catkin_make
90 | ```
91 | 2. Edit C++ node
92 | ```cpp
93 | #include
94 |
95 | int main(int argc, char** argv){
96 |
97 | ros::init(argc, argv, "my_first_cpp_node"); // Can't be the same with other nodes
98 | ros::NodeHandle nh; // Start the node
99 | ROS_INFO("Node has been started");
100 | //ros::Duration(1.0).sleep();
101 | ros::Rate rate(10);
102 | while (ros::ok()){
103 | ROS_INFO("Hello");
104 | rate.sleep();
105 | }
106 | ROS_INFO("Exit");
107 | }
108 | ```
109 | 3. Run C++ node
110 | ```console
111 | [alonzo@study ~/catkin_ws]$ catkin_make
112 | [alonzo@study ~/catkin_ws/devel/lib/package_name]$ ./{exe_name} # Same as exe_name in pkg CMakeLists
113 | Note : rosrun package_name {exe_name}
114 | ```
115 |
116 | ## ROS Topic
117 |
118 |
119 |
120 |

121 |

122 |
123 |
124 |
125 | * __Python Publisher/Subscriber:__
126 | * Publisher node:
127 | ```python
128 | #!/usr/bin/env python
129 |
130 | import rospy
131 | from std_msgs.msg import String
132 |
133 | if __name__ == '__main__':
134 |
135 | rospy.init_node('robot_news_radio_transmitter', anonymous = True) # Anonymous: If nodes have the same name, anonymous makes it possible to run both
136 |
137 | pub = rospy.Publisher("/robot_news_radio", String, queue_size=10) #Add buffer for subscriber in case they don't have time to process message
138 |
139 | rate = rospy.Rate(2) #two msg per second
140 |
141 | while not rospy.is_shutdown():
142 | msg = String() #Create an object from String class, in String class there is a private member called data
143 | msg.data = "Hi this is Dan fron the Robot News Radio !"
144 | pub.publish(msg)
145 | rate.sleep()
146 |
147 | rospy.loginfo("Node wass stopped")
148 | ```
149 | * Subscriber node:
150 | ```python
151 | #!/usr/bin/env python
152 |
153 | import rospy
154 | from std_msgs.msg import String
155 |
156 | def callback_recieve_radio_data(msg):
157 | rospy.loginfo("Message recieved : ")
158 | rospy.loginfo(msg)
159 |
160 | if __name__ == '__main__':
161 |
162 | rospy.init_node('smartphone')
163 |
164 | sub = rospy.Subscriber("/robot_news_radio", String, callback_recieve_radio_data)
165 |
166 | rospy.spin() # Keep running callbcak function
167 | ```
168 |
169 |
170 | * __C++ Publisher/Subscriber:__
171 | * Publisher node:
172 | ```cpp
173 | #include
174 | #include
175 | int main(int argc, char** argv){
176 |
177 | ros::init(argc, argv, "robot_news_radio_transmitter", ros::init_options::AnonymousName); // Can't be the same with other node
178 | ros::NodeHandle nh; // To start the node
179 |
180 | ros::Publisher pub = nh.advertise("/robot_news_radio", 10); // (topic name, qeue size)
181 | ros::Rate rate(3);
182 |
183 | while (ros::ok()){
184 | std_msgs::String msg;
185 | msg.data = "Hi this is logan from the robot news radio";
186 | pub.publish(msg);
187 | rate.sleep();
188 | }
189 | }
190 | ```
191 | * Subscriber node:
192 | ```cpp
193 | #include
194 | #include
195 |
196 | void callback_recieve_radio_data(const std_msgs::String& msg)
197 | {
198 | ROS_INFO("Message recieved : %s", msg.data.c_str());
199 | }
200 |
201 | int main(int argc, char** argv){
202 |
203 | ros::init(argc, argv, "smartphone"); // Can't be the same with other node
204 | ros::NodeHandle nh; // To start the node
205 |
206 | ros::Subscriber sub = nh.subscribe("/robot_news_radio", 1000, callback_recieve_radio_data); //(topic name, qeue size, function)
207 |
208 | ros::spin();
209 | }
210 | ```
211 |
--------------------------------------------------------------------------------
/Ch1 ROS Node & Topic/ROS_Node_Concept.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch1 ROS Node & Topic/ROS_Node_Concept.png
--------------------------------------------------------------------------------
/Ch1 ROS Node & Topic/ROS_Node_Description.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch1 ROS Node & Topic/ROS_Node_Description.png
--------------------------------------------------------------------------------
/Ch1 ROS Node & Topic/ROS_Topic_Concept.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch1 ROS Node & Topic/ROS_Topic_Concept.png
--------------------------------------------------------------------------------
/Ch1 ROS Node & Topic/ROS_Topic_Concept2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch1 ROS Node & Topic/ROS_Topic_Concept2.png
--------------------------------------------------------------------------------
/Ch1 ROS Node & Topic/ROS_Topic_Description.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch1 ROS Node & Topic/ROS_Topic_Description.png
--------------------------------------------------------------------------------
/Ch2 ROS Service/Python_Service_Example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch2 ROS Service/Python_Service_Example.png
--------------------------------------------------------------------------------
/Ch2 ROS Service/Python_Service_Example2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch2 ROS Service/Python_Service_Example2.png
--------------------------------------------------------------------------------
/Ch2 ROS Service/Python_Service_Example3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch2 ROS Service/Python_Service_Example3.png
--------------------------------------------------------------------------------
/Ch2 ROS Service/README.md:
--------------------------------------------------------------------------------
1 | # Chapter **2.** ROS Service
2 |
3 | ## ROS Service
4 |
5 |
6 |
7 |

8 |

9 |

10 |
11 |
12 |
13 | * __Service message (Request/Response) :__
14 |
15 |
16 |
17 |

18 |
19 |
20 |
21 | * __Python Server/Client :__
22 | * Python Server
23 | ```python
24 | #!/usr/bin/env python
25 |
26 | import rospy
27 | from rospy_tutorials.srv import AddTwoInts
28 |
29 | def handle_add_two_ints(req):
30 | result = req.a + req.b
31 | rospy.loginfo("Sum of " + str(req.a) + " and " + str(req.b) + " is " + str(result))
32 | return result
33 |
34 | if __name__ == '__main__':
35 |
36 | rospy.init_node('robot_news_radio_transmitter')
37 | rospy.loginfo("Add two ints server node created")
38 |
39 | service = rospy.Service("/add_two_ints", AddTwoInts, handle_add_two_ints) # name of the service, usually start with verb
40 | # wait for client AddTwoInts class object (int a, int b), in this code, it's req
41 | rospy.loginfo("Serrvice server has been started")
42 |
43 | rospy.spin()
44 | ```
45 |
46 |
47 |
48 |

49 |
Fig. Use rosservice call to poke msg to service "/add_two_ints"
50 |

51 |
Fig. Service "/add_two_ints" response to incoming msg
52 |
53 |
54 |
55 | * Python Client
56 | ```python
57 | #!/usr/bin/env python
58 |
59 | import rospy
60 | from rospy_tutorials.srv import AddTwoInts
61 |
62 | if __name__ == '__main__':
63 |
64 | rospy.init_node('add_two_ints_client')
65 | rospy.wait_for_service("/add_two_ints") # Wait for service is setup
66 |
67 | try: # If service is not ready, catch exception
68 | add_two_ints = rospy.ServiceProxy("/add_two_ints", AddTwoInts) # Create client and give the type of client
69 | response = add_two_ints(2,6) # Call client, get AddTwoInts class object(int sum) from server and assign to response
70 | rospy.loginfo("Sum is: " + str(response.sum))
71 | except rospy.ServiceException as e:
72 | #rospy.logwarn("Service failed: ", str(e))
73 | rospy.loginfo(str(e))
74 | ```
75 |
76 |
77 |
78 |

79 |
Fig. Run server and activate "/add_two_ints" service
80 |
81 |

82 |
Fig. Run client
83 |
84 |
85 |
86 | * __C++ Server/Client :__
87 | * C++ Server
88 | 1. Add library for service message (Remember to add executale and target link as well)
89 | ```console
90 | # pkg/src/CMakeLists.txt
91 | find_package(catkin REQUIRED COMPONENTS
92 | roscpp
93 | rospy
94 | std_msgs
95 | rospy_tutorials <= library for service msg
96 | )
97 |
98 | # pkg/src/package.xml
99 | rospy_tutorials
100 | rospy_tutorials
101 | ```
102 | 2. Edit C++ server
103 | ```cpp
104 | #include
105 | #include
106 |
107 | bool handle_add_two_ints(rospy_tutorials::AddTwoInts::Request &req,
108 | rospy_tutorials::AddTwoInts::Response &res)
109 | {
110 | int result = req.a + req.b;
111 | ROS_INFO("%d + %d = %d", (int)req.a, (int)req.b, (int)result);
112 | res.sum = result;
113 | return true;
114 | }
115 |
116 | int main(int argc, char** argv){
117 |
118 | ros::init(argc, argv, "add_two_ints_server"); // Can't be the same with other node
119 | ros::NodeHandle nh; //To start the node
120 |
121 | ros::ServiceServer server = nh.advertiseService("/add_two_ints", handle_add_two_ints); // Service name & callback
122 |
123 | ros::spin();
124 |
125 | }
126 | ```
127 | * C++ Client
128 | ```cpp
129 | #include
130 | #include
131 |
132 | int main(int argc, char** argv){
133 |
134 | ros::init(argc, argv, "add_two_ints_client"); // Can't be the same with other node
135 | ros::NodeHandle nh; // Start the node
136 |
137 | ros::ServiceClient client = nh.serviceClient("/add_two_ints");
138 |
139 | rospy_tutorials::AddTwoInts srv;
140 |
141 | srv.request.a = 12;
142 | srv.request.b = 5;
143 |
144 | if(client.call(srv)){ // If server return true
145 | //process data
146 | ROS_INFO("Returned sum is %d", (int)srv.response.sum);
147 | }
148 | else{
149 | ROS_WARN("Service call failed");
150 | }
151 |
152 | ros::spin();
153 |
154 | }
155 | ```
156 |
157 | * __ROS Service command :__
158 |
159 |
160 |
161 |

162 |
163 |
164 |
165 |
166 | * __Python example(Publisher/Subscriber/Service) :__
167 | ```python
168 | #!/usr/bin/env python
169 |
170 | import rospy
171 | from std_msgs.msg import Int64
172 | from std_srvs.srv import SetBool # sudo apt-get install ros-melodic-std-srvs
173 |
174 | counter = 0
175 | pub = None
176 |
177 | # Function for subscriber
178 | def callback(num):
179 | rospy.loginfo(num)
180 | global counter
181 | counter += num.data
182 | pub.publish(counter)
183 | rospy.loginfo(counter)
184 |
185 | # Service function
186 | def handle_message(msg):
187 | #rospy.loginfo(msg.response.success) # error: input message doesn't include Response(success,message)
188 | #rospy.loginfo(msg.response.message)
189 | if (msg.data):
190 | global counter
191 | counter = 0
192 | return True,"Counter reset success"
193 | else:
194 | return False,"Counter has not been reset"
195 |
196 | if __name__ == '__main__':
197 |
198 | rospy.init_node('number_counter')
199 |
200 | sub = rospy.Subscriber("/number", Int64, callback)
201 |
202 | pub = rospy.Publisher("/number_count", Int64, queue_size=10)
203 |
204 | service = rospy.Service("/reset_number_count", SetBool, handle_message) # name of the service, usually start with verb
205 |
206 | rospy.spin() #Keep running callbcak function
207 | ```
208 | * __Python example service message type :__
209 |
210 |
211 |
212 |

213 |
214 |
215 |
216 | * __Python example output :__
217 |
218 |
219 |
220 |

221 |

222 |
223 |
224 |
225 |
--------------------------------------------------------------------------------
/Ch2 ROS Service/ROS_Service_Client.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch2 ROS Service/ROS_Service_Client.png
--------------------------------------------------------------------------------
/Ch2 ROS Service/ROS_Service_Command.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch2 ROS Service/ROS_Service_Command.png
--------------------------------------------------------------------------------
/Ch2 ROS Service/ROS_Service_Concept.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch2 ROS Service/ROS_Service_Concept.png
--------------------------------------------------------------------------------
/Ch2 ROS Service/ROS_Service_Concept2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch2 ROS Service/ROS_Service_Concept2.png
--------------------------------------------------------------------------------
/Ch2 ROS Service/ROS_Service_Concept3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch2 ROS Service/ROS_Service_Concept3.png
--------------------------------------------------------------------------------
/Ch2 ROS Service/ROS_Service_Server.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch2 ROS Service/ROS_Service_Server.png
--------------------------------------------------------------------------------
/Ch2 ROS Service/Service_Call_Example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch2 ROS Service/Service_Call_Example.png
--------------------------------------------------------------------------------
/Ch2 ROS Service/Service_Call_Example2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch2 ROS Service/Service_Call_Example2.png
--------------------------------------------------------------------------------
/Ch2 ROS Service/Service_Msg_Type.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch2 ROS Service/Service_Msg_Type.png
--------------------------------------------------------------------------------
/Ch3 ROS Custom Message/README.md:
--------------------------------------------------------------------------------
1 | # Chapter **3.** Customize Your Application With Msg and Srv Files
2 |
3 |
4 |
5 |

6 |

7 |
8 |
9 |
10 | ## Create and Build Your Own Custom Msg
11 | ```console
12 | # Create a "new" pkg for custom msg and srv
13 | [alonzo@study ~/catkin_ws/src]$ catkin_create_pkg my_robot_msgs roscpp rospy std_msgs
14 | [alonzo@study ~/catkin_ws/src]$ cd /my_robot_msgs
15 |
16 | # Remove /include /src directories
17 | [alonzo@study ~/catkin_ws/src/my_robot_msgs]$ rm -rf /include /src
18 |
19 | # Create msg/ directory and modify .msg file
20 | [alonzo@study ~/catkin_ws/src/my_robot_msgs]$ mkdir msg;cd msg/
21 | [alonzo@study ~/catkin_ws/src/my_robot_msgs/msg]$ vim HardwareStatus.msg
22 | [alonzo@study ~/catkin_ws/src/my_robot_msgs/msg]$ cd ..
23 |
24 | # Modify CMakeLists.txt and package.xml in "Msg pkg"
25 | [alonzo@study ~/catkin_ws/src/my_robot_msgs]$ vim CMakeLists.txt
26 | [alonzo@study ~/catkin_ws/src/my_robot_msgs]$ vim package.xml
27 |
28 | # After editing CMakeLists.txt, package.xml and HardwareStatus.msg
29 | # Don't forget to catkin_make & source ~/.bashrc!
30 | [alonzo@study ~/catkin_ws/]$ catkin_make
31 | # Header file will be generated under ~/catkin_ws/devel/include/my_robot_msgs/
32 | [alonzo@study ~/catkin_ws/]$ . ~/bashrc
33 | ```
34 | * __CMakeLists.txt__
35 | ```
36 | 1.
37 | find_package(catkin REQUIRED COMPONENTS
38 | roscpp
39 | rospy
40 | std_msgs
41 | message_generation <==== Msg class .h/.cpp file will be generated after catkin_make
42 | )
43 |
44 | 2.
45 | ## Generate messages in the 'msg' folder
46 | add_message_files(
47 | FILES
48 | HardwareStatus.msg <====
49 | )
50 |
51 | 3.
52 | ## Generate added messages and services with any dependencies listed here
53 | generate_messages(
54 | DEPENDENCIES
55 | std_msgs
56 | )
57 |
58 | 4.
59 | catkin_package(
60 | # INCLUDE_DIRS include
61 | # LIBRARIES my_robot_msgs
62 | CATKIN_DEPENDS roscpp rospy std_msgs message_runtime <==== add "message_runtime"
63 | # DEPENDS system_lib
64 | )
65 | ```
66 | * __package.xml__
67 | ```
68 | message_generation
69 | message_runtime
70 | ```
71 |
72 | * __HardwareStatus.msg__
73 | ```
74 | int64 temperature
75 | bool are_motors_up
76 | string debug_message
77 | ```
78 |
79 | ## Use Your Custom Msg in Your Code
80 | ```console
81 | # Include msg pkg in another pkg to use your custom message
82 | [alonzo@study ~/catkin_ws/src/package_name/scripts]$ vim hw_status_publisher.py
83 | [alonzo@study ~/catkin_ws/src/package_name/scripts]$ chmod a+x hw_status_publisher.py
84 | [alonzo@study ~/catkin_ws/src/package_name/scripts]$ vim CMakeList.txt package.xml
85 | ```
86 | * __CMakeLists.txt__
87 | ```
88 | find_package(catkin REQUIRED COMPONENTS
89 | roscpp
90 | rospy
91 | std_msgs
92 | std_srvs
93 | rospy_tutorials
94 | my_robot_msgs <== add msg pkg
95 | )
96 | ```
97 | * __package.xml__
98 | ```
99 | my_robot_msgs
100 | ```
101 | * __hw_status_publisher.py__
102 | ```python
103 | #!/usr/bin/env python
104 |
105 | import rospy
106 | from my_robot_msgs.msg import HardwareStatus
107 |
108 | if __name__ == '__main__':
109 |
110 | rospy.init_node('hardware_status_publisher')
111 |
112 | pub = rospy.Publisher("/my_robot/hardware_status", HardwareStatus, queue_size = 10)
113 |
114 | rate = rospy.Rate(5)
115 |
116 | while not rospy.is_shutdown():\
117 | # Create custom msg object
118 | msg = HardwareStatus();
119 |
120 | # Call data in custom msg object
121 | msg.temperature = 45
122 | msg.are_motors_up = True
123 | msg.debug_message = "Everything is running well"
124 | pub.publish(msg)
125 | rate.sleep()
126 | ```
127 | ## Create Your Own Custom Srv
128 | ```console
129 | [alonzo@study ~/catkin_ws/src/my_robot_msgs]$ mkdir srv
130 | [alonzo@study ~/catkin_ws/src/my_robot_msgs/srv]$ vim ComputeDiskArea.srv
131 | [alonzo@study ~/catkin_ws/src/my_robot_msgs/srv]$ vim CMakeList.txt
132 | [alonzo@study ~/catkin_ws]$ catkin_make
133 | # Check generated header file: cd ~/catkin_ws/devel/include/my_robot_msgs/
134 | [alonzo@study ~/catkin_ws/devel/include/my_robot_msgs]$ ls
135 | # > ComputeDiskAreaRequest.h ComputeDiskAreaResponse.h
136 | ```
137 | * __ComputeDiskArea.srv__
138 | ```
139 | float64 radius
140 | ---
141 | float64 area
142 | ```
143 | * __CMakeLists.txt__
144 | ```
145 | ## Generate services in the 'srv' folder
146 | add_service_files(
147 | FILES
148 | ComputeDiskArea.srv
149 | )
150 | ```
151 |
152 | ## Msg and Srv With Command
153 | ```console
154 | [alonzo@study ~]$ rosmsg -h
155 | [alonzo@study ~]$ rosmsg list
156 | [alonzo@study ~]$ rosmsg show
157 | [alonzo@study ~]$ rossrv -h
158 | ```
159 |
160 |
161 |

162 |

163 |
164 |
165 |
166 | * __Note :__
167 | ```python
168 | # spin() only let the node stay active after finishing all the line, doesn't "Loop"
169 | rospy.spin() <== only let the node stay active after finishing all the line, doesn't "Loop"
170 |
171 | # 2 ways to implement sleep()
172 | rate = rospy.Rate(10)
173 | rate.sleep()
174 | # Or
175 | rospy.sleep(3)
176 | ```
177 |
178 | ## Practice
179 | * __led_panel.py__
180 | ```python
181 | #!/usr/bin/env python
182 |
183 | import rospy
184 | from my_robot_msgs.srv import SetLed
185 |
186 | led_states = [0,0,0]
187 |
188 | def callback_set_led(req):
189 | led_number = req.led_number
190 | state = req.state
191 | global led_states
192 |
193 | if (led_number > len(led_states)) or (led_number <= 0):
194 | return False
195 |
196 | if not (state == 0 or state == 1):
197 | return False
198 |
199 | led_states[led_number - 1] = state
200 |
201 | return True
202 |
203 | if __name__ == '__main__':
204 | rospy.init_node('led_panel')
205 |
206 | server = rospy.Service("/set_led", SetLed, callback_set_led)
207 |
208 | rate = rospy.Rate(10)
209 |
210 | while not rospy.is_shutdown():
211 | rospy.loginfo(led_states)
212 | rate.sleep()
213 | ```
214 |
215 | * __battery.py__
216 | ```python
217 | #!/usr/bin/env python
218 |
219 | import rospy
220 | from my_robot_msgs.srv import SetLed
221 |
222 | def set_led(battery_state):
223 | rospy.wait_for_service("/set_led")
224 | try:
225 | service = rospy.ServiceProxy("/set_led", SetLed)
226 | state = 0
227 | if battery_state == 'empty':
228 | state = 1
229 | resp = service(1, state)
230 | rospy.loginfo("Set led success flag : " + str(resp))
231 | except rospy.ServiceException as e:
232 | rospy.logerr(e)
233 |
234 |
235 | if __name__ == '__main__':
236 | rospy.init_node('battery')
237 |
238 | battery_state = "full"
239 |
240 | while not rospy.is_shutdown():
241 | rospy.sleep(7)
242 | battery_state = "empty"
243 | rospy.loginfo("The battery is empty !")
244 | set_led(battery_state)
245 | rospy.sleep(3)
246 | battery_state = "full"
247 | rospy.loginfo("The battery is now full")
248 | set_led(battery_state)
249 | ```
250 |
251 | * __Setled.srv__
252 | ```
253 | int64 led_number
254 | int64 state
255 | ---
256 | bool success
257 | ```
258 |
--------------------------------------------------------------------------------
/Ch3 ROS Custom Message/ROS_Message1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch3 ROS Custom Message/ROS_Message1.png
--------------------------------------------------------------------------------
/Ch3 ROS Custom Message/ROS_Message2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch3 ROS Custom Message/ROS_Message2.png
--------------------------------------------------------------------------------
/Ch3 ROS Custom Message/ROS_Message3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch3 ROS Custom Message/ROS_Message3.png
--------------------------------------------------------------------------------
/Ch3 ROS Custom Message/ROS_Message_Concept.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch3 ROS Custom Message/ROS_Message_Concept.PNG
--------------------------------------------------------------------------------
/Ch3 ROS Custom Message/ROS_Message_Concept2.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch3 ROS Custom Message/ROS_Message_Concept2.PNG
--------------------------------------------------------------------------------
/Ch4 ROS Params & Launch Files/README.md:
--------------------------------------------------------------------------------
1 | # Chapter **4.** ROS Params & Launch Files
2 |
3 |
4 |
5 |

6 |

7 |
8 |
9 |
10 |
11 | ## Manipulate Parameters With Command Line Tools
12 | ```console
13 | # Run roscore to initiate up ros parameter server
14 | [alonzo@study ~]$ roscore
15 |
16 | # Help for rosparam
17 | # rosparam is a cmd-line tool for setting up ros parameter server
18 | [alonzo@study ~]$ rosparam -h
19 |
20 | # list all the ros params in ros
21 | [alonzo@study ~]$ rosparam list
22 |
23 | # Set ros param
24 | # Usage: rosparam set {param_name} {param_value}
25 | [alonzo@study ~]$ rosparam set /robot_name "my_robot"
26 | [alonzo@study ~]$ rosparam set /sensors_read_frequency 40
27 | [alonzo@study ~]$ rosparam set /simulation_mode false
28 |
29 | # Check ros parameters
30 | [alonzo@study ~]$ rosparam list
31 |
32 | # Check ros params value
33 | [alonzo@study ~]$ rosparam get /robot_name
34 | [alonzo@study ~]$ rosparam get /sensors_read_frequency
35 | [alonzo@study ~]$ rosparam get /simulation_mode
36 | ```
37 |
38 |
39 | ## Handle Parameters With Python
40 | ```python
41 | # Get param from ros parameter server
42 | publish_frequency = rospy.get_param("/number_publish_frequency")
43 | # Note : remember to set the param in ros server before calling it
44 | # cmd: rosparam set /number_publish_frequency 2
45 |
46 | # Set param in py file
47 | rospy.set_param("/another_param", "Hello")
48 | ```
49 | ```console
50 | # Run .py file and kill it
51 | # Check in cmd
52 | [alonzo@study ~]$ rosparam list => see "/another_param"
53 | # ros param will till exist even after the node is killed
54 | [alonzo@study ~]$ rosparam get /another_param
55 | ```
56 |
57 | ## Handle Parameters With C++
58 | ```cpp
59 | # Get param from ros parameter server
60 | double publish_frequency;
61 | nh.getParam("/number_publish_frequency", publish_frequency);
62 | ros::Rate rate(publish_frequency);
63 | ```
64 | ```console
65 | # Catkin_make
66 | # Before running node, set ros param first
67 | [alonzo@study ~]$ rosparam set /number_publish_frequency 2
68 |
69 | # Check
70 | [alonzo@study ~]$ rosparam list
71 | # Run your node
72 | ```
73 | ```cpp
74 | # Set param in cpp file
75 | int number;
76 | nh.setParam("/just_another_param","Bye");
77 | ```
78 | ```console
79 | # Catkin_make
80 | [alonzo@study ~]$ rosparam get /just_another_param
81 |
82 | * Note:
83 | Once the node is executed, the value of ros param inside the node is immutable.
84 | Retstart the node to change the value of ros params.
85 | ```
86 |
87 |
88 | ## ROS Launch File
89 |
90 |
91 |
92 |

93 |

94 |
95 |
96 |
97 | ## Create a Launch File to Start all Your Parameters and Nodes
98 | ```console
99 | # Create a pkg for launch file
100 | [alonzo@study ~/catkin_ws/src]$ catkin_create_pkg my_robot_bringup
101 | [alonzo@study ~/catkin_ws]$ catkin_make
102 | [alonzo@study ~/catkin_ws/src]$ cd my_robot_bringup
103 | [alonzo@study ~/catkin_ws/src/my_robot_bringup]$ mkdir launch
104 | [alonzo@study ~/catkin_ws/src/my_robot_bringup]$ cd launch
105 | [alonzo@study ~/catkin_ws/src/my_robot_bringup/launch]$ touch number_app.launch
106 | [alonzo@study ~/catkin_ws/src/my_robot_bringup/launch]$ vim number_app.launch
107 | ```
108 | * __number_app.launch__
109 | ```html
110 |
111 | # Add ros params in launch file
112 |
113 |
114 |
115 | # Add node Note "type => exe name"
116 |
117 |
118 |
119 | ```
120 | * __Execute launch file__
121 | ```console
122 | [alonzo@study ~]$ roslaunch my_robot_bringup number_app.launch
123 |
124 | # Kill ros node
125 | # Check ros parameter
126 | [alonzo@study ~]$ rosparams list
127 | [alonzo@study ~]$ rosnode list
128 | [alonzo@study ~]$ rostopic echo /number
129 | [alonzo@study ~]$ rostopic echo /number_count
130 |
131 | * Note: If using roslaunch, we don't have to run roscore manually
132 | ```
133 |
134 |
--------------------------------------------------------------------------------
/Ch4 ROS Params & Launch Files/ROS_Launch_file_concept.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch4 ROS Params & Launch Files/ROS_Launch_file_concept.PNG
--------------------------------------------------------------------------------
/Ch4 ROS Params & Launch Files/ROS_Parameters.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch4 ROS Params & Launch Files/ROS_Parameters.PNG
--------------------------------------------------------------------------------
/Ch4 ROS Params & Launch Files/ROS_Parameters2.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch4 ROS Params & Launch Files/ROS_Parameters2.PNG
--------------------------------------------------------------------------------
/Ch4 ROS Params & Launch Files/ROS_Parameters_concept.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch4 ROS Params & Launch Files/ROS_Parameters_concept.PNG
--------------------------------------------------------------------------------
/Ch5 ROS Bag & OOP/README.md:
--------------------------------------------------------------------------------
1 | # Chapter **5.** ROS Bag and OOP
2 |
3 | ## Replay a Topic With ROS Bags
4 | * A bag is a file format in ROS for storing ROS message data.
5 | * `rosbag` command can record, replay bags.
6 |
7 | ```console
8 | # Rosbag help
9 | rosbag -h
10 |
11 | # Run ros master and node
12 | [alonzo@study ~]$ roscore
13 | [alonzo@study ~]$ rosrun my_robot_tutorials hw_status_publisher.py
14 | [alonzo@study ~]$ rosnode list
15 | [alonzo@study ~]$ rostopic list
16 | [alonzo@study ~]$ rostopic echo /my_robot/hardware_status
17 |
18 | # Save the data in one topic
19 | # rosbag record {topic name}
20 | [alonzo@study ~]$ rosbag record /my_robot/hardware_status
21 | # This will generate .bag file
22 |
23 | # Replay topic
24 | [alonzo@study ~]$ rosbag play 2018-06-16-08-31-32.bag
25 | # rostopic /my_robot/hardware_status start printing
26 | ```
27 |
28 | ## Use OOP With ROS Python
29 | ```python
30 | #!/usr/bin/env python
31 |
32 | import rospy
33 | from std_msgs.msg import Int64
34 | from std_srvs.srv import SetBool
35 |
36 |
37 | class NumberCounter:
38 |
39 | def __init__(self):
40 | self.counter = 0
41 |
42 | self.number_subscriber = rospy.Subscriber("/number", Int64, self.callback_number)
43 |
44 | self.pub = rospy.Publisher("/number_count", Int64, queue_size=10)
45 |
46 | self.reset_service = rospy.Service("/reset_counter", SetBool, self.callback_reset_counter)
47 |
48 | def callback_number(self, msg):
49 | self.counter += msg.data
50 | new_msg = Int64()
51 | new_msg.data = self.counter
52 | self.pub.publish(new_msg)
53 |
54 | def callback_reset_counter(self, req):
55 | if req.data:
56 | self.counter = 0
57 | return True, "Counter has been successfully reset"
58 | return False, "Counter has not been reset"
59 |
60 |
61 | if __name__ == '__main__':
62 | rospy.init_node('number_counter')
63 | NumberCounter()
64 | rospy.spin()
65 | ```
66 |
67 | ## Use OOP With ROS C++
68 | ```cpp
69 | #include
70 | #include
71 | #include
72 |
73 | class NumberCounter {
74 |
75 | private:
76 | int counter;
77 | ros::Publisher pub;
78 | ros::Subscriber number_subscriber;
79 | ros::ServiceServer reset_service;
80 |
81 | public:
82 | NumberCounter(ros::NodeHandle *nh) {
83 | counter = 0;
84 |
85 | pub = nh->advertise("/number_count", 10);
86 |
87 | number_subscriber = nh->subscribe("/number", 1000,
88 | &NumberCounter::callback_number, this);
89 |
90 | reset_service = nh->advertiseService("/reset_counter",
91 | &NumberCounter::callback_reset_counter, this);
92 | }
93 |
94 | void callback_number(const std_msgs::Int64& msg) {
95 | counter += msg.data;
96 | std_msgs::Int64 new_msg;
97 | new_msg.data = counter;
98 | pub.publish(new_msg);
99 | }
100 |
101 | bool callback_reset_counter(std_srvs::SetBool::Request &req,
102 | std_srvs::SetBool::Response &res)
103 | {
104 | if (req.data) {
105 | counter = 0;
106 | res.success = true;
107 | res.message = "Counter has been successfully reset";
108 | }
109 | else {
110 | res.success = false;
111 | res.message = "Counter has not been reset";
112 | }
113 |
114 | return true;
115 | }
116 | };
117 |
118 | int main (int argc, char **argv)
119 | {
120 | ros::init(argc, argv, "number_counter");
121 | ros::NodeHandle nh;
122 | NumberCounter nc = NumberCounter(&nh);
123 | ros::spin();
124 | }
125 | ```
126 |
127 | ## Work With Multiple Catkin Workspaces
128 |
129 | * __Note :__
130 | Only the last setup.bash in ~/.bashrc will be implemented.
131 | Thus, source manually to overwrite env params or modify bashrc.
132 |
133 |
--------------------------------------------------------------------------------
/Ch6 ROS Gazebo/Ch1 Launch Your First Gazebo World Using ROS/README.md:
--------------------------------------------------------------------------------
1 | ## Launch Your First Gazebo World Using ROS
2 | 1. **Create your own workspace and pkg**
3 | ```console
4 | [alonzo@study ~]$ mkdir -p simulation_ws/src
5 | [alonzo@study ~/simulation_ws/src]$ catkin_create_pkg my_simulations # No dependencies
6 | [alonzo@study ~/simulation_ws]$ catkin_make
7 | [alonzo@study ~/simulation_ws]$ source ~/simulation_ws/devel/setup.bash
8 | ```
9 | 2. **Create launch and world folder**
10 | ```console
11 | [alonzo@study ~/simulation_ws/src/my_simulations]$ mkdir launch world
12 | ```
13 |
14 | 3. **Create and edit your .launch file**
15 | ```console
16 | [alonzo@study ~/simulation_ws/src/my_simulations/launch]$ touch my_world.launch
17 | ```
18 |
19 | 4. **Create and edit your .world file**
20 | ```console
21 | [alonzo@study ~/simulation_ws/src/my_simulations/world]$ touch empty_world.world
22 | ```
23 |
24 | 5. **Launch your Gazebo world**
25 | ```console
26 | [alonzo@study ~]$ roslaunch my_simulations my_world.launch
27 | ```
28 |
29 | ## Source code
30 | * my_world.launch
31 | ```xml
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | ```
50 |
51 | * empty_world.world
52 | ```xml
53 |
54 |
55 |
56 |
57 |
58 |
59 | model://sun
60 |
61 |
62 |
63 | model://ground_plane
64 |
65 |
66 |
67 |
68 | ```
69 |
70 | ## Appendix
71 | * empty_world.launch (Caution: "This is a launch file!")
72 | ```xml
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 | ```
126 |
--------------------------------------------------------------------------------
/Ch6 ROS Gazebo/Ch10 Launch RViz using a configuration file/README.md:
--------------------------------------------------------------------------------
1 | ## Launch RViz using a configuration file
2 | * __.rviz configuration file :__ Save rviz config so that you don't have to reconfigure after roslaunch.
3 |
4 | 1. **Launch rviz**
5 | ```console
6 | [alonzo@study ~/simulation_ws/src/my_robot_description]$ roslaunch my_robot_description rviz.launch
7 | ```
8 | 2. **Configure your rviz in GUI**
9 |
10 | 3. **Select "Save config as" option**
11 |
12 | 4. **Store .rivz in ~/simulation_ws/src/my_robot_description/rviz**
13 |
14 | 5. **Name it (robot.rviz)**
15 |
16 | 6. **Edit rviz.launch file**
17 | ```console
18 | [alonzo@study ~/simulation_ws/src/my_robot_description/launch]$ vim rviz.launch
19 | ```
20 | 7. **Relaunch**
21 | ```console
22 | [alonzo@study ~/simulation_ws/src/my_robot_description/launch]$ roslaunch my_robot_description rviz.launch
23 | ```
24 | ## Source code
25 | * rviz.launch
26 | ```xml
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | ```
47 |
--------------------------------------------------------------------------------
/Ch6 ROS Gazebo/Ch11 Use joint_state_publisher/README.md:
--------------------------------------------------------------------------------
1 | ## Use joint_state_publisher
2 |
3 | 1. **Edit rviz.launch file, change gui to "True"**
4 | * ``
5 |
6 | 2. **Launch rviz**
7 | ```console
8 | $ roslaunch my_robot_description rviz.launch
9 | ```
10 |
11 | 3. **A joint1 terminal apprears on the screen**
12 | 4. **Drag joint bar to rotate joint1 object**
13 |
14 | ## Source code
15 | * rviz.launch
16 | ```xml
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | ```
38 |
39 | ## Appendix
40 | * __ROS node :__
41 | * __`joint_state_publisher`:__
42 | * This package publishes [sensor_msgs/JointState][0] messages for a robot.
43 | * The package reads the __robot_description parameter__ from the parameter server, finds all of the __non-fixed joints__ and publishes a JointState message with all those joints defined.
44 | * __`robot_state_publisher`:__
45 | * robot_state_publisher calculate the forward kinematics of the robot and publish the results via tf.
46 | * Source : URDF specified by the parameter robot_description
47 | * Subscribe topic : `joint_states` (provide joint positions to `robot_state_publisher`)
48 | * Subscribe message type : sensor_msgs/JointState
49 |
50 | [0]:http://docs.ros.org/api/sensor_msgs/html/msg/JointState.html
51 |
--------------------------------------------------------------------------------
/Ch6 ROS Gazebo/Ch12 Create custom gazebo model using heightmap/README.md:
--------------------------------------------------------------------------------
1 | ## Gazebo Heightmap tutorial
2 |
3 | 1. **Install** [**GIMP**][0]
4 |
5 | [0]: https://tecadmin.net/install-gimp-on-ubuntu/
6 |
7 |
8 | 2. **Create a New Image**
9 |
10 | 3. __Select Width and Height value (2**n+1: 129/129, 257/257, 513/513)__
11 | * __Note :__ Gazebo requires these values be equal
12 |
13 | 4. **White is high & Black is low. Thus, start with all black**
14 |
15 | 5. **Draw your terrain**
16 |
17 | 6. **Export as .png file**
18 |
19 | 7. **In ~/.gazebo/models directory, these are models that you used in the past**
20 | ```console
21 | $ cd ~/.gazebo/models
22 | ```
23 | 8. **Create a folder for your model**
24 | ```console
25 | $ mkdir ~/.gazebo/models/custom_lake
26 | ```
27 | 9. **Copy model.sdf & model.config from other model**
28 | ```console
29 | $ cp -rp ~/.gazebo/models/playground ~/.gazebo/models/custom_lake
30 | ```
31 |
32 | 10. **Overwrite model.sdf file**
33 | ```console
34 | $ cp /usr/share/gazebo-9/worlds/heightmap.world model.sdf
35 | ```
36 |
37 | 11. **Edit model.sdf file. Remove tag and "sun" model**
38 |
39 | 12. **Remove all the "box" model in model.sdf**
40 |
41 | ## Source code
42 | * model.sdf
43 | ```xml
44 |
45 |
46 |
47 |
48 | true
49 |
50 |
51 |
52 |
53 |
54 | model://custom_lake/materials/textures/custom_lake.png
55 |
56 |
57 |
58 | 200 200 10
59 | 0 0 0
60 |
61 |
62 |
63 |
64 |
65 |
66 | false
67 |
68 | file://media/materials/textures/dirt_diffusespecular.png
69 | file://media/materials/textures/flat_normal.png
70 | 1
71 |
72 |
73 | file://media/materials/textures/grass_diffusespecular.png
74 | file://media/materials/textures/flat_normal.png
75 | 1
76 |
77 |
78 | file://media/materials/textures/fungus_diffusespecular.png
79 | file://media/materials/textures/flat_normal.png
80 | 1
81 |
82 |
83 | 2
84 | 5
85 |
86 |
87 | 4
88 | 5
89 |
90 |
91 | model://custom_lake/materials/textures/custom_lake.png
92 |
93 |
94 |
95 | 200 200 10
96 | 0 0 0
97 |
98 |
99 |
100 |
101 |
102 |
103 | ```
104 |
--------------------------------------------------------------------------------
/Ch6 ROS Gazebo/Ch2 Add gazebo models to a simulation/README.md:
--------------------------------------------------------------------------------
1 | ## Add gazebo models to a simulation
2 | * Online [__Gazebo models__][0]
3 | * Modify your .world file to import gazebo online models
4 | * empty_world.world
5 | ```xml
6 |
7 |
8 |
9 |
10 |
11 |
12 | model://sun
13 |
14 |
15 |
16 | model://ground_plane
17 |
18 |
19 |
20 |
21 | model://suv
22 | false
23 | 0 0 20 0 0 0
24 |
25 |
26 |
27 | ```
28 |
29 | [0]: https://bitbucket.org/osrf/gazebo_models/src/default/
30 |
--------------------------------------------------------------------------------
/Ch6 ROS Gazebo/Ch3 Spawn a robot in gazebo/README.md:
--------------------------------------------------------------------------------
1 | ## Spawn a robot in gazebo
2 |
3 | 1. **Clone this repository (two-wheeled-robot-simulation pkg)**
4 | ```console
5 | [alonzo@study ~/simulation_ws/src]$ git clone https://bitbucket.org/theconstructcore/two-wheeled-robot-simulation
6 | ```
7 |
8 | 2. **View .xacro file**
9 | ```console
10 | [alonzo@study ~/simulation_ws/src/two-wheeled-robot-simulation/urdf]$ vim m2wr.xacro
11 | ```
12 |
13 | 3. **View .launch file**
14 | ```console
15 | [alonzo@study ~/simulation_ws/src/two-wheeled-robot-simulation/launch]$ vim spawn.launch
16 | ```
17 |
18 | 4. **Launch**
19 | ```console
20 | [alonzo@study ~/simulation_ws/src/two-wheeled-robot-simulation/launch]$ roslaunch two-wheeled-robot-simulation spawn.launch
21 | ```
22 |
23 | ## Source code
24 | * m2wr.xacro
25 | ```xml
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | 0 0 0.1 0 0 0
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | 0
64 | 0
65 | 1.0
66 | 1.0
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 | ```
115 |
116 | * spawn.launch
117 | ```
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
145 |
146 |
147 |
148 | ```
149 |
--------------------------------------------------------------------------------
/Ch6 ROS Gazebo/Ch4 Create a gazebo model using SDF/README.md:
--------------------------------------------------------------------------------
1 | ## Create a gazebo model (Not Robot!) using SDF
2 |
3 | * __SDF__ v.s. __URDF__
4 | * SDF : SDF is used for entire robotic simulation environments.
5 | * URDF : Only for robot description.
6 |
7 | 1. **Create a directory for gazebo model in a ros package**
8 | ```console
9 | [alonzo@study ~/simulation_ws/src/my_simulations]$ mkdir models
10 | [alonzo@study ~/simulation_ws/src/my_simulations/models]$ mkdir {your_model_name}
11 | [alonzo@study ~/simulation_ws/src/my_simulations/models]$ mkdir my1stmodel
12 | ```
13 |
14 | 2. **Create .sdf and .config**
15 | ```console
16 | [alonzo@study ~/simulation_ws/src/my_simulations/models/my1stmodel]$ model.sdf
17 | [alonzo@study ~/simulation_ws/src/my_simulations/models/my1stmodel]$ model.config (paste code)
18 | ```
19 |
20 | 4. **Add model path to env param GAZEBO_MODEL_PATH**
21 | ```console
22 | [alonzo@study ~/simulation_ws/src/my_simulations/models/my1stmodel]$ GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:{your_model_model_path}
23 | [alonzo@study ~/simulation_ws/src/my_simulations/models/my1stmodel]$ GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:/home/ual/simulation_ws/src/my_simulations/models
24 | ```
25 | 5. **Modify .world file, "include" your model**
26 | ```console
27 | [alonzo@study ~/simulation_ws/src/my_simulations/world]$ vim empty_world.world
28 | # > Add : model://my1stmodel
29 | ```
30 |
31 | 6. **Launch**
32 | ```console
33 | [alonzo@study ~/simulation_ws/src/my_simulations/world]$ roslaunch my_simulations my_world.launch
34 | ```
35 | ## Source code
36 | * model.sdf
37 | ```xml
38 |
39 |
40 |
41 | true
42 |
43 |
44 |
45 |
46 | 3 2 5
47 |
48 |
49 |
50 |
51 |
52 | 100
53 | 50
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | 3 2 5
62 |
63 |
64 |
65 |
69 |
70 |
71 |
72 |
73 |
74 | ```
75 |
76 | * model.config
77 | ```xml
78 |
79 |
80 |
81 | My 1st model
82 | 1.0
83 | model.sdf
84 |
85 |
86 | Logan Zhang
87 | r07525074@ntu.edu.tw
88 |
89 |
90 |
91 | This is my first model for gazebo.
92 |
93 |
94 | ```
95 |
96 | * empty_world.world
97 | ```xml
98 |
99 |
100 |
101 |
102 |
103 | model://sun
104 |
105 |
106 |
107 | model://ground_plane
108 |
109 |
110 |
111 |
112 |
113 | model://my1stmodel
114 |
115 | false
116 | 0 0 5 0 0 0
117 |
118 |
119 |
120 | ```
121 |
--------------------------------------------------------------------------------
/Ch6 ROS Gazebo/Ch5 Use a mesh file to create a gazebo model/README.md:
--------------------------------------------------------------------------------
1 | ## How to use a mesh file to create a gazebo model
2 | 1. **Create meshes folders**
3 | ```console
4 | [alonzo@study ~/simulation_ws/src/my_simulations/models/my1stmodel/]$ mkdir meshes
5 | ```
6 |
7 | 2. **Download .stl file from my github repo to /meshes folder**
8 |
9 | 3. __Modify .sdf file, change box to mesh (Both "collision" and "visual" tag)__
10 | ```console
11 | [alonzo@study ~/simulation_ws/src/my_simulations/models/my1stmodel/]$ vim model.sdf
12 | ```
13 |
14 | 4. **Launch file**
15 | ```console
16 | [alonzo@study ~/simulation_ws/src/my_simulations/models/my1stmodel/]$ roslaunch my_simulations my_world.launch
17 | ```
18 |
19 | ## Source code
20 | * model.sdf
21 | ```xml
22 |
23 |
24 |
25 | true
26 |
27 |
28 |
29 |
30 |
31 | model://my1stmodel/meshes/robot_car.stl
32 |
33 |
34 | 0.01 0.01 0.01
35 |
36 |
37 |
38 |
39 |
40 | 100
41 | 50
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | model://my1stmodel/meshes/robot_car.stl
51 |
52 |
53 | 0.01 0.01 0.01
54 |
55 |
56 |
57 |
61 |
62 |
63 |
64 |
65 |
66 | ```
67 |
--------------------------------------------------------------------------------
/Ch6 ROS Gazebo/Ch5 Use a mesh file to create a gazebo model/cordless_drill.stl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch6 ROS Gazebo/Ch5 Use a mesh file to create a gazebo model/cordless_drill.stl
--------------------------------------------------------------------------------
/Ch6 ROS Gazebo/Ch5 Use a mesh file to create a gazebo model/robot_car.stl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch6 ROS Gazebo/Ch5 Use a mesh file to create a gazebo model/robot_car.stl
--------------------------------------------------------------------------------
/Ch6 ROS Gazebo/Ch6 Use an image file as texture for gazebo model/README.md:
--------------------------------------------------------------------------------
1 | ## How to use an image file as texture for gazebo model
2 | 1. **Create materials/scripts and materials/textures folder**
3 | ```console
4 | [alonzo@study ~/simulation_ws/src/my_simulations/models/my1stmodel/]$ mkdir scripts texture
5 | ```
6 | 2. **Touch .material file in scripts folder**
7 | ```console
8 | [alonzo@study ~/simulation_ws/src/my_simulations/models/my1stmodel/scripts]$ touch robot_car.material
9 | ```
10 | 3. **Edit .material file**
11 | ```console
12 | [alonzo@study ~/simulation_ws/src/my_simulations/models/my1stmodel/scripts]$ vim robot_car.material
13 | ```
14 | 4. **Download .png file from my github repo and store it inside the texture folder**
15 |
16 | 5. **Modify .sdf file "visual" tag**
17 | ```console
18 | [alonzo@study ~/simulation_ws/src/my_simulations/models/my1stmodel]$ vim model.sdf
19 | ```
20 | 6. **Launch**
21 | ```console
22 | [alonzo@study ~/simulation_ws/src/my_simulations/models/my1stmodel/]$ roslaunch my_simulations my_world.launch
23 | ```
24 | ## Source code
25 | * robot_car.material
26 | ```console
27 | material robot_car/Diffuse # name of your material
28 | { # Same as Gazebo/Grey in .sdf file
29 | recieve_shadows off
30 | technique
31 | {
32 | pass
33 | {
34 | texture_unit
35 | {
36 | texture seamless_texture.png # texture file
37 | }
38 | }
39 | }
40 | }
41 | ```
42 |
43 |
44 | * model.sdf
45 | ```xml
46 |
47 |
48 |
49 | true
50 |
51 |
52 |
53 |
54 | model://my1stmodel/meshes/robot_car.stl
55 |
56 | 0.01 0.01 0.01
57 |
58 |
59 |
60 |
61 |
62 | 100
63 | 50
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | model://my1stmodel/meshes/robot_car.stl
72 |
73 |
74 | 0.01 0.01 0.01
75 |
76 |
77 |
78 |
84 |
85 |
86 |
87 |
88 |
89 | ```
90 |
--------------------------------------------------------------------------------
/Ch6 ROS Gazebo/Ch6 Use an image file as texture for gazebo model/seamless_texture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch6 ROS Gazebo/Ch6 Use an image file as texture for gazebo model/seamless_texture.png
--------------------------------------------------------------------------------
/Ch6 ROS Gazebo/Ch7 Create a robot using URDF/README.md:
--------------------------------------------------------------------------------
1 | ## Create a robot using URDF
2 |
3 | 1. **Create a pkg for your robot**
4 | ```console
5 | [alonzo@study ~/simulation_ws/src]$ catkin_create_pkg my_robot_description # No dependcies
6 | ```
7 |
8 | 2. **Create folder urdf & launch in my_robot_description pkg**
9 | ```console
10 | [alonzo@study ~/simulation_ws/src/my_robot_description]$ mkdir urdf launch
11 | ```
12 | 3. **Create .urdf file and edit**
13 | ```console
14 | [alonzo@study ~/simulation_ws/src/my_robot_description/urdf]$ touch robot.urdf
15 | ```
16 |
17 | 4. **Create .launch file in launch folder**
18 | ```console
19 | [alonzo@study ~/simulation_ws/src/my_robot_description/urdf]$ touch spawn.launch
20 | ```
21 |
22 | 5. **Launch**
23 | ```console
24 | [alonzo@study ~/simulation_ws/src/my_robot_description/urdf]$ roslaunch my_robot_description spawn.launch
25 | ```
26 |
27 | ## Source code
28 | * robot.urdf
29 | ```xml
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | 0 0 0.1 0 0 0
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 | ```
66 |
67 | * spawn.launch
68 | ```xml
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
97 |
98 |
99 |
100 | ```
101 |
--------------------------------------------------------------------------------
/Ch6 ROS Gazebo/Ch8 Visualize a robot URDF using RVIZ/README.md:
--------------------------------------------------------------------------------
1 | ## How to visualize a robot URDF using RVIZ
2 | 1. **Create rviz.launch in launch folder**
3 | ```console
4 | [alonzo@study ~/simulation_ws/src/my_robot_description/launch]$ touch rviz.launch
5 | ```
6 |
7 | 2. **Launch**
8 | ```console
9 | [alonzo@study ~/simulation_ws/src/my_robot_description/launch]$ roslaunch my_robot_description rviz.launch
10 | ```
11 | 3. **In Rviz GUI, press Add**
12 | 4. **Choose RobotModel option**
13 | 5. **To remove error, change global options "Fixed Frame: map" to link_chassis**
14 |
15 | ## Source code
16 | * rviz.launch
17 | ```xml
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | ```
39 |
--------------------------------------------------------------------------------
/Ch6 ROS Gazebo/Ch9 Create a robot using URDF(Advance & RVIZ)/README.md:
--------------------------------------------------------------------------------
1 | ## Create a robot using URDF (Advance + RVIZ)
2 | 1. **Edit .urdf, and link and joint**
3 | ```console
4 | [alonzo@study ~/simulation_ws/src/my_robot_description/urdf]$ vim robot.urdf
5 | ```
6 |
7 | 2. **Launch**
8 | ```console
9 | [alonzo@study ~/simulation_ws/src/my_robot_description]$ roslaunch my_robot_description rviz.launch
10 | ```
11 |
12 | 3. **In Rviz GUI, press Add**
13 | 4. **Choose RobotModel option**
14 | 5. **To remove error, change global options "Fixed Frame: map" to link_chassis**
15 |
16 | ## Source code
17 | * robot.urdf
18 | ```xml
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | 0 0 0.1 0 0 0
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | 0 0 0.1 0 0 0
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 | ```
90 |
--------------------------------------------------------------------------------
/Ch7 ROS Virtual RobotX/Ch01_Adding_Course_Elements.md:
--------------------------------------------------------------------------------
1 | ## Adding course elements
2 |
3 | 1. **Create a ros pkg**
4 | ```console
5 | $ catkin_create_pkg example_vrx_package
6 | ```
7 |
8 | 2. **Create a worlds folder for .world and .xacro**
9 | ```console
10 | $ mkdir worlds
11 | ```
12 |
13 | 3. **Copy .xacro file from source pkg**
14 | ```console
15 | $ roscp vrx_gazebo example_course.world.xacro .
16 | ```
17 |
18 | 4. **Modify .xcro file (Add new module)**
19 |
20 |
21 | 5. **Generate the compiled XML from the xacro file ("compile" your xacro files into static XML)**
22 | ```console
23 | $ rosrun xacro xacro --inorder example_course.world.xacro > my_world.world
24 | ```
25 |
26 | 6. **Run simulation**
27 | ```console
28 | $ roslaunch vrx_gazebo sandisland.launch world:=`pwd`/my_world.world
29 | ```
30 |
31 | ## Source code
32 | * __VRX example launch file: (vrx_gazebo) sandisland.launch__
33 | * Create vrx model from `example_course.world.xacro` (Default)
34 | * Generate wamv robot urdf using `wamv_gazebo.urdf.xacro`
35 | * Spawn wamv robot
36 |
37 | ```xml
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
103 |
104 |
105 |
109 |
110 |
114 |
115 | ```
116 |
117 | * __VRX example world file : example_course.world.xacro__
118 | ```xml
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 | model://robotx_navigation_challenge
134 | 58 68 2 0 0 0.4
135 |
136 |
137 | model://robotx_light_buoy
138 | 110 28 0.25 0 0 0
139 |
140 |
141 | model://robotx_2016_qualifying_pinger_transit
142 | 55 -50 0 0 0 -1.3
143 |
144 |
145 |
146 |
147 | model://dock_2016
148 | 75 22 0.0 0 0 -2.78
149 |
150 |
151 |
152 |
153 | model://dock_2018
154 | -2 -18 0.0 0 0 0.2
155 |
156 |
157 |
158 |
159 |
160 | wamv
161 | base_link
162 | .5 .5 .33
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 | model://polyform_a3
171 |
172 | -10 2 0 0 0 0
173 |
174 |
175 | model://polyform_a7
176 | -15 8 0 0 0 0
177 |
178 |
179 | model://surmark950400
180 | -12.5 -3 0 0 0 0
181 |
182 |
183 |
184 |
185 |
186 | ```
187 |
188 |
189 | * __WAMV robot example xacro: wamv_gazebo.urdf.xacro__
190 | ```xml
191 |
192 |
193 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 | wamv::base_link
265 | wamv_external_link
266 |
267 | 1 0 0
268 |
269 |
270 | 0 1 0
271 |
272 |
273 |
274 | world
275 | wamv_external_link
276 |
277 |
278 | -3
279 | 3
280 |
281 | 0 0 1
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 | ```
361 |
362 | ## Working with xacro files
363 | ### What is xacro?
364 | * A programmable xml file
365 | ### Functionality
366 | * Include other files
367 | * Define functions, store variables(macros).
368 | * VRX packages make heavy use of xacro to reduce code reuse and make composing new models/worlds easy.
369 |
370 | ### Generating XML from xacro
371 | * __From Terminal:__ To generate `my_wamv.urdf` from `my_wamv.urdf.xacro`, run this command:
372 | `$ rosrun xacro xacro --inorder my_wamv.urdf.xacro -o my_wamv.urdf`
373 | * __In CMakeLists.txt:__ (Allows you to find this issue at build time, not runtime)
374 | ```
375 | find_package(catkin REQUIRED COMPONENTS
376 | xacro <= Add this line
377 | )
378 | ```
379 | ```
380 | xacro_add_files(
381 | worlds/example_course.world.xacro
382 | INORDER INSTALL DESTINATION worlds <= This will generate devel/share/worlds/your_project_name/example_course.world in your workspace.
383 | )
384 | ```
385 | * __In launch file:__
386 | ```
387 |
388 |
389 |
390 |
391 |
392 |
393 | ```
394 |
395 | ### Using Macros
396 | Here is an example macro included to create a gazebo camera sensor with the ROS plugin.
397 | * __wamv_camera.xacro__ (ROS plugin/Xacro template)
398 | ```xml
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 | ...
409 |
410 |
411 | ```
412 | * __.urdf file__
413 | ```xml
414 |
415 |
417 | ...
418 |
419 |
420 |
421 |
422 | ...
423 |
424 | ```
425 |
426 |
427 |
--------------------------------------------------------------------------------
/Ch7 ROS Virtual RobotX/Ch02_Custom_WAM-V_Thruster_Sensor_Configuration.md:
--------------------------------------------------------------------------------
1 | ## Custom WAM-V Thruster and Sensor Configuration
2 |
3 | 1. **Make a directory for your custom WAM-V**
4 | ```console
5 | $ mkdir ~/my_wamv
6 | ```
7 | 2. **Touch and edit .yaml file**
8 | ```console
9 | $ vim ~/my_wamv/sensor_config.yaml
10 | $ vim ~/my_wamv/thruster_config.yaml
11 | ```
12 |
13 | 3. **Generate .urdf from launch file**
14 | * Usage:
15 | `roslaunch vrx_gazebo generate_wamv.launch thruster_yaml:={ } sensor_yaml:={ } wamv_target:={ }`
16 |
17 | * Params:
18 | * thruster_yaml: Input, the full path of the thruster YAML
19 | * sensor_yaml: Input, the full path of the sensor YAML configuration
20 | * wamv_target: Output, the path where WAM-V URDF will be generated
21 |
22 | * Note:
23 | 1. If yaml path is not given, it uses default thruster/sensor yaml
24 | 2. Create WAM-V with no thruster and no sensors
25 | * thruster_yaml : empty_thruster_config.yaml
26 | * sensor_yaml : empty_sensor_config.yaml
27 | ```console
28 | # Case 1
29 | $ roslaunch vrx_gazebo generate_wamv.launch thruster_yaml:=$HOME/my_wamv/thruster_config.yaml sensor_yaml:=$HOME/my_wamv/sensor_config.yaml wamv_target:=$HOME/my_wamv/my_wamv.urdf
30 |
31 | # Case2
32 | $ roslaunch vrx_gazebo generate_wamv.launch thruster_yaml:=$HOME/my_wamv/thruster_config.yaml sensor_yaml:=$HOME/my_wamv/sensor_config.yaml wamv_target:=$HOME/my_wamv/my_wamv_2.urdf
33 |
34 | # Case 3 (Non-compliant)
35 | $ roslaunch vrx_gazebo generate_wamv.launch thruster_yaml:=$HOME/my_wamv/thruster_config.yaml sensor_yaml:=$HOME/my_wamv/sensor_config.yaml wamv_target:=$HOME/my_wamv/my_wamv_3.urdf
36 | ```
37 |
38 | 4. **Launch the example world with your WAM-V**
39 | ```console
40 | # Case 1
41 | $ roslaunch vrx_gazebo sandisland.launch urdf:=$HOME/my_wamv/my_wamv.urdf
42 |
43 | # Case 2
44 | $ roslaunch vrx_gazebo sandisland.launch urdf:=$HOME/my_wamv/my_wamv_2.urdf
45 |
46 | # Case 3
47 | $ roslaunch vrx_gazebo sandisland.launch urdf:=$HOME/my_wamv/my_wamv_3.urdf
48 | ```
49 | ## Source code
50 | * sensor_config.yaml
51 | ```
52 | wamv_camera:
53 | - name: front_left_camera
54 | x: 0.75
55 | y: 0.1
56 | P: ${radians(15)}
57 | - name: front_right_camera
58 | x: 0.75
59 | y: -0.1
60 | P: ${radians(15)}
61 | - name: middle_right_camera
62 | x: 0.75
63 | y: 0.3
64 | P: ${radians(15)}
65 | wamv_gps:
66 | - name: gps_wamv
67 | x: -0.85
68 | wamv_imu:
69 | - name: imu_wamv
70 | y: -0.2
71 | wamv_p3d:
72 | - name: p3d_wamv
73 | lidar:
74 | - name: lidar_wamv
75 | type: 16_beam
76 | P: ${radians(8)}
77 | ```
78 | ```
79 | # Removed all cameras
80 |
81 | wamv_gps:
82 | - name: gps_wamv
83 | x: -0.85
84 | wamv_imu:
85 | - name: imu_wamv
86 | y: -0.2
87 | wamv_p3d:
88 | - name: p3d_wamv
89 | lidar:
90 | - name: lidar_wamv
91 | type: 16_beam
92 | P: ${radians(8)}
93 | ```
94 | * __Non-compliant__ sensor_config.yaml
95 | ```
96 | # Too many cameras
97 | wamv_camera:
98 | - name: front_left_camera
99 | x: 0.75
100 | y: 0.1
101 | P: ${radians(15)}
102 | - name: front_right_camera
103 | x: 0.75
104 | y: -0.1
105 | P: ${radians(15)}
106 | - name: front_far_left_camera
107 | x: 0.75
108 | y: 0.3
109 | P: ${radians(15)}
110 | - name: front_far_right_camera
111 | x: 0.75
112 | y: -0.3
113 | P: ${radians(15)}
114 | - name: middle_left_camera
115 | x: 0.6
116 | y: 0.4
117 | P: ${radians(15)}
118 | Y: ${radians(90)}
119 | post_Y: ${radians(90)}
120 | ```
121 | * thruster_config.yaml
122 | ```
123 | engine:
124 | - prefix: "left"
125 | position: "-2.373776 1.027135 0.318237"
126 | orientation: "0.0 0.0 0.0"
127 | - prefix: "right"
128 | position: "-2.373776 -1.027135 0.318237"
129 | orientation: "0.0 0.0 0.0"
130 | ```
131 | ```
132 | engine:
133 | - prefix: "left"
134 | position: "-2.373776 1.027135 0.318237"
135 | orientation: "0.0 0.0 0.0"
136 | - prefix: "right"
137 | position: "-2.373776 -1.027135 0.318237"
138 | orientation: "0.0 0.0 0.0"
139 |
140 | # Adding new thruster
141 | - prefix: "middle"
142 | position: "0 0 0.318237"
143 | orientation: "0.0 0.0 0.0"
144 | ```
145 | * __Non-compliant__ thruster_config.yaml
146 | ```
147 | engine:
148 | - prefix: "left"
149 | position: "-2.373776 1.027135 0.318237"
150 | orientation: "0.0 0.0 0.0"
151 | - prefix: "right"
152 | position: "-2.373776 -1.027135 0.318237"
153 | orientation: "0.0 0.0 0.0"
154 |
155 | # Adding new thruster in non-compliant position
156 | - prefix: "second_right"
157 | position: "-2.373776 -1.027135 0.318237"
158 | orientation: "0.0 0.0 0.0"
159 | ```
160 |
161 | * generate_wamv.launch
162 | ```xml
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 | ```
197 |
198 | * sandisland.launch
199 | ```xml
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
263 |
264 |
265 |
266 |
270 |
271 |
275 |
276 | ```
277 |
278 | ## Compliance rules
279 | 1. All sensors must be contained within one of the sensor bounding boxes.
280 | 2. All thrusters must be contained within one of the thruster bounding boxes.
281 | 3. The number of each sensor and thruster in the configuration must be within the limit.
282 | 4. For thrusters, there can only be one thruster in each bounding box.
283 | * If you call __generate_wamv.launch__ on __non-compliant configuration YAML files__, red error messages will be printed but the URDF file will still be created. However, it is not a valid configuration for the VRX competition.
284 |
285 | * `generate_wamv.launch`: (generate_wamv python exe => import configure_wamv.py)
286 | * Input: Thruster/Sensor configurations YAML files
287 | * Output: Robot urdf file
288 | * Check YAML files compliance
289 | * Generate xacro files from YAML (YAML -> xacro)
290 | * Generate urdf file (xacro -> urdf -> robot)
291 | * In fact, it's configure_wamv.py doing all the stuff.(Compliance -> YAML -> xacro -> urdf)
292 | * To understand how to convert YAML to urdf, check out __configure_wamv.py__
293 |
294 | * __Thruster/Sensor Required Parameters in thruster/sensor_config.yaml__
295 | * In __wamv_camera.xacro__: (Import/Use by generate_wamv/configure_wamv.py(?) to generate wamv urdf)
296 | ```xml
297 |
298 | ```
299 | * Required params: name (Must define in sensor_config.yaml)
300 | * Default params: x,y,z,R,P,Y
301 | * In __engine.xacro__:
302 | ```xml
303 |
304 | ```
305 | * Required params: prefix (Must define in thruster_config.yaml)
306 | * Default params: position, orientation
307 |
308 |
309 | ## Boundary & Limitations
310 | * Sensor bounding box:
311 | ```
312 | sensor_compliance_for:
313 | pose: '0.8 0 1.8 0 0 0'
314 | size: '1 1 1'
315 | capacity: '-1'
316 | sensor_compliance_aft:
317 | pose: '-0.9 0 1.8 0 0 0'
318 | size: '0.5 1 1'
319 | capacity: '-1'
320 | ```
321 | * Thruster bounding box:
322 | ```
323 | thruster_compliance_port_aft:
324 | pose: '-2.25 1 0 0 0 0'
325 | size: '1 1 1.2'
326 | capacity: '1'
327 | thruster_compliance_star_aft:
328 | pose: '-2.25 -1 0 0 0 0'
329 | size: '1 1 1.2'
330 | capacity: '1'
331 | thruster_compliance_port_for:
332 | pose: '1 1 0 0 0 0'
333 | size: '1 1 1.2'
334 | capacity: '1'
335 | thruster_compliance_star_for:
336 | pose: '1 -1 0 0 0 0'
337 | size: '1 1 1.2'
338 | capacity: '1'
339 | thruster_compliance_middle:
340 | pose: 0.25 0 0 0 0 0
341 | size: '2.5 1 1.2'
342 | capacity: '1'
343 | ```
344 | * Sensor configuration limit
345 | ```
346 | wamv_camera:
347 | num: 3
348 | allowed_params:
349 | x
350 | y
351 | z
352 | R
353 | P
354 | Y
355 | name
356 | post_Y
357 |
358 | wamv_gps:
359 | num: 1
360 | allowed_params:
361 | x
362 | y
363 | z
364 | R
365 | P
366 | Y
367 | name
368 | post_Y
369 |
370 | wamv_imu:
371 | num: 1
372 | allowed_params:
373 | x
374 | y
375 | z
376 | R
377 | P
378 | Y
379 | name
380 | post_Y
381 |
382 | lidar:
383 | num: 2
384 | allowed_params:
385 | x
386 | y
387 | z
388 | R
389 | P
390 | Y
391 | name
392 | post_Y
393 | type
394 |
395 | wamv_p3d:
396 | num: 0
397 | allowed_params:
398 | name
399 | ```
400 | * Thruster configuration limit
401 | ```
402 | engine:
403 | num: 4
404 | allowed_params:
405 | prefix
406 | position
407 | orientation
408 |
409 | ```
410 |
--------------------------------------------------------------------------------
/Ch7 ROS Virtual RobotX/Ch03_Propulsion_Configurations.md:
--------------------------------------------------------------------------------
1 | ## Propulsion Configurations
2 |
3 |
4 |
5 |

6 |
7 |
8 |
9 | * __"H": Differential Thrust :__ Two, Fixed Stern Thrusters (Default)
10 | ```console
11 | $ roslaunch vrx_gazebo sandisland.launch
12 | ```
13 |
14 |
15 |
16 |

17 |
18 |
19 |
20 | * __"T": Differential Thrust :__ An Additional Lateral/Bow Thruster
21 | ```console
22 | $ roslaunch vrx_gazebo sandisland.launch thrust_config:=T
23 | ```
24 |
25 |
26 |
27 |

28 |
29 |
30 |
31 | * __"X": Holonomic Thruster :__ Configuration with Four Fixed Thrusters
32 | ```console
33 | $ roslaunch vrx_gazebo sandisland.launch thrust_config:=X
34 | ```
35 |
36 |
37 |
38 |

39 |
40 |
41 |
--------------------------------------------------------------------------------
/Ch7 ROS Virtual RobotX/Ch04_Adding_Sensors.md:
--------------------------------------------------------------------------------
1 | ## Adding Sensors
2 |
3 | Create your own robot description file (URDF) for a custom WAM-V with your choice of sensors.
4 |
5 | 1. **Copy `wamv_gazebo wamv_gazebo.urdf.xacro`**
6 | ```console
7 | $ roscp wamv_gazebo wamv_gazebo.urdf.xacro my_wamv.urdf.xacro
8 | ```
9 |
10 | 2. **Modify `my_wamv.urdf.xacro` (Remove all sensors on wamv and add lines below)**
11 | ```xml
12 |
13 |
14 |
15 | ```
16 |
17 | * __Note :__
18 | * A common property "stereo_x" is used so the value is not copied in multiple places
19 | * The x,y,z and P (pitch) set where the cameras are located **relative to the WAM-V base link**
20 | * A Python expression ${radians(15)} was used to convert 15 degrees to radians
21 |
22 | 3. **Compile xacro file**
23 | ```console
24 | $ rosrun xacro xacro --inorder my_wamv.urdf.xacro > my_wamv.urdf
25 | ```
26 | 4. **Launch**
27 | ```console
28 | $ roslaunch vrx_gazebo sandisland.launch urdf:=`pwd`/my_wamv.urdf
29 | ```
30 | ## Source file
31 | * my_wamv.urdf.xacro
32 | ```xml
33 |
34 |
35 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 | wamv::base_link
105 | wamv_external_link
106 |
107 | 1 0 0
108 |
109 |
110 | 0 1 0
111 |
112 |
113 |
114 | world
115 | wamv_external_link
116 |
117 |
118 | -3
119 | 3
120 |
121 | 0 0 1
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 | ```
134 |
--------------------------------------------------------------------------------
/Ch7 ROS Virtual RobotX/Ch05_Thruster_Articulation.md:
--------------------------------------------------------------------------------
1 | ## Thruster Articulation
2 |
3 | 1. **Check out wamv_gazebo_thruster_config.xacro**
4 | ```console
5 | $ roscd wamv_gazebo/urdf/thruster_layouts
6 | $ vim wamv_gazebo_thruster_config.xacro
7 | ```
8 | 2. **Launch**
9 | ```console
10 | $ roslaunch vrx_gazebo sandisland.launch
11 | ```
12 |
13 | 3. **Run rqt_publisher to see params in topic**
14 | ```console
15 | $ rosrun rqt_publisher rqt_publisher
16 | ```
17 |
18 | 4. **Click on the __topic dropdown menu__ and select:**
19 | * Topic `left_thrust_cmd`
20 | * Topic `left_thrust_angle`
21 | * Topic `right_thrust_cmd`
22 | * Topic `right_thrust_angle`
23 |
24 | 5. **Press plus sign on the right side to display select topic**
25 | 6. **Change the number by double clicking the value of the data**
26 | 7. **Click the box to start publishing**
27 | * __Note :__
28 | * `Ctrl+Shift+R` to restart wamv position in Gazebo
29 | * `left/right_thrust_angle` value range from +1.57 to -1.57 (+90 degrees ~ -90 degrees)
30 | * If value > +1.57, value = 1.57
31 | * If value < -1.57, value = -1.57
32 |
33 | ## Source code
34 | * wamv_gazebo_thruster_config.xacro
35 | ```xml
36 |
37 |
38 |
39 |
40 |
41 | ${name}_propeller_link
42 | ${name}_engine_propeller_joint
43 | ${name}_chasis_engine_joint
44 | ${name}_thrust_cmd
45 |
46 |
47 | ${name}_thrust_angle
48 |
49 | true
50 |
51 |
52 | 1
53 | 1.0
54 | 250.0
55 | -100.0
56 | ${pi/2}
57 |
58 |
59 |
60 | ```
61 |
62 |
--------------------------------------------------------------------------------
/Ch7 ROS Virtual RobotX/Ch06_Driving.md:
--------------------------------------------------------------------------------
1 | ## Driving
2 |
3 | 1. **Launch simulation**
4 | ```console
5 | $ roslaunch vrx_gazebo sandisland.launch
6 | ```
7 |
8 | 2. __Teleoperation :__
9 | 1. __rostopic pub__
10 | ```console
11 | $ rostopic pub --once /right_thrust_cmd std_msgs/Float32 "data: 1.0"
12 | ```
13 | * This command will timeout after a pre-determined amount of time
14 | * Default is 1.0 s, but can be changed in the __wamv_gazebo_thruster_config.xacro__
15 | * `1.0`
16 | 2. __Keyboard__
17 | ```console
18 | $ roslaunch vrx_gazebo usv_keydrive.launch
19 | ```
20 | * Make sure node `/twist2thrust` is publishing cmd to topic `left/right_thrust_cmd`(which gazebo is subscribing)
21 |
22 |
23 |
24 |

25 |
26 |
27 |
28 | * If gazebo isn't getting any message from node `/twist2thrust` (as shown in figure)
29 | * Modify `~/vrx_ws/src/vrx/vrx_gazebo/launch/usv_keydrive.launch`
30 | * Change `/wamv/thrusters/left_thrust_cmd` to `left_thrust_cmd`
31 |
32 | ```xml
33 |
34 |
35 | ```
36 |
37 |
38 |
39 |

40 |
41 |
42 |
43 | * Debug:
44 | * `rosrun rqt_graph rqt_graph`
45 | * `rosnode/rostopic info/list`
46 |
47 |
48 |
49 |
50 |

51 |
52 |
53 |
54 | 3. __Gamepad__
55 | ```console
56 | $ roslaunch vrx_gazebo usv_joydrive.launch
57 | ```
58 |
59 |
60 |
--------------------------------------------------------------------------------
/Ch7 ROS Virtual RobotX/Ch07_Visualizing_with_RViz.md:
--------------------------------------------------------------------------------
1 | ## Visualizing with RViz
2 |
3 | 1. __Launching Gazebo__
4 |
5 | ```console
6 | $ roslaunch vrx_gazebo vrx.launch camera_enabled:=true gps_enabled:=true imu_enabled:=true
7 | ```
8 |
9 | 2. __Publishing a TF tree__
10 | * __Node :__ `robot_state_publisher`
11 | * `robot_state_publisher` will publish all the fixed/non-fixed joints in your URDF to the TF tree based on messages published to `/JointStates`.
12 | * `robot_state_publisher` is also in charge of deciding the relationship between map/odom/base_link (Rviz Frame).
13 | * Method 1:
14 | If you are using the example wamv_gazebo.urdf, run
15 |
16 | ```console
17 | $ roslaunch wamv_gazebo localization_example.launch
18 | ```
19 | * Note : Odom frame
20 |
21 | * Method 2:
22 | Using a custom URDF without the standard GPS/IMU configuration, run the `robot_state_publisher`
23 | ```console
24 | $ rosrun robot_state_publisher robot_state_publisher
25 | ```
26 |
27 | 3. Running RViz
28 | ```console
29 | $ roslaunch wamv_gazebo rviz_vrx.launch
30 | ```
31 |
--------------------------------------------------------------------------------
/Ch7 ROS Virtual RobotX/Ch08_Plugin_Parameters.md:
--------------------------------------------------------------------------------
1 | ## Plugin Parameters
2 |
3 | * __Changing the Wind__
4 | * __sandisland.world.xacro__ include __usv_wind_plugin.xacro__
5 | * Determine params such as __wind coefficient__ in __sandisland.world.xacro__
6 | * Specify that the wind forces should be applied to the `wamv` model(?)
7 |
8 | * Method 1: Modify __usv_wind_plugin.xacro__
9 | ```xml
10 |
11 |
12 |
21 |
22 |
23 |
24 |
25 |
26 | ${direction}
27 | ${mean_vel}
28 | ${var_gain}
29 | ${var_time}
30 | ${seed}
31 | ${ros_update_rate}
32 |
33 |
34 |
35 | ```
36 | Note: Don't forget `catkin_make` before `roslaunch vrx_gazebo sandisland.launch`
37 |
38 | * Method 2: Modify __sandisland.world.xacro__ (X)
39 | ```xml
40 |
41 |
42 |
43 |
44 | wamv
45 | 8 <= Change Here! (X)
46 | base_link
47 | 0.5 0.5 0.33
48 |
49 |
50 |
51 | ```
52 | Note: Any number of wind_obj's may be added under wind_objs. Only one link per model is supported.
53 | Note: Don't forget `catkin_make` before `roslaunch vrx_gazebo sandisland.launch`
54 |
55 |
56 | * Ways to change the wind plugin parameters:
57 | * Change the default wind parameters in __usv_wind_plugin.xacro__
58 | * Override the default parameters in the __sandisland.world.xacro__
59 | * Change the __models affected by wind__(?) or their coefficients in __sandisland.world.xacro__
60 | * Make sure to run `catkin_make` after any changes to process the XML macros.
61 |
62 | * __Changing the Wave Field__
63 | * Plugin file: `wave_gazebo/world_models/ocean_waves/model.xacro`
64 | * World file: `vrx_gazebo/worlds/example_course.world.xacro`
65 | ```xml
66 |
67 |
68 |
69 |
70 | ```
71 |
72 | * Create ane environment without waves:
73 | * Method 1: Modify `wave_gazebo/world_models/ocean_waves/model.xacro`
74 | ```xml
75 |
78 | ```
79 | Note: Don't forget `catkin_make` before `roslaunch vrx_gazebo vrx.launch`
80 |
81 |
82 | * Method 2: Modify `vrx_gazebo/worlds/example_course.world.xacro`
83 | ```xml
84 |
85 |
86 | <= Change Here!
87 | ```
88 | Note: Don't forget `catkin_make` before `roslaunch vrx_gazebo vrx.launch`
89 |
90 | * __Changing Fog and Ambient Lighting__
91 | * Modify `vrx_gazebo/worlds/sandisland.xacro`
92 | ```xml
93 |
94 |
95 |
96 | 12
97 |
98 |
99 | 0
100 | 0
101 | => Add tag
102 | linear
103 | 0.7 0.7 0.7 1
104 | 0.0
105 |
106 | 1.0 1.0 1.0 1 => Add tag
107 |
108 | ```
109 | Note: Don't forget `catkin_make` before `roslaunch vrx_gazebo sandisland.launch`
110 |
--------------------------------------------------------------------------------
/Ch7 ROS Virtual RobotX/Ch09_Custom_Dock.md:
--------------------------------------------------------------------------------
1 | ## Custom Dock
2 |
3 | 1. Create a new folder for your custom dock
4 | ```console
5 | $ mkdir -p ~/vrx_ws/src/vrx/vrx_gazebo/models/my_dock_base && cd ~/vrx_ws/src/vrx/vrx_gazebo/models/my_dock_base
6 | ```
7 |
8 | 2. Create .config file
9 | ```
10 | $ vim model.config
11 | ```
12 |
13 | 3. Edit .config file
14 | ```xml
15 |
16 |
17 | my_dock_base
18 | 1.0
19 | model.sdf
20 |
21 |
22 | Carlos Agüero
23 | caguero@openrobotics.org
24 |
25 |
26 |
27 | My custom dock base.
28 |
29 |
30 | ```
31 |
32 | 4. Create .sdf.erb file
33 | ```
34 | $ vim model.sdf.erb
35 | ```
36 |
37 | 5. Edit .sdf.erb file
38 | ```xml
39 |
40 |
41 |
42 |
43 |
44 |
45 | <%
46 | layout = [
47 | 'X X',
48 | 'X X',
49 | 'X X',
50 | 'XXXXXXX',
51 | 'XXXX',
52 | 'XXXXXXX',
53 | 'X X',
54 | 'X X',
55 | 'X X',
56 | ]
57 | %>
58 | <%= ERB.new(File.read('dock_generator.erb'),
59 | nil, '-', 'dock').result(binding) %>
60 |
61 |
62 | ```
63 |
64 | 6. Open the vrx_gazebo/CMakeLists.txt file and add your model
65 | ```
66 | # Dock base files that need to be processed with erb
67 | set (dock_base_erb_files
68 | models/dock_2016_base/model.sdf.erb
69 | models/dock_2018_base/model.sdf.erb
70 |
71 | # THIS IS THE ONLY LINE THAT NEEDS TO BE ADDED.
72 | models/my_dock_base/model.sdf.erb <== Add this line
73 | )
74 | ```
75 |
76 | 7. Launch gazebo
77 | ```
78 | $ roslaunch vrx_gazebo sandisland.launch
79 | ```
80 |
81 | 8. Insert your new dock by clicking on `Insert->my_dock_base`
82 |
--------------------------------------------------------------------------------
/Ch7 ROS Virtual RobotX/figure/driving_debug_before.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch7 ROS Virtual RobotX/figure/driving_debug_before.png
--------------------------------------------------------------------------------
/Ch7 ROS Virtual RobotX/figure/keyboard_debug_after.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alonzo3569/ROS_Tutorial/595a93c0e960bfc832290e1c52995170cb525948/Ch7 ROS Virtual RobotX/figure/keyboard_debug_after.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Table of contents
2 | 1. **ROS Node & Topic**
3 | 2. **ROS Service**
4 | 3. **ROS Custom Message**
5 | 4. **ROS Params & Launch Files**
6 | 5. **ROS Bag & OOP**
7 | 6. **ROS Gazebo**
8 | * Launch Your First Gazebo World Using ROS
9 | * Add gazebo models to a simulation
10 | * Spawn a robot in gazebo
11 | * Create a gazebo model using SDF
12 | * Use a mesh file to create a gazebo model
13 | * Use an image file as texture for gazebo model
14 | * Create a robot using URDF
15 | * Visualize a robot URDF using RVIZ
16 | * Create a robot using URDF(Advance & RVIZ)
17 | 7. **ROS Virtual RobotX**
18 | * Adding Course Elements
19 | * Custom WAM-V Thruster and Sensor Configuration
20 | * Propulsion Configurations
21 | * Adding Sensors
22 | * Thruster Articulation
23 | * Driving
24 | * Visualizing with RViz
25 | * Plugin Parameters
26 | * Custom Dock
27 |
--------------------------------------------------------------------------------
/src/my_robot_bringup/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8.3)
2 | project(my_robot_bringup)
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)
11 |
12 | ## System dependencies are found with CMake's conventions
13 | # find_package(Boost REQUIRED COMPONENTS system)
14 |
15 |
16 | ## Uncomment this if the package has a setup.py. This macro ensures
17 | ## modules and global scripts declared therein get installed
18 | ## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
19 | # catkin_python_setup()
20 |
21 | ################################################
22 | ## Declare ROS messages, services and actions ##
23 | ################################################
24 |
25 | ## To declare and build messages, services or actions from within this
26 | ## package, follow these steps:
27 | ## * Let MSG_DEP_SET be the set of packages whose message types you use in
28 | ## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
29 | ## * In the file package.xml:
30 | ## * add a build_depend tag for "message_generation"
31 | ## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET
32 | ## * If MSG_DEP_SET isn't empty the following dependency has been pulled in
33 | ## but can be declared for certainty nonetheless:
34 | ## * add a exec_depend tag for "message_runtime"
35 | ## * In this file (CMakeLists.txt):
36 | ## * add "message_generation" and every package in MSG_DEP_SET to
37 | ## find_package(catkin REQUIRED COMPONENTS ...)
38 | ## * add "message_runtime" and every package in MSG_DEP_SET to
39 | ## catkin_package(CATKIN_DEPENDS ...)
40 | ## * uncomment the add_*_files sections below as needed
41 | ## and list every .msg/.srv/.action file to be processed
42 | ## * uncomment the generate_messages entry below
43 | ## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
44 |
45 | ## Generate messages in the 'msg' folder
46 | # add_message_files(
47 | # FILES
48 | # Message1.msg
49 | # Message2.msg
50 | # )
51 |
52 | ## Generate services in the 'srv' folder
53 | # add_service_files(
54 | # FILES
55 | # Service1.srv
56 | # Service2.srv
57 | # )
58 |
59 | ## Generate actions in the 'action' folder
60 | # add_action_files(
61 | # FILES
62 | # Action1.action
63 | # Action2.action
64 | # )
65 |
66 | ## Generate added messages and services with any dependencies listed here
67 | # generate_messages(
68 | # DEPENDENCIES
69 | # std_msgs # Or other packages containing msgs
70 | # )
71 |
72 | ################################################
73 | ## Declare ROS dynamic reconfigure parameters ##
74 | ################################################
75 |
76 | ## To declare and build dynamic reconfigure parameters within this
77 | ## package, follow these steps:
78 | ## * In the file package.xml:
79 | ## * add a build_depend and a exec_depend tag for "dynamic_reconfigure"
80 | ## * In this file (CMakeLists.txt):
81 | ## * add "dynamic_reconfigure" to
82 | ## find_package(catkin REQUIRED COMPONENTS ...)
83 | ## * uncomment the "generate_dynamic_reconfigure_options" section below
84 | ## and list every .cfg file to be processed
85 |
86 | ## Generate dynamic reconfigure parameters in the 'cfg' folder
87 | # generate_dynamic_reconfigure_options(
88 | # cfg/DynReconf1.cfg
89 | # cfg/DynReconf2.cfg
90 | # )
91 |
92 | ###################################
93 | ## catkin specific configuration ##
94 | ###################################
95 | ## The catkin_package macro generates cmake config files for your package
96 | ## Declare things to be passed to dependent projects
97 | ## INCLUDE_DIRS: uncomment this if your package contains header files
98 | ## LIBRARIES: libraries you create in this project that dependent projects also need
99 | ## CATKIN_DEPENDS: catkin_packages dependent projects also need
100 | ## DEPENDS: system dependencies of this project that dependent projects also need
101 | catkin_package(
102 | # INCLUDE_DIRS include
103 | # LIBRARIES my_robot_bringup
104 | # CATKIN_DEPENDS other_catkin_pkg
105 | # DEPENDS system_lib
106 | )
107 |
108 | ###########
109 | ## Build ##
110 | ###########
111 |
112 | ## Specify additional locations of header files
113 | ## Your package locations should be listed before other locations
114 | include_directories(
115 | # include
116 | # ${catkin_INCLUDE_DIRS}
117 | )
118 |
119 | ## Declare a C++ library
120 | # add_library(${PROJECT_NAME}
121 | # src/${PROJECT_NAME}/my_robot_bringup.cpp
122 | # )
123 |
124 | ## Add cmake target dependencies of the library
125 | ## as an example, code may need to be generated before libraries
126 | ## either from message generation or dynamic reconfigure
127 | # add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
128 |
129 | ## Declare a C++ executable
130 | ## With catkin_make all packages are built within a single CMake context
131 | ## The recommended prefix ensures that target names across packages don't collide
132 | # add_executable(${PROJECT_NAME}_node src/my_robot_bringup_node.cpp)
133 |
134 | ## Rename C++ executable without prefix
135 | ## The above recommended prefix causes long target names, the following renames the
136 | ## target back to the shorter version for ease of user use
137 | ## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
138 | # set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")
139 |
140 | ## Add cmake target dependencies of the executable
141 | ## same as for the library above
142 | # add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
143 |
144 | ## Specify libraries to link a library or executable target against
145 | # target_link_libraries(${PROJECT_NAME}_node
146 | # ${catkin_LIBRARIES}
147 | # )
148 |
149 | #############
150 | ## Install ##
151 | #############
152 |
153 | # all install targets should use catkin DESTINATION variables
154 | # See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
155 |
156 | ## Mark executable scripts (Python etc.) for installation
157 | ## in contrast to setup.py, you can choose the destination
158 | # install(PROGRAMS
159 | # scripts/my_python_script
160 | # DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
161 | # )
162 |
163 | ## Mark executables and/or libraries for installation
164 | # install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}_node
165 | # ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
166 | # LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
167 | # RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
168 | # )
169 |
170 | ## Mark cpp header files for installation
171 | # install(DIRECTORY include/${PROJECT_NAME}/
172 | # DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
173 | # FILES_MATCHING PATTERN "*.h"
174 | # PATTERN ".svn" EXCLUDE
175 | # )
176 |
177 | ## Mark other files for installation (e.g. launch and bag files, etc.)
178 | # install(FILES
179 | # # myfile1
180 | # # myfile2
181 | # DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
182 | # )
183 |
184 | #############
185 | ## Testing ##
186 | #############
187 |
188 | ## Add gtest based cpp test target and link libraries
189 | # catkin_add_gtest(${PROJECT_NAME}-test test/test_my_robot_bringup.cpp)
190 | # if(TARGET ${PROJECT_NAME}-test)
191 | # target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
192 | # endif()
193 |
194 | ## Add folders to be run by python nosetests
195 | # catkin_add_nosetests(test)
196 |
--------------------------------------------------------------------------------
/src/my_robot_bringup/launch/number_app.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/my_robot_bringup/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | my_robot_bringup
4 | 0.0.0
5 | The my_robot_bringup package
6 |
7 |
8 |
9 |
10 | ros
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 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/src/my_robot_msgs/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8.3)
2 | project(my_robot_msgs)
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 | roscpp
12 | rospy
13 | std_msgs
14 | message_generation
15 | )
16 |
17 | ## System dependencies are found with CMake's conventions
18 | # find_package(Boost REQUIRED COMPONENTS system)
19 |
20 |
21 | ## Uncomment this if the package has a setup.py. This macro ensures
22 | ## modules and global scripts declared therein get installed
23 | ## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
24 | # catkin_python_setup()
25 |
26 | ################################################
27 | ## Declare ROS messages, services and actions ##
28 | ################################################
29 |
30 | ## To declare and build messages, services or actions from within this
31 | ## package, follow these steps:
32 | ## * Let MSG_DEP_SET be the set of packages whose message types you use in
33 | ## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
34 | ## * In the file package.xml:
35 | ## * add a build_depend tag for "message_generation"
36 | ## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET
37 | ## * If MSG_DEP_SET isn't empty the following dependency has been pulled in
38 | ## but can be declared for certainty nonetheless:
39 | ## * add a exec_depend tag for "message_runtime"
40 | ## * In this file (CMakeLists.txt):
41 | ## * add "message_generation" and every package in MSG_DEP_SET to
42 | ## find_package(catkin REQUIRED COMPONENTS ...)
43 | ## * add "message_runtime" and every package in MSG_DEP_SET to
44 | ## catkin_package(CATKIN_DEPENDS ...)
45 | ## * uncomment the add_*_files sections below as needed
46 | ## and list every .msg/.srv/.action file to be processed
47 | ## * uncomment the generate_messages entry below
48 | ## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
49 |
50 | ## Generate messages in the 'msg' folder
51 | add_message_files(
52 | FILES
53 | HardwareStatus.msg
54 | )
55 |
56 | ## Generate services in the 'srv' folder
57 | add_service_files(
58 | FILES
59 | ComputeDiskArea.srv
60 | SetLed.srv
61 | )
62 |
63 | ## Generate actions in the 'action' folder
64 | # add_action_files(
65 | # FILES
66 | # Action1.action
67 | # Action2.action
68 | # )
69 |
70 | ## Generate added messages and services with any dependencies listed here
71 | generate_messages(
72 | DEPENDENCIES
73 | std_msgs
74 | )
75 |
76 | ################################################
77 | ## Declare ROS dynamic reconfigure parameters ##
78 | ################################################
79 |
80 | ## To declare and build dynamic reconfigure parameters within this
81 | ## package, follow these steps:
82 | ## * In the file package.xml:
83 | ## * add a build_depend and a exec_depend tag for "dynamic_reconfigure"
84 | ## * In this file (CMakeLists.txt):
85 | ## * add "dynamic_reconfigure" to
86 | ## find_package(catkin REQUIRED COMPONENTS ...)
87 | ## * uncomment the "generate_dynamic_reconfigure_options" section below
88 | ## and list every .cfg file to be processed
89 |
90 | ## Generate dynamic reconfigure parameters in the 'cfg' folder
91 | # generate_dynamic_reconfigure_options(
92 | # cfg/DynReconf1.cfg
93 | # cfg/DynReconf2.cfg
94 | # )
95 |
96 | ###################################
97 | ## catkin specific configuration ##
98 | ###################################
99 | ## The catkin_package macro generates cmake config files for your package
100 | ## Declare things to be passed to dependent projects
101 | ## INCLUDE_DIRS: uncomment this if your package contains header files
102 | ## LIBRARIES: libraries you create in this project that dependent projects also need
103 | ## CATKIN_DEPENDS: catkin_packages dependent projects also need
104 | ## DEPENDS: system dependencies of this project that dependent projects also need
105 | catkin_package(
106 | # INCLUDE_DIRS include
107 | # LIBRARIES my_robot_msgs
108 | CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
109 | # DEPENDS system_lib
110 | )
111 |
112 | ###########
113 | ## Build ##
114 | ###########
115 |
116 | ## Specify additional locations of header files
117 | ## Your package locations should be listed before other locations
118 | include_directories(
119 | # include
120 | ${catkin_INCLUDE_DIRS}
121 | )
122 |
123 | ## Declare a C++ library
124 | # add_library(${PROJECT_NAME}
125 | # src/${PROJECT_NAME}/my_robot_msgs.cpp
126 | # )
127 |
128 | ## Add cmake target dependencies of the library
129 | ## as an example, code may need to be generated before libraries
130 | ## either from message generation or dynamic reconfigure
131 | # add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
132 |
133 | ## Declare a C++ executable
134 | ## With catkin_make all packages are built within a single CMake context
135 | ## The recommended prefix ensures that target names across packages don't collide
136 | # add_executable(${PROJECT_NAME}_node src/my_robot_msgs_node.cpp)
137 |
138 | ## Rename C++ executable without prefix
139 | ## The above recommended prefix causes long target names, the following renames the
140 | ## target back to the shorter version for ease of user use
141 | ## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
142 | # set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")
143 |
144 | ## Add cmake target dependencies of the executable
145 | ## same as for the library above
146 | # add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
147 |
148 | ## Specify libraries to link a library or executable target against
149 | # target_link_libraries(${PROJECT_NAME}_node
150 | # ${catkin_LIBRARIES}
151 | # )
152 |
153 | #############
154 | ## Install ##
155 | #############
156 |
157 | # all install targets should use catkin DESTINATION variables
158 | # See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
159 |
160 | ## Mark executable scripts (Python etc.) for installation
161 | ## in contrast to setup.py, you can choose the destination
162 | # install(PROGRAMS
163 | # scripts/my_python_script
164 | # DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
165 | # )
166 |
167 | ## Mark executables and/or libraries for installation
168 | # install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}_node
169 | # ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
170 | # LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
171 | # RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
172 | # )
173 |
174 | ## Mark cpp header files for installation
175 | # install(DIRECTORY include/${PROJECT_NAME}/
176 | # DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
177 | # FILES_MATCHING PATTERN "*.h"
178 | # PATTERN ".svn" EXCLUDE
179 | # )
180 |
181 | ## Mark other files for installation (e.g. launch and bag files, etc.)
182 | # install(FILES
183 | # # myfile1
184 | # # myfile2
185 | # DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
186 | # )
187 |
188 | #############
189 | ## Testing ##
190 | #############
191 |
192 | ## Add gtest based cpp test target and link libraries
193 | # catkin_add_gtest(${PROJECT_NAME}-test test/test_my_robot_msgs.cpp)
194 | # if(TARGET ${PROJECT_NAME}-test)
195 | # target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
196 | # endif()
197 |
198 | ## Add folders to be run by python nosetests
199 | # catkin_add_nosetests(test)
200 |
--------------------------------------------------------------------------------
/src/my_robot_msgs/msg/HardwareStatus.msg:
--------------------------------------------------------------------------------
1 | int64 temperature
2 | bool are_motors_up
3 | string debug_message
4 |
--------------------------------------------------------------------------------
/src/my_robot_msgs/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | my_robot_msgs
4 | 0.0.0
5 | The my_robot_msgs package
6 |
7 |
8 |
9 |
10 | ros
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 | roscpp
53 | rospy
54 | std_msgs
55 | message_generation
56 | roscpp
57 | rospy
58 | std_msgs
59 | roscpp
60 | rospy
61 | std_msgs
62 | message_runtime
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/src/my_robot_msgs/srv/ComputeDiskArea.srv:
--------------------------------------------------------------------------------
1 | float64 radius
2 | ---
3 | float64 area
4 |
--------------------------------------------------------------------------------
/src/my_robot_msgs/srv/SetLed.srv:
--------------------------------------------------------------------------------
1 | int64 led_number
2 | int64 state
3 | ---
4 | bool success
5 |
--------------------------------------------------------------------------------
/src/my_robot_tutorials/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8.3)
2 | project(my_robot_tutorials)
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 | roscpp
12 | rospy
13 | std_msgs
14 | std_srvs
15 | rospy_tutorials
16 | my_robot_msgs
17 | )
18 |
19 | ## System dependencies are found with CMake's conventions
20 | # find_package(Boost REQUIRED COMPONENTS system)
21 |
22 |
23 | ## Uncomment this if the package has a setup.py. This macro ensures
24 | ## modules and global scripts declared therein get installed
25 | ## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
26 | # catkin_python_setup()
27 |
28 | ################################################
29 | ## Declare ROS messages, services and actions ##
30 | ################################################
31 |
32 | ## To declare and build messages, services or actions from within this
33 | ## package, follow these steps:
34 | ## * Let MSG_DEP_SET be the set of packages whose message types you use in
35 | ## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
36 | ## * In the file package.xml:
37 | ## * add a build_depend tag for "message_generation"
38 | ## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET
39 | ## * If MSG_DEP_SET isn't empty the following dependency has been pulled in
40 | ## but can be declared for certainty nonetheless:
41 | ## * add a exec_depend tag for "message_runtime"
42 | ## * In this file (CMakeLists.txt):
43 | ## * add "message_generation" and every package in MSG_DEP_SET to
44 | ## find_package(catkin REQUIRED COMPONENTS ...)
45 | ## * add "message_runtime" and every package in MSG_DEP_SET to
46 | ## catkin_package(CATKIN_DEPENDS ...)
47 | ## * uncomment the add_*_files sections below as needed
48 | ## and list every .msg/.srv/.action file to be processed
49 | ## * uncomment the generate_messages entry below
50 | ## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
51 |
52 | ## Generate messages in the 'msg' folder
53 | # add_message_files(
54 | # FILES
55 | # Message1.msg
56 | # Message2.msg
57 | # )
58 |
59 | ## Generate services in the 'srv' folder
60 | # add_service_files(
61 | # FILES
62 | # Service1.srv
63 | # Service2.srv
64 | # )
65 |
66 | ## Generate actions in the 'action' folder
67 | # add_action_files(
68 | # FILES
69 | # Action1.action
70 | # Action2.action
71 | # )
72 |
73 | ## Generate added messages and services with any dependencies listed here
74 | # generate_messages(
75 | # DEPENDENCIES
76 | # std_msgs
77 | # )
78 |
79 | ################################################
80 | ## Declare ROS dynamic reconfigure parameters ##
81 | ################################################
82 |
83 | ## To declare and build dynamic reconfigure parameters within this
84 | ## package, follow these steps:
85 | ## * In the file package.xml:
86 | ## * add a build_depend and a exec_depend tag for "dynamic_reconfigure"
87 | ## * In this file (CMakeLists.txt):
88 | ## * add "dynamic_reconfigure" to
89 | ## find_package(catkin REQUIRED COMPONENTS ...)
90 | ## * uncomment the "generate_dynamic_reconfigure_options" section below
91 | ## and list every .cfg file to be processed
92 |
93 | ## Generate dynamic reconfigure parameters in the 'cfg' folder
94 | # generate_dynamic_reconfigure_options(
95 | # cfg/DynReconf1.cfg
96 | # cfg/DynReconf2.cfg
97 | # )
98 |
99 | ###################################
100 | ## catkin specific configuration ##
101 | ###################################
102 | ## The catkin_package macro generates cmake config files for your package
103 | ## Declare things to be passed to dependent projects
104 | ## INCLUDE_DIRS: uncomment this if your package contains header files
105 | ## LIBRARIES: libraries you create in this project that dependent projects also need
106 | ## CATKIN_DEPENDS: catkin_packages dependent projects also need
107 | ## DEPENDS: system dependencies of this project that dependent projects also need
108 | catkin_package(
109 | # INCLUDE_DIRS include
110 | # LIBRARIES my_robot_tutorials
111 | # CATKIN_DEPENDS roscpp rospy std_msgs
112 | # DEPENDS system_lib
113 | )
114 |
115 | ###########
116 | ## Build ##
117 | ###########
118 |
119 | ## Specify additional locations of header files
120 | ## Your package locations should be listed before other locations
121 | include_directories(
122 | # include
123 | ${catkin_INCLUDE_DIRS}
124 | )
125 |
126 | ## Declare a C++ library
127 | # add_library(${PROJECT_NAME}
128 | # src/${PROJECT_NAME}/my_robot_tutorials.cpp
129 | # )
130 |
131 | ## Add cmake target dependencies of the library
132 | ## as an example, code may need to be generated before libraries
133 | ## either from message generation or dynamic reconfigure
134 | # add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
135 |
136 | ## Declare a C++ executable
137 | ## With catkin_make all packages are built within a single CMake context
138 | ## The recommended prefix ensures that target names across packages don't collide
139 | # add_executable(${PROJECT_NAME}_node src/my_robot_tutorials_node.cpp)
140 |
141 | add_executable(node_cpp src/my_first_node.cpp)
142 | target_link_libraries(node_cpp ${catkin_LIBRARIES})
143 |
144 | add_executable(robot_news_radio_transmitter src/robot_news_radio_transmitter.cpp)
145 | target_link_libraries(robot_news_radio_transmitter ${catkin_LIBRARIES})
146 |
147 | add_executable(smartphone_node src/smartphone_node.cpp)
148 | target_link_libraries(smartphone_node ${catkin_LIBRARIES})
149 |
150 | add_executable(number_publisher src/number_publisher.cpp)
151 | target_link_libraries(number_publisher ${catkin_LIBRARIES})
152 |
153 | add_executable(number_counter src/number_counter.cpp)
154 | target_link_libraries(number_counter ${catkin_LIBRARIES})
155 |
156 | add_executable(add_two_ints_server src/add_two_ints_server.cpp)
157 | target_link_libraries(add_two_ints_server ${catkin_LIBRARIES})
158 |
159 | add_executable(add_two_ints_client src/add_two_ints_client.cpp)
160 | target_link_libraries(add_two_ints_client ${catkin_LIBRARIES})
161 |
162 | add_executable(oop_number_counter src/oop_number_counter.cpp)
163 | target_link_libraries(oop_number_counter ${catkin_LIBRARIES})
164 |
165 | ## Rename C++ executable without prefix
166 | ## The above recommended prefix causes long target names, the following renames the
167 | ## target back to the shorter version for ease of user use
168 | ## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
169 | # set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")
170 |
171 | ## Add cmake target dependencies of the executable
172 | ## same as for the library above
173 | # add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
174 |
175 | ## Specify libraries to link a library or executable target against
176 | # target_link_libraries(${PROJECT_NAME}_node
177 | # ${catkin_LIBRARIES}
178 | # )
179 |
180 | #############
181 | ## Install ##
182 | #############
183 |
184 | # all install targets should use catkin DESTINATION variables
185 | # See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
186 |
187 | ## Mark executable scripts (Python etc.) for installation
188 | ## in contrast to setup.py, you can choose the destination
189 | # install(PROGRAMS
190 | # scripts/my_python_script
191 | # DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
192 | # )
193 |
194 | ## Mark executables and/or libraries for installation
195 | # install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}_node
196 | # ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
197 | # LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
198 | # RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
199 | # )
200 |
201 | ## Mark cpp header files for installation
202 | # install(DIRECTORY include/${PROJECT_NAME}/
203 | # DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
204 | # FILES_MATCHING PATTERN "*.h"
205 | # PATTERN ".svn" EXCLUDE
206 | # )
207 |
208 | ## Mark other files for installation (e.g. launch and bag files, etc.)
209 | # install(FILES
210 | # # myfile1
211 | # # myfile2
212 | # DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
213 | # )
214 |
215 | #############
216 | ## Testing ##
217 | #############
218 |
219 | ## Add gtest based cpp test target and link libraries
220 | # catkin_add_gtest(${PROJECT_NAME}-test test/test_my_robot_tutorials.cpp)
221 | # if(TARGET ${PROJECT_NAME}-test)
222 | # target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
223 | # endif()
224 |
225 | ## Add folders to be run by python nosetests
226 | # catkin_add_nosetests(test)
227 |
--------------------------------------------------------------------------------
/src/my_robot_tutorials/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | my_robot_tutorials
4 | 0.0.0
5 | The my_robot_tutorials package
6 |
7 |
8 |
9 |
10 | ros
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 | roscpp
53 | rospy
54 | std_msgs
55 | std_srvs
56 | rospy_tutorials
57 | roscpp
58 | rospy
59 | std_msgs
60 | std_srvs
61 | rospy_tutorials
62 | roscpp
63 | rospy
64 | std_msgs
65 | std_srvs
66 | rospy_tutorials
67 |
68 | my_robot_msgs
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/src/my_robot_tutorials/scripts/add_two_ints_client.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import rospy
4 | from rospy_tutorials.srv import AddTwoInts
5 |
6 | if __name__ == '__main__':
7 | rospy.init_node("add_two_ints_client")
8 |
9 | rospy.wait_for_service("/add_two_ints")
10 |
11 | try:
12 | add_two_ints = rospy.ServiceProxy("/add_two_ints", AddTwoInts)
13 | response = add_two_ints(2,6)
14 | rospy.loginfo("Sum is : " + str(response.sum))
15 | except rospy.ServiceException as e:
16 | rospy.logwarn("Service failed: " + str(e))
17 |
--------------------------------------------------------------------------------
/src/my_robot_tutorials/scripts/add_two_ints_server.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import rospy
4 | from rospy_tutorials.srv import AddTwoInts
5 |
6 | def handle_add_two_ints(req):
7 | result = req.a + req.b
8 | rospy.loginfo("Sum of " + str(req.a) + " and " + str(req.b) + " is " + str(result))
9 | return result
10 |
11 | if __name__ == '__main__':
12 | rospy.init_node("add_two_ints_server")
13 | rospy.loginfo("Add two ints server node created")
14 |
15 | service = rospy.Service("/add_two_ints", AddTwoInts, handle_add_two_ints)
16 | rospy.loginfo("Service server has been started")
17 |
18 | rospy.spin()
19 |
--------------------------------------------------------------------------------
/src/my_robot_tutorials/scripts/battery.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import rospy
4 | from my_robot_msgs.srv import SetLed
5 |
6 | def set_led(battery_state):
7 | rospy.wait_for_service("/set_led")
8 | try:
9 | service = rospy.ServiceProxy("/set_led", SetLed)
10 | state = 0
11 | if battery_state == 'empty':
12 | state = 1
13 | resp = service(1, state)
14 | rospy.loginfo("Set led success flag : " + str(resp))
15 | except rospy.ServiceException as e:
16 | rospy.logerr(e)
17 |
18 |
19 | if __name__ == '__main__':
20 | rospy.init_node('battery')
21 |
22 | battery_state = "full"
23 |
24 | while not rospy.is_shutdown():
25 | rospy.sleep(7)
26 | battery_state = "empty"
27 | rospy.loginfo("The battery is empty !")
28 | set_led(battery_state)
29 | rospy.sleep(3)
30 | battery_state = "full"
31 | rospy.loginfo("The battery is now full")
32 | set_led(battery_state)
33 |
--------------------------------------------------------------------------------
/src/my_robot_tutorials/scripts/hw_status_publisher.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import rospy
4 | from my_robot_msgs.msg import HardwareStatus
5 |
6 | if __name__ == '__main__':
7 | rospy.init_node("hardware_status_publisher")
8 |
9 | pub = rospy.Publisher("/my_robot/hardware_status", HardwareStatus, queue_size=10)
10 |
11 | rate = rospy.Rate(5)
12 |
13 | while not rospy.is_shutdown():
14 | msg = HardwareStatus()
15 | msg.temperature = 45
16 | msg.are_motors_up = True
17 | msg.debug_message = "Everything is running well"
18 | pub.publish(msg)
19 | rate.sleep()
20 |
--------------------------------------------------------------------------------
/src/my_robot_tutorials/scripts/led_panel.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import rospy
4 | from my_robot_msgs.srv import SetLed
5 |
6 | led_states = [0,0,0]
7 |
8 | def callback_set_led(req):
9 | led_number = req.led_number
10 | state = req.state
11 | global led_states
12 |
13 | if (led_number > len(led_states)) or (led_number <= 0):
14 | return False
15 |
16 | if not (state == 0 or state == 1):
17 | return False
18 |
19 | led_states[led_number - 1] = state
20 |
21 | return True
22 |
23 | if __name__ == '__main__':
24 | rospy.init_node('led_panel')
25 |
26 |
27 | server = rospy.Service("/set_led", SetLed, callback_set_led)
28 |
29 | rate = rospy.Rate(10)
30 |
31 | while not rospy.is_shutdown():
32 | rospy.loginfo(led_states)
33 | rate.sleep()
34 |
35 |
--------------------------------------------------------------------------------
/src/my_robot_tutorials/scripts/my_first_node.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import rospy
4 |
5 | if __name__ == '__main__':
6 | rospy.init_node('my_first_python_node')
7 | rospy.loginfo("This node has been started")
8 |
9 | rate = rospy.Rate(10)
10 |
11 | while not rospy.is_shutdown():
12 | rospy.loginfo("Hello")
13 | rate.sleep()
14 |
--------------------------------------------------------------------------------
/src/my_robot_tutorials/scripts/number_counter.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import rospy
4 | from std_msgs.msg import Int64
5 | from std_srvs.srv import SetBool
6 |
7 | counter = 0
8 | pub = None
9 |
10 | def callback_number(msg):
11 | global counter
12 | counter += msg.data
13 | new_msg = Int64()
14 | new_msg.data = counter
15 | pub.publish(new_msg)
16 |
17 | def callback_reset_counter(req):
18 | if req.data:
19 | global counter
20 | counter = 0
21 | return True, "Counter has been successfully reset"
22 | return False, "Counter has not been reset"
23 |
24 | if __name__ == '__main__':
25 | rospy.init_node('number_counter')
26 |
27 | sub = rospy.Subscriber("/number", Int64, callback_number)
28 |
29 | pub = rospy.Publisher("/number_count", Int64, queue_size=10)
30 |
31 | reset_service = rospy.Service("/reset_counter", SetBool, callback_reset_counter)
32 |
33 | rospy.spin()
34 |
--------------------------------------------------------------------------------
/src/my_robot_tutorials/scripts/number_publisher.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import rospy
4 | from std_msgs.msg import Int64
5 |
6 | if __name__ == '__main__':
7 | rospy.init_node("number_publisher", anonymous=True)
8 |
9 | pub = rospy.Publisher("/number", Int64, queue_size=10)
10 |
11 | publish_frequency = rospy.get_param("/number_publish_frequency")
12 | rate = rospy.Rate(publish_frequency)
13 |
14 | number = rospy.get_param("/number_to_publish")
15 |
16 | rospy.set_param("/another_param", "Helloooo")
17 |
18 | while not rospy.is_shutdown():
19 | msg = Int64()
20 | msg.data = number
21 | pub.publish(msg)
22 | rate.sleep()
23 |
--------------------------------------------------------------------------------
/src/my_robot_tutorials/scripts/oop_number_counter.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import rospy
4 | from std_msgs.msg import Int64
5 | from std_srvs.srv import SetBool
6 |
7 |
8 | class NumberCounter:
9 |
10 | def __init__(self):
11 | self.counter = 0
12 |
13 | self.number_subscriber = rospy.Subscriber("/number", Int64, self.callback_number)
14 |
15 | self.pub = rospy.Publisher("/number_count", Int64, queue_size=10)
16 |
17 | self.reset_service = rospy.Service("/reset_counter", SetBool, self.callback_reset_counter)
18 |
19 | def callback_number(self, msg):
20 | self.counter += msg.data
21 | new_msg = Int64()
22 | new_msg.data = self.counter
23 | self.pub.publish(new_msg)
24 |
25 | def callback_reset_counter(self, req):
26 | if req.data:
27 | self.counter = 0
28 | return True, "Counter has been successfully reset"
29 | return False, "Counter has not been reset"
30 |
31 |
32 | if __name__ == '__main__':
33 | rospy.init_node('number_counter')
34 | NumberCounter()
35 | rospy.spin()
36 |
--------------------------------------------------------------------------------
/src/my_robot_tutorials/scripts/robot_news_radio_transmitter.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import rospy
4 | from std_msgs.msg import String
5 |
6 | if __name__ == '__main__':
7 |
8 | rospy.init_node('robot_news_radio_transmitter', anonymous=True)
9 |
10 | pub = rospy.Publisher("/robot_news_radio", String, queue_size=10)
11 |
12 | rate = rospy.Rate(2)
13 |
14 | while not rospy.is_shutdown():
15 | msg = String()
16 | msg.data = "Hi, this is Dan from the Robot News Radio !"
17 | pub.publish(msg)
18 | rate.sleep()
19 |
20 | rospy.loginfo("Node was stopped")
21 |
--------------------------------------------------------------------------------
/src/my_robot_tutorials/scripts/smartphone.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import rospy
4 | from std_msgs.msg import String
5 |
6 | def callback_receive_radio_data(msg):
7 | rospy.loginfo("Message received : ")
8 | rospy.loginfo(msg)
9 |
10 |
11 | if __name__ == '__main__':
12 | rospy.init_node('smartphone')
13 |
14 | sub = rospy.Subscriber("/robot_news_radio", String, callback_receive_radio_data)
15 |
16 | rospy.spin()
17 |
--------------------------------------------------------------------------------
/src/my_robot_tutorials/src/add_two_ints_client.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | int main (int argc, char **argv)
5 | {
6 | ros::init(argc, argv, "add_two_ints_client");
7 | ros::NodeHandle nh;
8 |
9 | ros::ServiceClient client =
10 | nh.serviceClient("/add_two_ints");
11 |
12 | rospy_tutorials::AddTwoInts srv;
13 | srv.request.a = 12;
14 | srv.request.b = 5;
15 |
16 | if (client.call(srv)) {
17 | ROS_INFO("Returned sum is %d", (int)srv.response.sum);
18 | }
19 | else {
20 | ROS_WARN("Service call failed");
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/my_robot_tutorials/src/add_two_ints_server.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | bool handle_add_two_ints(rospy_tutorials::AddTwoInts::Request &req,
5 | rospy_tutorials::AddTwoInts::Response &res)
6 | {
7 | int result = req.a + req.b;
8 | ROS_INFO("%d + %d = %d", (int)req.a, (int)req.b, (int)result);
9 | res.sum = result;
10 | return true;
11 | }
12 |
13 | int main (int argc, char **argv)
14 | {
15 | ros::init(argc, argv, "add_two_ints_server");
16 | ros::NodeHandle nh;
17 |
18 | ros::ServiceServer server = nh.advertiseService("/add_two_ints",
19 | handle_add_two_ints);
20 |
21 | ros::spin();
22 | }
23 |
--------------------------------------------------------------------------------
/src/my_robot_tutorials/src/my_first_node.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main (int argc, char **argv)
4 | {
5 | ros::init(argc, argv, "my_first_cpp_node");
6 | ros::NodeHandle nh;
7 | ROS_INFO("Node has been started");
8 |
9 | ros::Rate rate(10);
10 |
11 | while (ros::ok()) {
12 | ROS_INFO("Hello");
13 | rate.sleep();
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/src/my_robot_tutorials/src/number_counter.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | int counter = 0;
6 | ros::Publisher pub;
7 |
8 | void callback_number(const std_msgs::Int64& msg)
9 | {
10 | counter += msg.data;
11 | std_msgs::Int64 new_msg;
12 | new_msg.data = counter;
13 | pub.publish(new_msg);
14 | }
15 |
16 | bool callback_reset_counter(std_srvs::SetBool::Request &req,
17 | std_srvs::SetBool::Response &res)
18 | {
19 | if (req.data) {
20 | counter = 0;
21 | res.success = true;
22 | res.message = "Counter has been successfully reset";
23 | }
24 | else {
25 | res.success = false;
26 | res.message = "Counter has not been reset";
27 | }
28 |
29 | return true;
30 | }
31 |
32 |
33 | int main (int argc, char **argv)
34 | {
35 | ros::init(argc, argv, "number_counter");
36 | ros::NodeHandle nh;
37 |
38 | ros::Subscriber sub = nh.subscribe("/number", 1000, callback_number);
39 |
40 | pub = nh.advertise("/number_count", 10);
41 |
42 | ros::ServiceServer reset_service = nh.advertiseService("/reset_counter",
43 | callback_reset_counter);
44 |
45 | ros::spin();
46 | }
47 |
--------------------------------------------------------------------------------
/src/my_robot_tutorials/src/number_publisher.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | int main (int argc, char **argv)
5 | {
6 | ros::init(argc, argv, "number_publisher", ros::init_options::AnonymousName);
7 | ros::NodeHandle nh;
8 |
9 | ros::Publisher pub = nh.advertise("/number", 10);
10 |
11 | double publish_frequency;
12 | nh.getParam("/number_publish_frequency", publish_frequency);
13 | ros::Rate rate(publish_frequency);
14 |
15 | int number;
16 | nh.getParam("/number_to_publish", number);
17 |
18 | nh.setParam("/just_another_param", "Bye");
19 |
20 | while (ros::ok()) {
21 | std_msgs::Int64 msg;
22 | msg.data = number;
23 | pub.publish(msg);
24 | rate.sleep();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/my_robot_tutorials/src/oop_number_counter.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | class NumberCounter {
6 |
7 | private:
8 | int counter;
9 | ros::Publisher pub;
10 | ros::Subscriber number_subscriber;
11 | ros::ServiceServer reset_service;
12 |
13 | public:
14 | NumberCounter(ros::NodeHandle *nh) {
15 | counter = 0;
16 |
17 | pub = nh->advertise("/number_count", 10);
18 |
19 | number_subscriber = nh->subscribe("/number", 1000,
20 | &NumberCounter::callback_number, this);
21 |
22 | reset_service = nh->advertiseService("/reset_counter",
23 | &NumberCounter::callback_reset_counter, this);
24 | }
25 |
26 | void callback_number(const std_msgs::Int64& msg) {
27 | counter += msg.data;
28 | std_msgs::Int64 new_msg;
29 | new_msg.data = counter;
30 | pub.publish(new_msg);
31 | }
32 |
33 | bool callback_reset_counter(std_srvs::SetBool::Request &req,
34 | std_srvs::SetBool::Response &res)
35 | {
36 | if (req.data) {
37 | counter = 0;
38 | res.success = true;
39 | res.message = "Counter has been successfully reset";
40 | }
41 | else {
42 | res.success = false;
43 | res.message = "Counter has not been reset";
44 | }
45 |
46 | return true;
47 | }
48 | };
49 |
50 | int main (int argc, char **argv)
51 | {
52 | ros::init(argc, argv, "number_counter");
53 | ros::NodeHandle nh;
54 | NumberCounter nc = NumberCounter(&nh);
55 | ros::spin();
56 | }
57 |
--------------------------------------------------------------------------------
/src/my_robot_tutorials/src/robot_news_radio_transmitter.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | int main (int argc, char **argv)
5 | {
6 | ros::init(argc, argv, "robot_news_radio_transmitter",
7 | ros::init_options::AnonymousName);
8 | ros::NodeHandle nh;
9 |
10 | ros::Publisher pub = nh.advertise("/robot_news_radio", 10);
11 |
12 | ros::Rate rate(3);
13 |
14 | while (ros::ok()) {
15 | std_msgs::String msg;
16 | msg.data = "Hi, this is William from the Robot News Radio";
17 | pub.publish(msg);
18 | rate.sleep();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/my_robot_tutorials/src/smartphone_node.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | void callback_receive_radio_data(const std_msgs::String& msg)
5 | {
6 | ROS_INFO("Message received : %s", msg.data.c_str());
7 | }
8 |
9 |
10 | int main (int argc, char **argv)
11 | {
12 | ros::init(argc, argv, "smartphone");
13 | ros::NodeHandle nh;
14 |
15 | ros::Subscriber sub = nh.subscribe("/robot_news_radio",
16 | 1000, callback_receive_radio_data );
17 |
18 | ros::spin();
19 | }
20 |
--------------------------------------------------------------------------------