Skip to content

Commit

Permalink
file
Browse files Browse the repository at this point in the history
  • Loading branch information
Natsu-Akatsuki committed Jul 26, 2023
1 parent 2ea34cc commit adb5a59
Show file tree
Hide file tree
Showing 17 changed files with 367 additions and 287 deletions.
60 changes: 40 additions & 20 deletions docs/Beginner/CMake and Package.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,46 +63,64 @@ ament_auto_package()
CMakeLists.txt
</summary>


</details>

<!-- tabs:start -->

#### **ROS2**

```cmake
cmake_minimum_required(VERSION 3.11)
project(<project_name>)
具体参考 [Here](https://docs.ros.org/en/iron/How-To-Guides/Ament-CMake-Documentation.html)

# ======================= COMPILE OPTION =======================
由于 ament_auto_find_build_dependencies() 命令会根据 package.xml 导入相关的依赖,所以一定得有 package.xml 文件)

当前的最佳实践是基于 targets 的导入,因此推荐使用 ament_target_dependencies() 命令来替代 target_link_library() 和 include_directory() 命令

```cmake
cmake_minimum_required(VERSION 3.8)
project(<工程名>)
# >>> 通用配置 >>>
# 设置优化等级
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE RELEASE)
endif ()
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0"))
# 设置标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_BUILD_TYPE RELEASE)
# 设置编译选项
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic")
# 导入宏包
# >>> 导入三方包 >>>
find_package(PCL REQUIRED)
# >>> 导入 ROS 包 >>>
find_package(ament_cmake_auto REQUIRED)
# 根据package.xml导入相关的依赖(所以一定得有package.xml)
# >>> 查找相关的依赖 >>>
ament_auto_find_build_dependencies()
# 等价于导入相关的ROS头文件和依赖库
# >>> 构建目标文件 >>>
ament_auto_add_executable(<target_name> <sources>)
ament_auto_add_library(<target_name> <sources>)
ament_target_dependencies(<target_name> Eigen3)
# 导出相关的配置文件和进行安装
ament_auto_package()
# 不同于ROS1会在源目录中查找文件,ROS2需要显式安装相关内容到install目录,为更好的维护建议编译时使用关键词--symlink-install
# >>> 导出非配置文件 >>>
install(DIRECTORY launch
DESTINATION share/${PROJECT_NAME})
install(DIRECTORY rviz_cfg
DESTINATION share/${PROJECT_NAME})
# >>> 导出相关的配置文件和进行安装 >>>
ament_auto_package()
```

#### **ROS1**

```cmake
cmake_minimum_required(VERSION 3.14)
project(工程名)
cmake_minimum_required(VERSION 3.8)
project(<工程名>)
# ======================= COMPILE OPTION =======================
set(CMAKE_CXX_STANDARD 17)
Expand All @@ -118,11 +136,11 @@ find_package(catkin REQUIRED COMPONENTS
)
catkin_package(
INCLUDE_DIRS # 导出当前的头文件以被其他ROS包调用
INCLUDE_DIRS # 导出当前的头文件以被其他ROS包调用
include
LIBRARIES # 导出当前生成的库文件以被其他ROS包调用
LIBRARIES # 导出当前生成的库文件以被其他ROS包调用
route_handler
CATKIN_DEPENDS # 导出当前的ROS依赖,以被其他ROS包继承
CATKIN_DEPENDS # 导出当前的ROS依赖,以被其他ROS包继承
roscpp
pcl_ros
sensor_msgs
Expand All @@ -142,6 +160,8 @@ target_link_libraries(route_handler ${catkin_LIBRARIES})

<!-- tabs:end -->

</details>

## Package.xml

<details>
Expand Down
246 changes: 246 additions & 0 deletions docs/Beginner/Interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,249 @@ catkin_package(

## Service

<details>
<summary>:wrench: <b>用例 1:</b>
常用命令行
</summary>

```bash
# >>> 调用服务 >>>
# ros2 service call /clear std_srvs/srv/Empty
(ros2) ros2 service call <service_name> <service_type> [arguments]
```

</details>

<details>
<summary>:wrench: <b>用例 2:</b>
初始化服务(客户端、服务端)
</summary>

<!-- tabs:start -->

#### **ROS2(C++)**

ROS2 倾向于使用智能指针

```cpp
// >>> 客户端 >>>
rclcpp::Client<包名::srv::服务名>::SharedPtr client_;
client_ = node->create_client<CooperateCommands>(<服务类型>, [rmw_qos_profile_services_default]);

// >>> 服务端 >>>
rclcpp::Service<包名::srv::服务名>::SharedPtr service_;
service_ = node->create_service<服务类型>(<服务名>, &回调函数);
```

#### **ROS1(C++)**

```cpp
// >>> 客户端 >>>
ros::ServiceClient client_;
client_ = pnh_.serviceClient<服务类型>(<服务名>);

// >>> 服务端 >>>
ros::ServiceServer service_;
service_ = pnh_.advertiseService(<服务类型>, <回调函数>);
```

#### **ROS1(Python)**

```python
# >>> 客户端 >>>
rospy.wait_for_service('服务名')
service = rospy.ServiceProxy('服务名', 服务类型)

# >>> 服务端 >>>
rospy.Service('服务名', 服务类型, 回调函数)


def onCallback(self, req):
pass
```

<!-- tabs:end -->

</details>

<details>
<summary>:wrench: <b>用例 3:</b>
等待服务
</summary>

<!-- tabs:start -->

#### **ROS1(C++)**

```c++
// 等待 1s
while (!ros::service::waitForService(<服务名>, ros::Duration(1))) {
if (!ros::ok()) {
ROS_ERROR("Interrupted while waiting for service.");
ros::shutdown();
return;
}
ROS_INFO_STREAM("Waiting for service... [" << module_name << "]");
}
```

#### **ROS2(C++)**

ROS1 的 wait() 是普通函数,而 ROS2 的是成员函数

```c++
// concise
using std::chrono_literals::operator ""s;
client->wait_for_service(1s)

// complex
while (!client->wait_for_service(1s)) {
if (!rclcpp::ok()) {
RCLCPP_ERROR(node->get_logger(), "Interrupted while waiting for service.");
rclcpp::shutdown();
return;
}
RCLCPP_INFO_STREAM(node->get_logger(), "Waiting for service... [" << module_name << "]");
}
```
#### **ROS1(Python)**
不能仿效 C++的形式,尽管可以指定 timeout,但它是直接抛出异常 ROSException,而非返回 true/false
```python
import rospy
rospy.init_node( < 节点名 >)
rospy.wait_for_service( < 服务名 >)
```

<!-- tabs:end -->

#### **ROS2(Python)**

```python
while not self.cli.wait_for_service(timeout_sec=1.0):
if not rclpy.is_shutdown():
node.get_logger().error("Interrupted while waiting for service.")
rclpy.shutdown()
return
node.get_logger().info("Waiting for service... [{}]".format(module_name))
```

</details>

<details>
<summary>:wrench: <b>用例 4:</b>
回调函数
</summary>

|| ROS1 | ROS2 |
|:---:|:----------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------:|
| 返回值 | `bool` | `void` |
| 形参 | 引用(无 const,无指针) | const + 智能指针 |
| 示例 | bool on_clear_route(<br/> ClearRoute::Service::Request &req,<br/> ClearRoute::Service::Response &res); | void on_clear_route(<br/> const ClearRoute::Service::Request::SharedPtr req,<br/> const ClearRoute::Service::Response::SharedPtr res); |

<!-- tabs:start -->

#### **ROS1(C++)**

```cpp
// 类成员函数(无模板参数)
srv_auto_mode_ = pnh->advertiseService("服务名", &RTCInterface::onAutoModeService, this);
bool onAutoModeService(AutoMode::Request &request, AutoMode::Response &response);
```
#### **ROS2(C++)**
```c++
#include <memory>
void callback(const std::shared_ptr<包名::srv::服务类型::Request> request,
std::shared_ptr<包名::srv::服务类型::Response> response)
{
response->sum = request->a + request->b;
}
rclcpp::Service<包名::srv::服务类型>::SharedPtr service =
node->create_service<包名::srv::服务类型>("服务名", &callback);
```

#### **ROS1(Python)**

TODO

#### **ROS2(Python)**

```python
self.srv = self.create_service( < 服务类型 >, < 服务名 >, self.callback)

def callback(self, request, response):
return response
```

<!-- tabs:end -->

</details>

<details>
<summary>:wrench: <b>用例 5:</b>
调用服务
</summary>

<!-- tabs:start -->

#### **ROS1(C++)**

`call()` 函数只能接受左值

```cpp
# 步骤一:实例化请求
请求类 srv;
# 步骤二:触发请求
if (client.call(srv)) {
ROS_INFO("Sum: %ld", (long int)srv.response.sum);
}
else {
ROS_ERROR("Failed to call service add_two_ints");
return 1;
}
```

#### **ROS2(C++)**

C++中`ROS1`的服务是同步的,而`ROS2`的则为异步

```cpp
# 步骤一:实例化请求
auto request = std::make_shared<包名::srv::服务类型::Request>();
// TODO
# 步骤二:异步触发请求
client->async_send_request(request);
auto result = client->async_send_request(request);

// Wait for the result.
if (rclcpp::spin_until_future_complete(node, result) ==
rclcpp::FutureReturnCode::SUCCESS){
RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "...");
} else {
RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Failed to call service [服务名]");
}
```
#### **ROS1(Python)**
TODO
#### **ROS2(Python)**
TODO
<!-- tabs:end -->
</details>
## Action
TODO
Expand Down Expand Up @@ -281,3 +522,8 @@ rosidl_generator_traits::data_type<am_rviz_plugins_msgs::OverlayMenu>
- [Autoware.Universe name guidelines](https://autowarefoundation.github.io/autoware-documentation/main/contributing/coding-guidelines/ros-nodes/message-guidelines/)
- [Autowarw adapting-message-definitions](https://github.com/tier4/AutowareArchitectureProposal.proj/blob/main/docs/developer_guide/knowhow/PortingToROS2.md#adapting-message-definitions)

## Service

- Official C++ demo:[ROS1](http://wiki.ros.org/ROS/Tutorials/WritingServiceClient%28c%2B%2B%29), [ROS2](https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-Service-And-Client.html)
- Official Python demo:[ROS1](http://wiki.ros.org/rospy/Overview/Services), [ROS2](https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Py-Service-And-Client.html)
- [Services between ROS1 and ROS2](https://roboticsbackend.com/ros1-vs-ros2-practical-overview/)
File renamed without changes.
6 changes: 3 additions & 3 deletions docs/Beginner/Publisher and Subscriber.md
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ int main(int argc, char** argv)

## Reference

- Official demo: [ROS1](http://wiki.ros.org/ROS/Tutorials/WritingPublisherSubscriber%28c%2B%2B%29), [ROS2](https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-Publisher-And-Subscriber.html)
- Topic statistics: [ROS1](https://wiki.ros.org/Topics#Topic_statistics), [ROS2](https://docs.ros.org/en/humble/Concepts/About-Topic-Statistics.html)
- Sync demo: [ROS1](http://wiki.ros.org/message_filters)
- Official demo for [ROS1](http://wiki.ros.org/ROS/Tutorials/WritingPublisherSubscriber%28c%2B%2B%29) and [ROS2](https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-Publisher-And-Subscriber.html)
- Topic statistics for [ROS1](https://wiki.ros.org/Topics#Topic_statistics) and [ROS2](https://docs.ros.org/en/humble/Concepts/About-Topic-Statistics.html)
- Sync demo for [ROS1](http://wiki.ros.org/message_filters)

Loading

0 comments on commit adb5a59

Please sign in to comment.