Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added a sample support node subscribes string and publishes its CRC32. #14

Merged
merged 1 commit into from
Apr 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,15 @@ Please also check for more details about example applications on the embedded de
- or, `$ ros2 launch mros2_pub_pose launch.py`
- mros2 application on the embedded device:
- [sub_pose](https://github.com/mROS-base/mros2-mbed/tree/main/workspace/sub_pose)

## mros2_sub_long_string_pub_crc

- Description:
- (The mros2 node on the embedded device publishes `string` (`std_msgs::msg::String`) message to `/to_linux` topic.)
- The `sub_long_string_pub_crc` node on the host subscribes `string` (`geometry_msgs::msg::String`) message from `/to_linux` topic, and then its node publishes the CRC32 as a u_int32 (`std_msgs::msg::UInt32`) value to `/to_stm` topic.
- Host operation:
- `$ ros2 run mros2_sub_long_string_pub_crc sub_long_string_pub_crc_node.
- or, `$ ros2 launch mros2_sub_long_string_pub_crc subpub.launch.py`
- mros2 application on the embedded device:
- [sub_pose](https://github.com/mROS-base/mros2-mbed/tree/main/workspace/pub_long_string_sub_crc)

51 changes: 51 additions & 0 deletions mros2_sub_long_string_pub_crc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
cmake_minimum_required(VERSION 3.5)
project(mros2_sub_long_string_pub_crc)

# Default to C99
if(NOT CMAKE_C_STANDARD)
set(CMAKE_C_STANDARD 99)
endif()

# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
# uncomment the following section in order to fill in
# further dependencies manually.
# find_package(<dependency> REQUIRED)

add_executable(sub_long_string_pub_crc_node src/sub_long_string_pub_crc.cpp)
ament_target_dependencies(sub_long_string_pub_crc_node rclcpp std_msgs)

target_include_directories(sub_long_string_pub_crc_node PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)

install(TARGETS sub_long_string_pub_crc_node
DESTINATION lib/${PROJECT_NAME})

install(DIRECTORY
launch
DESTINATION share/${PROJECT_NAME})

if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
# the following line skips the linter which checks for copyrights
# uncomment the line when a copyright and license is not present in all source files
#set(ament_cmake_copyright_FOUND TRUE)
# the following line skips cpplint (only works in a git repo)
# uncomment the line when this package is not in a git repo
#set(ament_cmake_cpplint_FOUND TRUE)
ament_lint_auto_find_test_dependencies()
endif()

ament_package()
14 changes: 14 additions & 0 deletions mros2_sub_long_string_pub_crc/launch/subpub.launch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from launch import LaunchDescription
from launch_ros.actions import Node

# Note: `node_`, `prefix` and `output` will be removed on Foxy
def generate_launch_description():
return LaunchDescription([
Node(
package='mros2_sub_long_string_pub_crc',
executable='sub_long_string_pub_crc_node',
name='subpub_mros2',
prefix=['stdbuf -o L'],
output="screen"
)
])
21 changes: 21 additions & 0 deletions mros2_sub_long_string_pub_crc/package.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>mros2_sub_long_string_pub_crc</name>
<version>0.0.0</version>
<description>TODO: Package description</description>
<maintainer email="[email protected]">uden</maintainer>
<license>TODO: License declaration</license>

<buildtool_depend>ament_cmake</buildtool_depend>
<build_depend>rclcpp</build_depend>
<build_depend>std_msgs</build_depend>
<exec_depend>rclcpp</exec_depend>
<exec_depend>std_msgs</exec_depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>

<export>
<build_type>ament_cmake</build_type>
</export>
</package>
74 changes: 74 additions & 0 deletions mros2_sub_long_string_pub_crc/src/sub_long_string_pub_crc.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include <chrono>
#include <functional>
#include <memory>
#include <string>

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
#include "std_msgs/msg/u_int32.hpp"

using std::placeholders::_1;

// imported from
// https://github.com/aeldidi/crc32/blob/master/src/crc32.c
uint32_t
crc32_for_byte(uint32_t byte)
{
const uint32_t polynomial = 0xEDB88320L;
uint32_t result = byte;
size_t i = 0;

for (; i < 8; i++) {
result = (result >> 1) ^ (result & 1) * polynomial;
}
return result;
}

uint32_t
crc32(const void *input, size_t size)
{
const uint8_t *current = static_cast<const uint8_t *>(input);
uint32_t result = 0xFFFFFFFF;
size_t i = 0;

for (; i < size; i++) {
result ^= current[i];
result = crc32_for_byte(result);
}

return ~result;
}

class Crc32generator : public rclcpp::Node
{
public:
Crc32generator() : Node("recv_long_string_send_crc_node")
{
publisher_ = this->create_publisher<std_msgs::msg::UInt32>("to_stm", 10);
subscriber_ = this->create_subscription<std_msgs::msg::String>("to_linux", rclcpp::QoS(10).best_effort(), std::bind(&Crc32generator::topic_callback, this, _1));
}

private:
void topic_callback(const std_msgs::msg::String::SharedPtr msg) const
{
auto pub_msg = std_msgs::msg::UInt32();
uint32_t tmp = crc32((char *)&msg->data[0], msg->data.size());
pub_msg.data = tmp;
RCLCPP_INFO(this->get_logger(), "\r\nSubscribed msg: '%s'", msg->data.c_str());
RCLCPP_INFO(this->get_logger(), "\r\n");
RCLCPP_INFO(this->get_logger(), "========================");
RCLCPP_INFO(this->get_logger(), "CRC: 0x%0x", tmp);
RCLCPP_INFO(this->get_logger(), "========================");
publisher_->publish(pub_msg);
}
rclcpp::Publisher<std_msgs::msg::UInt32>::SharedPtr publisher_;
rclcpp::Subscription<std_msgs::msg::String>::SharedPtr subscriber_;
};

int main(int argc, char * argv[])
{
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<Crc32generator>());
rclcpp::shutdown();
return 0;
}