Skip to content

Commit

Permalink
Clean up + healtcheck update
Browse files Browse the repository at this point in the history
  • Loading branch information
rafal-gorecki committed Jan 23, 2024
1 parent 6b7674e commit a775e04
Show file tree
Hide file tree
Showing 11 changed files with 146 additions and 104 deletions.
31 changes: 14 additions & 17 deletions Dockerfile.gazebo
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ RUN mkdir src && \
MYDISTRO=${PREFIX:-ros}; MYDISTRO=${MYDISTRO//-/} && \
source /opt/$MYDISTRO/$ROS_DISTRO/setup.bash && \
# Create health check package
ros2 pkg create healthcheck_pkg --build-type ament_cmake --dependencies rclcpp nav_msgs && \
sed -i '/find_package(nav_msgs REQUIRED)/a \
ros2 pkg create healthcheck_pkg --build-type ament_cmake --dependencies rclcpp nav_msgs sensor_msgs && \
sed -i '/find_package(sensor_msgs REQUIRED)/a \
add_executable(healthcheck_node src/healthcheck.cpp)\n \
ament_target_dependencies(healthcheck_node rclcpp nav_msgs)\n \
ament_target_dependencies(healthcheck_node rclcpp nav_msgs sensor_msgs)\n \
install(TARGETS healthcheck_node DESTINATION lib/${PROJECT_NAME})' \
/ros2_ws/src/healthcheck_pkg/CMakeLists.txt

COPY healthcheck.cpp src/healthcheck_pkg/src/
COPY husarion_utils/healthcheck.cpp src/healthcheck_pkg/src/

RUN MYDISTRO=${PREFIX:-ros}; MYDISTRO=${MYDISTRO//-/} && \
source /opt/$MYDISTRO/$ROS_DISTRO/setup.bash && \
Expand All @@ -44,13 +44,10 @@ ENV HUSARION_ROS_BUILD simulation

WORKDIR /ros2_ws

COPY ./healthcheck.cpp /

# install everything needed
RUN apt-get update --fix-missing && apt-get install -y \
python3-pip \
ros-dev-tools && \
apt-get upgrade -y && \
# Clone source
git clone --depth 1 -b humble https://github.com/husarion/rosbot_ros.git src && \
vcs import src < src/rosbot/rosbot_hardware.repos && \
Expand Down Expand Up @@ -84,11 +81,10 @@ ENV HUSARION_ROS_BUILD simulation
WORKDIR /ros2_ws

COPY --from=ros_builder /ros2_ws /ros2_ws
COPY --from=healthcheck_builder /ros2_ws /ros2_ws_healthcheck

RUN apt-get update && apt-get install -y \
python3-rosdep \
python3-pip \
python3-rosdep \
ros-$ROS_DISTRO-teleop-twist-keyboard && \
rm -rf /etc/ros/rosdep/sources.list.d/20-default.list && \
rosdep init && \
Expand All @@ -98,17 +94,18 @@ RUN apt-get update && apt-get install -y \
echo $(cat /ros2_ws/src/rosbot_gazebo/package.xml | grep '<version>' | sed -r 's/.*<version>([0-9]+.[0-9]+.[0-9]+)<\/version>/\1/g') > /version.txt && \
# Size optimalization
apt-get remove -y \
python3-rosdep \
python3-pip && \
python3-pip \
python3-rosdep && \
apt-get clean && \
rm -rf src && \
rm -rf /var/lib/apt/lists/*

COPY healthcheck.sh /
COPY run_healthcheck_node.sh /
COPY husarion_utils /husarion_utils

HEALTHCHECK --interval=2s --timeout=1s --start-period=30s --retries=1 \
CMD ["/healthcheck.sh"]

RUN sed -i "/# <additional-user-commands>/r /run_healthcheck_node.sh" /*_entrypoint.sh && \
# Run healthcheck in background
COPY --from=healthcheck_builder /ros2_ws /healthcheck_ws
RUN sed -i "/# <additional-user-commands>/r /husarion_utils/run_healthcheck_node.sh" /*_entrypoint.sh && \
sed -i "/# <additional-user-commands>/d" /*_entrypoint.sh

HEALTHCHECK --interval=2s --timeout=1s --start-period=30s --retries=1 \
CMD ["/husarion_utils/healthcheck.sh"]
39 changes: 17 additions & 22 deletions Dockerfile.hardware
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ RUN mkdir src && \
MYDISTRO=${PREFIX:-ros}; MYDISTRO=${MYDISTRO//-/} && \
source /opt/$MYDISTRO/$ROS_DISTRO/setup.bash && \
# Create health check package
ros2 pkg create healthcheck_pkg --build-type ament_cmake --dependencies rclcpp nav_msgs && \
sed -i '/find_package(nav_msgs REQUIRED)/a \
ros2 pkg create healthcheck_pkg --build-type ament_cmake --dependencies rclcpp nav_msgs sensor_msgs && \
sed -i '/find_package(sensor_msgs REQUIRED)/a \
add_executable(healthcheck_node src/healthcheck.cpp)\n \
ament_target_dependencies(healthcheck_node rclcpp nav_msgs)\n \
ament_target_dependencies(healthcheck_node rclcpp nav_msgs sensor_msgs)\n \
install(TARGETS healthcheck_node DESTINATION lib/${PROJECT_NAME})' \
/ros2_ws/src/healthcheck_pkg/CMakeLists.txt

COPY healthcheck.cpp src/healthcheck_pkg/src/
COPY husarion_utils/healthcheck.cpp src/healthcheck_pkg/src/

RUN MYDISTRO=${PREFIX:-ros}; MYDISTRO=${MYDISTRO//-/} && \
source /opt/$MYDISTRO/$ROS_DISTRO/setup.bash && \
Expand All @@ -42,8 +42,6 @@ SHELL ["/bin/bash", "-c"]
WORKDIR /ros2_ws
RUN mkdir src

COPY ./healthcheck.cpp /

RUN apt-get update && apt-get install -y \
python3-pip

Expand Down Expand Up @@ -77,12 +75,6 @@ WORKDIR /ros2_ws

COPY --from=ros_builder /ros2_ws /ros2_ws
COPY --from=ros_builder /version.txt /version.txt
COPY --from=healthcheck_builder /ros2_ws /ros2_ws_healthcheck

# for backward compatibility
RUN cp src/rosbot_utils/rosbot_utils/flash-firmware.py /usr/bin/ && \
cp src/rosbot_utils/rosbot_utils/flash-firmware.py / && \
cp install/rosbot_utils/share/rosbot_utils/firmware/firmware-*.bin /root/firmware.bin

RUN apt-get update && apt-get install -y \
python3-pip \
Expand All @@ -97,21 +89,24 @@ RUN apt-get update && apt-get install -y \
rosdep install -i --from-path src --rosdistro $ROS_DISTRO -y && \
# Size optimalization
apt-get remove -y \
python3-rosdep \
python3-pip && \
python3-pip \
python3-rosdep && \
apt-get clean && \
rm -rf src && \
rm -rf /var/lib/apt/lists/*

COPY healthcheck.sh /
COPY run_healthcheck_node.sh /
COPY husarion_utils /husarion_utils

COPY print-serial-number.py /usr/bin/
RUN mv /husarion_utils/print-serial-number.py /usr/bin/ && \
# for backward compatibility
cp src/rosbot_utils/rosbot_utils/flash-firmware.py /usr/bin/ && \
cp src/rosbot_utils/rosbot_utils/flash-firmware.py / && \
cp install/rosbot_utils/share/rosbot_utils/firmware/firmware-*.bin /root/firmware.bin

ENV ROBOT_NAMESPACE=
# Run healthcheck in background
COPY --from=healthcheck_builder /ros2_ws /healthcheck_ws
RUN sed -i "/# <additional-user-commands>/r /husarion_utils/run_healthcheck_node.sh" /*_entrypoint.sh && \
sed -i "/# <additional-user-commands>/d" /*_entrypoint.sh

HEALTHCHECK --interval=2s --timeout=1s --start-period=30s --retries=1 \
CMD ["/healthcheck.sh"]

RUN sed -i "/# <additional-user-commands>/r /run_healthcheck_node.sh" /*_entrypoint.sh && \
sed -i "/# <additional-user-commands>/d" /*_entrypoint.sh
CMD ["/husarion_utils/healthcheck.sh"]
8 changes: 4 additions & 4 deletions demo/compose.build.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Quick Start
#
#
# 1. run `docker compose up` on the robot
# 2. run `ROS_DOMAIN_ID=10 ros2 run teleop_twist_keyboard teleop_twist_keyboard` in the robot termianl
# 2. run `ROS_DOMAIN_ID=10 ros2 run teleop_twist_keyboard teleop_twist_keyboard` in the robot terminal

x-common-config:
&common-config
Expand All @@ -27,8 +27,8 @@ services:
# command: tail -f /dev/null
# command: ros2 run rosbot_utils flash_firmware --usb
command: >
ros2 launch rosbot_bringup combined.launch.py
ros2 launch rosbot_bringup combined.launch.py
mecanum:=${MECANUM:-False}
serial_port:=$SERIAL_PORT
serial_port:=$SERIAL_PORT
serial_baudrate:=576000
# namespace:=rosbot
2 changes: 1 addition & 1 deletion demo/shm-only.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
<useBuiltinTransports>false</useBuiltinTransports>
</rtps>
</participant>
</profiles>
</profiles>
55 changes: 0 additions & 55 deletions healthcheck.cpp

This file was deleted.

94 changes: 94 additions & 0 deletions husarion_utils/healthcheck.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#include "fstream"
#include "nav_msgs/msg/odometry.hpp"
#include "rclcpp/rclcpp.hpp"
#include "sensor_msgs/msg/imu.hpp"
#include <cstdlib>

using namespace std::chrono;
using namespace std::chrono_literals;

#define HEALTHCHECK_PERIOD 500ms
#define MSG_VALID_TIME 2s

class HealthCheckNode : public rclcpp::Node {
public:
HealthCheckNode()
: Node("healthcheck_rosbot"), last_controller_msg_(steady_clock::now()),
last_ekf_msg_(steady_clock::now()), last_imu_msg_(steady_clock::now()) {

sub_controller_ = create_subscription<nav_msgs::msg::Odometry>(
"rosbot_base_controller/odom",
rclcpp::SystemDefaultsQoS().keep_last(1).transient_local(),
std::bind(&HealthCheckNode::controllerCallback, this,
std::placeholders::_1));

sub_ekf_ = create_subscription<nav_msgs::msg::Odometry>(
"odometry/filtered", rclcpp::SystemDefaultsQoS().keep_last(1),
std::bind(&HealthCheckNode::ekfCallback, this, std::placeholders::_1));

sub_imu_ = create_subscription<sensor_msgs::msg::Imu>(
"imu_broadcaster/imu",
rclcpp::SystemDefaultsQoS().keep_last(1).transient_local(),
std::bind(&HealthCheckNode::imuCallback, this, std::placeholders::_1));

healthcheck_timer_ = create_wall_timer(
HEALTHCHECK_PERIOD, std::bind(&HealthCheckNode::healthyCheck, this));
}

private:
steady_clock::time_point last_controller_msg_;
steady_clock::time_point last_ekf_msg_;
steady_clock::time_point last_imu_msg_;

rclcpp::Subscription<nav_msgs::msg::Odometry>::SharedPtr sub_controller_;
rclcpp::Subscription<nav_msgs::msg::Odometry>::SharedPtr sub_ekf_;
rclcpp::Subscription<sensor_msgs::msg::Imu>::SharedPtr sub_imu_;
rclcpp::TimerBase::SharedPtr healthcheck_timer_;

bool isMsgValid(steady_clock::time_point current_time,
steady_clock::time_point last_msg) {
duration<double> elapsed_time = current_time - last_controller_msg_;
return elapsed_time < MSG_VALID_TIME;
}

void healthyCheck() {
auto current_time = steady_clock::now();

bool is_controller = isMsgValid(current_time, last_ekf_msg_);
bool is_ekf = isMsgValid(current_time, last_ekf_msg_);
bool is_imu = isMsgValid(current_time, last_imu_msg_);

if (is_controller && is_ekf && is_imu) {
writeHealthStatus("healthy");
} else {
writeHealthStatus("unhealthy");
}
}

void writeHealthStatus(const std::string &status) {
std::ofstream healthFile("/var/tmp/health_status.txt");
healthFile << status;
}

void controllerCallback(const nav_msgs::msg::Odometry::SharedPtr msg) {
RCLCPP_DEBUG_ONCE(get_logger(), "Map msg arrived");
last_controller_msg_ = steady_clock::now();
}

void ekfCallback(const nav_msgs::msg::Odometry::SharedPtr msg) {
RCLCPP_DEBUG_ONCE(get_logger(), "Map msg arrived");
last_controller_msg_ = steady_clock::now();
}

void imuCallback(const sensor_msgs::msg::Imu::SharedPtr msg) {
RCLCPP_DEBUG_ONCE(get_logger(), "Map msg arrived");
last_controller_msg_ = steady_clock::now();
}
};

int main(int argc, char *argv[]) {
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<HealthCheckNode>());
rclcpp::shutdown();
return 0;
}
File renamed without changes.
13 changes: 10 additions & 3 deletions print-serial-number.py → husarion_utils/print-serial-number.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,23 @@
import string
import re


def get_cpu_id_from_ros_service():
try:
# Run the ROS service call command
result = subprocess.run(['ros2', 'service', 'call', '/get_cpu_id', 'std_srvs/srv/Trigger'],
capture_output=True, text=True, timeout=30)
result = subprocess.run(
["ros2", "service", "call", "/get_cpu_id", "std_srvs/srv/Trigger"],
capture_output=True,
text=True,
timeout=30,
)

# Regular expression to extract JSON from the response
match = re.search(r"message='(\{.*\})'", result.stdout)
if match:
json_str = match.group(1)
json_data = json.loads(json_str)
cpu_id = json_data['cpu_id']
cpu_id = json_data["cpu_id"]
return cpu_id
else:
print("JSON response not found in the output.")
Expand All @@ -29,6 +34,7 @@ def get_cpu_id_from_ros_service():
print(f"JSON parsing error: {e}")
return None


def hex_to_num(hex_str):
# Check if the hex string is valid
if not all(c in string.hexdigits for c in hex_str):
Expand All @@ -46,6 +52,7 @@ def hex_to_num(hex_str):
# Return the hash as an ASCII string
return hash


try:
# Obtain CPU ID from ROS service
cpu_id = get_cpu_id_from_ros_service()
Expand Down
6 changes: 6 additions & 0 deletions husarion_utils/run_healthcheck_node.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
source "/healthcheck_ws/install/setup.bash"
if [ -n "$ROBOT_NAMESPACE" ]; then
gosu $USER bash -c "ros2 run healthcheck_pkg healthcheck_node --ros-args -r __ns:=/$ROBOT_NAMESPACE &"
else
gosu $USER bash -c "ros2 run healthcheck_pkg healthcheck_node &"
fi
File renamed without changes.
2 changes: 0 additions & 2 deletions run_healthcheck_node.sh

This file was deleted.

0 comments on commit a775e04

Please sign in to comment.