Framerate is a parameter now

This commit is contained in:
dmalad 2023-12-04 16:34:55 +01:00
parent 083693732c
commit e68cfccc50
5 changed files with 41 additions and 18 deletions

View File

@ -5,8 +5,10 @@ This project is a migration from ROS1 to ROS2. The original code was developed b
This project enables the conversion of a selected ROS2 topic of type `sensor_msgs::msg::Image` into an `RTSP` stream, with an anticipated delay of approximately 30-50ms. The generated stream can be utilized for various purposes such as remote control, object detection tasks, monitoring, and more. Please note that the migration process is ongoing, and therefore, the complete functionality of the original package is not yet available. This project enables the conversion of a selected ROS2 topic of type `sensor_msgs::msg::Image` into an `RTSP` stream, with an anticipated delay of approximately 30-50ms. The generated stream can be utilized for various purposes such as remote control, object detection tasks, monitoring, and more. Please note that the migration process is ongoing, and therefore, the complete functionality of the original package is not yet available.
The development is being carried out on Ubuntu 20.04 with ROS2 Foxy. The development is being carried out on Ubuntu 20.04 with ROS2 Foxy.
You are reading now the README for a **default** ROS2 Foxy package. If you want to use this package written as a ROS2 Foxy component, checkout `ros2_component` branch.
## Dependencies ## Dependencies
- ROS2 Foxy - ROS2 foxy
- gstreamer libs: - gstreamer libs:
```bash ```bash
@ -19,9 +21,19 @@ sudo apt-get install libgstreamer-plugins-base1.0-dev libgstreamer-plugins-good1
mkdir -p ros2_ws/src mkdir -p ros2_ws/src
cd ros2_ws/src/ cd ros2_ws/src/
``` ```
- Clone the package: - Clone the package and then navigate into the directory `image2rtsp`:
```bashrc ```bashrc
git clone https://github.com/45kmh/image2rtsp.git git clone https://gitlab.rhrk.uni-kl.de/dmalad/image2rtsp.git
cd image2rtsp/
```
- To use the package as a **component** with ROS2 checkout **ros2_component** branch (Dont forget to switch the README).
```bashrc
git checkout ros2_component
```
- To use the package as a **simple subscriber** with ROS2 Foxy stay on the `master` branch and follow the instructions.
- Check the framerate of the topic to be subscribed:
```bashrc
ros2 topic hz /someTopic
``` ```
- Adjust `parameters.yaml` according to your needs: - Adjust `parameters.yaml` according to your needs:
```bashrc ```bashrc
@ -31,16 +43,18 @@ sudo apt-get install libgstreamer-plugins-base1.0-dev libgstreamer-plugins-good1
topic: "/color/image_raw" # The ROS2 topic to subscribe to topic: "/color/image_raw" # The ROS2 topic to subscribe to
mountpoint: "/back" # Choose the mountpoint for the rtsp stream. mountpoint: "/back" # Choose the mountpoint for the rtsp stream.
# This will be able to be accessed from rtsp://<server_ip>/portAndMountpoint # This will be able to be accessed from rtsp://<server_ip>/portAndMountpoint
caps: "video/x-raw,framerate=10/1,width=640,height=480"
# Set the caps to be applied after getting the ROS2 Image and before the x265 encoder.
bitrate: "500" bitrate: "500"
framerate: "30" # Make sure that your framerate corresponds to the frequency of a topic you are subscribing to
caps_1: "video/x-raw,framerate="
capr_2: "/1,width=640,height=480"
# Set the caps to be applied after getting the ROS2 Image and before the x265 encoder. Ignore
# framerate setting here.
port: "8554" port: "8554"
local_only: True # True = rtsp://127.0.0.1:port (The stream is accessible only from the local machine) local_only: True # True = rtsp://127.0.0.1:portAndMountpoint (The stream is accessible only from the local machine)
# False = rtsp://0.0.0.0:portAndMountpoint (The stream is accessible from the outside) # False = rtsp://0.0.0.0:portAndMountpoint (The stream is accessible from the outside)
# For example, to access the stream running on the machine with IP = 192.168.20.20, # For example, to access the stream running on the machine with IP = 192.168.20.20,
# use rtsp://192.186.20.20:portAndMountpoint # use rtsp://192.186.20.20:portAndMountpoint
# True = rtsp://127.0.0.1:portAndMountpoint (The stream is accessible only from the local machine) - Save your configuration and navigate to `ros2_ws` colcon root, source and build the package:
- Save your configuration and navigate to `image2rtsp ` colcon root, source and build the package:
```bashrc ```bashrc
cd ~/ros2_ws/ cd ~/ros2_ws/
colcon build --packages-select image2rtsp colcon build --packages-select image2rtsp

View File

@ -3,10 +3,11 @@
topic: "/color/image_raw" topic: "/color/image_raw"
mountpoint: "/back" mountpoint: "/back"
bitrate: "500" bitrate: "500"
caps: "video/x-raw,framerate=10/1,width=640,height=480" framerate: "30"
caps_1: "video/x-raw, framerate ="
caps_2: "/1,width=640,height=480"
port: "8554" port: "8554"
local_only: True # True = rtsp://127.0.0.1:port (The stream is accessible only from the local machine) local_only: True # True = rtsp://127.0.0.1:portAndMountpoint (The stream is accessible only from the local machine)
# False = rtsp://0.0.0.0:portAndMountpoint (The stream is accessible from the outside) # False = rtsp://0.0.0.0:portAndMountpoint (The stream is accessible from the outside)
# For example, to access the stream running on the machine with IP = 192.168.20.20, # For example, to access the stream running on the machine with IP = 192.168.20.20,
# use rtsp://192.186.20.20:portAndMountpoint # use rtsp://192.186.20.20:portAndMountpoint
# True = rtsp://127.0.0.1:portAndMountpoint (The stream is accessible only from the local machine)

View File

@ -18,7 +18,9 @@ private:
string topic; string topic;
string mountpoint; string mountpoint;
string bitrate; string bitrate;
string caps; string framerate;
string caps_1;
string caps_2;
string port; string port;
string pipeline; string pipeline;
string pipeline_head; string pipeline_head;

View File

@ -12,19 +12,25 @@ Image2rtsp::Image2rtsp() : Node("image2rtsp"){
this->declare_parameter("topic"); this->declare_parameter("topic");
this->declare_parameter("mountpoint"); this->declare_parameter("mountpoint");
this->declare_parameter("bitrate"); this->declare_parameter("bitrate");
this->declare_parameter("caps"); this->declare_parameter("framerate");
this->declare_parameter("caps_1");
this->declare_parameter("caps_2");
this->declare_parameter("port"); this->declare_parameter("port");
this->declare_parameter("local_only"); this->declare_parameter("local_only");
topic = this->get_parameter("topic").as_string(); topic = this->get_parameter("topic").as_string();
mountpoint = this->get_parameter("mountpoint").as_string(); mountpoint = this->get_parameter("mountpoint").as_string();
bitrate = this->get_parameter("bitrate").as_string(); bitrate = this->get_parameter("bitrate").as_string();
caps = this->get_parameter("caps").as_string(); framerate = this->get_parameter("framerate").as_string();
caps_1 = this->get_parameter("caps_1").as_string();
caps_2 = this->get_parameter("caps_2").as_string();
port = this->get_parameter("port").as_string(); port = this->get_parameter("port").as_string();
local_only = this->get_parameter("local_only").as_bool(); local_only = this->get_parameter("local_only").as_bool();
// Check if the parameter is set, since no default value is provided // Check if the parameter is set, since no default value is provided
if (!this->has_parameter("topic") || !this->has_parameter("mountpoint") || !this->has_parameter("bitrate") || !this->has_parameter("caps") || !this->has_parameter("port")){ if (!this->has_parameter("topic") || !this->has_parameter("mountpoint") || !this->has_parameter("bitrate") ||
!this->has_parameter("framerate") || !this->has_parameter("caps_1") || !this->has_parameter("caps_2") ||
!this->has_parameter("port") || !this->has_parameter("local_only")){
rclcpp::shutdown(); // Shutdown the node if there are some issues with launch file rclcpp::shutdown(); // Shutdown the node if there are some issues with launch file
return; return;
} }
@ -39,7 +45,7 @@ Image2rtsp::Image2rtsp() : Node("image2rtsp"){
// Setup the pipeline // Setup the pipeline
pipeline_head = "( appsrc name=imagesrc do-timestamp=true min-latency=0 max-latency=0 max-bytes=1000 is-live=true ! videoconvert ! videoscale ! "; pipeline_head = "( appsrc name=imagesrc do-timestamp=true min-latency=0 max-latency=0 max-bytes=1000 is-live=true ! videoconvert ! videoscale ! ";
pipeline_tail = "key-int-max=30 ! video/x-h264, profile=baseline ! rtph264pay name=pay0 pt=96 )"; pipeline_tail = "key-int-max=30 ! video/x-h264, profile=baseline ! rtph264pay name=pay0 pt=96 )";
pipeline = pipeline_head + caps + " ! x264enc tune=zerolatency bitrate=" + bitrate + pipeline_tail; pipeline = pipeline_head + caps_1 + framerate + caps_2 + " ! x264enc tune=zerolatency bitrate=" + bitrate + pipeline_tail;
rtsp_server_add_url(mountpoint.c_str(), pipeline.c_str(), (GstElement **)&(appsrc)); rtsp_server_add_url(mountpoint.c_str(), pipeline.c_str(), (GstElement **)&(appsrc));
RCLCPP_INFO(this->get_logger(), "Stream available at rtsp://%s:%s%s", gst_rtsp_server_get_address(rtsp_server), port.c_str(), mountpoint.c_str()); RCLCPP_INFO(this->get_logger(), "Stream available at rtsp://%s:%s%s", gst_rtsp_server_get_address(rtsp_server), port.c_str(), mountpoint.c_str());
} }
@ -52,7 +58,7 @@ int main(int argc, char *argv[]){
rclcpp::spin(node); rclcpp::spin(node);
} }
}catch (const std::exception &e){ }catch (const std::exception &e){
RCLCPP_INFO(rclcpp::get_logger("image2rtsp"), "One or more required parameters are not set. Shutting down the node."); RCLCPP_INFO(rclcpp::get_logger("image2rtsp"), "One or more required parameters are not set, or set incorrectly. Shutting down the node.");
RCLCPP_INFO(rclcpp::get_logger("image2rtsp"), "Tip: Start the node only using launch file. Also rebuild after making changes in the YAML file"); RCLCPP_INFO(rclcpp::get_logger("image2rtsp"), "Tip: Start the node only using launch file. Also rebuild after making changes in the YAML file");
RCLCPP_ERROR(rclcpp::get_logger("image2rtsp"), "Parameter is not set: %s", e.what()); RCLCPP_ERROR(rclcpp::get_logger("image2rtsp"), "Parameter is not set: %s", e.what());
} }

View File

@ -131,7 +131,7 @@ GstCaps *Image2rtsp::gst_caps_new_from_image(const sensor_msgs::msg::Image::Shar
"format", G_TYPE_STRING, format->second.c_str(), "format", G_TYPE_STRING, format->second.c_str(),
"width", G_TYPE_INT, msg->width, "width", G_TYPE_INT, msg->width,
"height", G_TYPE_INT, msg->height, "height", G_TYPE_INT, msg->height,
"framerate", GST_TYPE_FRACTION, 10, 1, "framerate", GST_TYPE_FRACTION, stoi(framerate), 1,
nullptr); nullptr);
} }