diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..ed34f38 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +.git +.github +.devcontainer \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 5994dcc..38923ef 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,12 +6,33 @@ ARG BUILD_TYPE="RelWithDebInfo" ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update \ - && apt-get -y install --no-install-recommends software-properties-common git libusb-1.0-0-dev wget zsh python3-colcon-common-extensions python3-rosdep build-essential neovim tmux htop net-tools iputils-ping gpiod gstreamer1.0-plugins-bad gstreamer1.0-alsa libasound2-dev busybox + && apt-get -y install --no-install-recommends \ + software-properties-common \ + git \ + nano \ + libusb-1.0-0-dev \ + wget \ + zsh \ + python3-colcon-common-extensions \ + python3-rosdep \ + build-essential \ + neovim \ + tmux \ + htop \ + net-tools \ + iputils-ping \ + gpiod \ + gstreamer1.0-plugins-bad \ + gstreamer1.0-alsa \ + libasound2-dev \ + busybox ENV WS=/ws RUN mkdir -p $WS/src COPY ./ .$WS/src/rae-ros +RUN cp -R .$WS/src/rae-ros/assets/. /usr/share +RUN rm -rf .$WS/src/rae-ros/assets RUN rm -rf .$WS/src/rae-ros/rae_gazebo RUN cd .$WS/ && apt update && rosdep update && rosdep install --from-paths src --ignore-src -y --skip-keys depthai --skip-keys depthai_bridge --skip-keys depthai_ros_driver --skip-keys audio_msgs --skip-keys laserscan_kinect --skip-keys ira_laser_tools diff --git a/assets/rae-logo-white.jpg b/assets/rae-logo-white.jpg new file mode 100644 index 0000000..079e8f9 Binary files /dev/null and b/assets/rae-logo-white.jpg differ diff --git a/rae_hw/include/rae_hw/peripherals/lcd.hpp b/rae_hw/include/rae_hw/peripherals/lcd.hpp index 08d230f..44ef2fa 100644 --- a/rae_hw/include/rae_hw/peripherals/lcd.hpp +++ b/rae_hw/include/rae_hw/peripherals/lcd.hpp @@ -2,11 +2,13 @@ #include #include #include +#include #include "rclcpp/rclcpp.hpp" #include "sensor_msgs/msg/image.hpp" #include "cv_bridge/cv_bridge.h" #include "opencv2/opencv.hpp" + namespace rae_hw { class LCDNode : public rclcpp::Node @@ -16,6 +18,7 @@ namespace rae_hw ~LCDNode(); void image_callback(const sensor_msgs::msg::Image::SharedPtr msg); + void display_image(const cv::Mat& img); private: rclcpp::Subscription::SharedPtr subscription_; @@ -24,5 +27,6 @@ namespace rae_hw struct fb_var_screeninfo vinfo; struct fb_fix_screeninfo finfo; long screensize; + std::string default_logo_path; }; } \ No newline at end of file diff --git a/rae_hw/launch/peripherals.launch.py b/rae_hw/launch/peripherals.launch.py index ab71c35..1ec564d 100644 --- a/rae_hw/launch/peripherals.launch.py +++ b/rae_hw/launch/peripherals.launch.py @@ -34,6 +34,9 @@ def launch_setup(context, *args, **kwargs): name='lcd_node', package='rae_hw', plugin='rae_hw::LCDNode', + parameters=[{ + 'default_logo_path': LaunchConfiguration('default_logo_path') + }], ), ComposableNode( name='led_node', @@ -65,6 +68,7 @@ def generate_launch_description(): DeclareLaunchArgument('name', default_value='rae'), DeclareLaunchArgument('run_container', default_value='true'), DeclareLaunchArgument('enable_battery_status', default_value='true'), + DeclareLaunchArgument('default_logo_path', default_value='/usr/share/rae-logo-white.jpg'), ] return LaunchDescription( diff --git a/rae_hw/src/peripherals/lcd.cpp b/rae_hw/src/peripherals/lcd.cpp index 2a74386..27f9e07 100644 --- a/rae_hw/src/peripherals/lcd.cpp +++ b/rae_hw/src/peripherals/lcd.cpp @@ -15,6 +15,10 @@ namespace rae_hw LCDNode::LCDNode(const rclcpp::NodeOptions &options) : Node("lcd_node", options) { + std::string logo_key = "default_logo_path"; + declare_parameter(logo_key); + default_logo_path = get_parameter(logo_key).as_string(); + // Open the framebuffer device fbfd = open("/dev/fb0", O_RDWR); if (fbfd == -1) @@ -52,16 +56,22 @@ namespace rae_hw "lcd", 10, std::bind(&LCDNode::image_callback, this, std::placeholders::_1)); RCLCPP_INFO(this->get_logger(), "LCD node running!"); } + LCDNode::~LCDNode() { + // Load default image + cv::Mat default_img = cv::imread(default_logo_path); + if (!default_img.empty()) + { + display_image(default_img); + } + munmap(fbp, screensize); close(fbfd); } - void LCDNode::image_callback(const sensor_msgs::msg::Image::SharedPtr msg) + void LCDNode::display_image(const cv::Mat& img) { - // Convert ROS image message to OpenCV image - cv::Mat img = cv_bridge::toCvCopy(msg, "bgr8")->image; // Resize to match the screen dimensions cv::resize(img, img, cv::Size(vinfo.xres, vinfo.yres)); // Iterate over the image pixels @@ -77,8 +87,15 @@ namespace rae_hw *((cv::Vec3b *)(fbp + location)) = pixel; } } - }; + } + void LCDNode::image_callback(const sensor_msgs::msg::Image::SharedPtr msg) + { + // Convert ROS image message to OpenCV image + cv::Mat img = cv_bridge::toCvCopy(msg, "bgr8")->image; + display_image(img); + }; } + #include "rclcpp_components/register_node_macro.hpp" -RCLCPP_COMPONENTS_REGISTER_NODE(rae_hw::LCDNode); \ No newline at end of file +RCLCPP_COMPONENTS_REGISTER_NODE(rae_hw::LCDNode);