diff --git a/.cspell.json b/.cspell.json index 30dc5cda2..5b977fd6c 100644 --- a/.cspell.json +++ b/.cspell.json @@ -5,6 +5,7 @@ "words": [ "adctp", "Adctp", + "applicate", "AT", "autosar", "block_id", diff --git a/README.md b/README.md index a509950ca..9b55340f6 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,29 @@ -# Nebula Sensor Driver +# Nebula +## Welcome to Nebula, the universal sensor driver Nebula is a sensor driver platform that is designed to provide a unified framework for as wide a variety of devices as possible. -While it primarily targets Ethernet-based LiDAR sensors, it aims to be easily extendable to support new sensors and interfaces. -Nebula provides the following features: - -- Support for Velodyne and Hesai sensors, with other LiDAR vendor support under development -- ROS 2 interface implementations -- TCP/IP and UDP communication implementations -- Abstraction of sensor decoders and hardware interfaces available as libraries -- Handling of standard LiDAR functionality, including but not limited to: - - Configuration of communication settings such as sensor and host IP addresses and communication ports - - Configuration of scan speed, synchronization settings, scan phase, and field of view - - Receiving and conversion of UDP packet data into point clouds in Cartesian co-ordinates - - Receiving and interpretation of diagnostics information from the sensor - - Support for multiple return modes and labelling of return types for each point - -With a rapidly increasing number of sensor types and models becoming available, and varying levels of vendor and third-party driver support, Nebula creates a centralized driver methodology. We hope that this project will be used to facilitate active collaboration and efficiency in development projects by providing a platform that reduces the need to re-implement and maintain many different sensor drivers. Contributions to extend the supported devices and features of Nebula are always welcome. - -## How to build - -Nebula builds on ROS Galactic and Humble. +While it primarily targets Ethernet-based LiDAR sensors, it aims to be easily extendable to support new sensors and interfaces. +Nebula works with ROS 2 and is the recommended sensor driver for the [Autoware](https://autoware.org/) project. + +## Documentation +We recommend you get started with the [Nebula Documention](https://tier4.github.io/nebula/). +Here you will find information about the background of the project, how to install and use with ROS 2, and also how to add new sensors to the Nebula driver. +- [About Nebula](https://tier4.github.io/nebula/about) +- [Design](https://tier4.github.io/nebula/design) +- [Supported Sensors](https://tier4.github.io/nebula/supported_sensors) +- [Installation](https://tier4.github.io/nebula/installation) +- [Launching with ROS 2](https://tier4.github.io/nebula/usage) +- [Parameters](https://tier4.github.io/nebula/parameters) +- [Point cloud types](https://tier4.github.io/nebula/point_types) +- [Contributing](https://tier4.github.io/nebula/contributing) +- [Tutorials](https://tier4.github.io/nebula/tutorials) + +## Quick start +Nebula builds with ROS 2 Galactic and Humble. > **Note** > -> A [TCP enabled version of ROS' Transport Driver](https://github.com/MapIV/transport_drivers/tree/tcp) is required to use Nebula. +> A [TCP enabled version of ROS' Transport Driver](https://github.com/mojomex/transport_drivers/tree/mutable-buffer-in-udp-callback) is required to use Nebula. > It is installed automatically into your workspace using the below commands. However, if you already have ROS transport driver binaries installed, you will have to uninstall them to avoid conflicts (replace `humble` with your ROS distribution): > `sudo apt remove ros-humble-udp-driver ros-humble-io-context` @@ -39,243 +39,13 @@ rosdep install --from-paths src --ignore-src -y -r # Build Nebula colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Release ``` - -## How to run tests - -Run tests: - -```bash -colcon test --event-handlers console_cohesion+ --packages-above nebula_common -``` - -Show results: +To launch Nebula as a ROS 2 node with default parameters for your sensor model: ```bash -colcon test-result --all +ros2 launch nebula_ros *sensor_vendor_name*_launch_all_hw.xml sensor_model:=*sensor_model_name* ``` -## Generic launch file - -You can easily run the sensor hardware interface, the sensor hardware monitor and sensor driver using (e.g. Pandar64): - -```bash -ros2 launch nebula_ros nebula_launch.py sensor_model:=Pandar64 -``` - -If you don't want to launch the hardware (i.e. when you are working from a rosbag), set the `launch_hw` flag to false: - -```bash -ros2 launch nebula_ros nebula_launch.py sensor_model:=Pandar64 launch_hw:=false -``` - -If you don't want the hardware driver to perform the sensor configuration communication (i.e. limited number of connections) set the `setup_sensor` flag to false: - -```bash -ros2 launch nebula_ros nebula_launch.py sensor_model:=Pandar64 setup_sensor:=false -``` - -You should ideally provide a config file for your specific sensor, but default ones are provided `nebula_drivers/config`: - -```bash -ros2 launch nebula_ros nebula_launch.py sensor_model:=Pandar64 config_file:=your_sensor.yaml -``` - -## Supported sensors - -Supported models, where sensor_model is the ROS param to be used at launch: - -| Manufacturer | Model | sensor_model | Configuration file | Test status | -| ------------ | ------------- | ------------ | ------------------ | -------------------- | -| HESAI | Pandar 64 | Pandar64 | Pandar64.yaml | :heavy_check_mark: | -| HESAI | Pandar 40P | Pandar40P | Pandar40P.yaml | :heavy_check_mark: | -| HESAI | Pandar XT32 | PandarXT32 | PandarXT32.yaml | :heavy_check_mark: | -| HESAI | Pandar XT32M | PandarXT32M | PandarXT32M.yaml | :warning: | -| HESAI | Pandar QT64 | PandarQT64 | PandarQT64.yaml | :heavy_check_mark: | -| HESAI | Pandar QT128 | PandarQT128 | PandarQT128.yaml | :warning: | -| HESAI | Pandar AT128 | PandarAT128 | PandarAT128.yaml | :heavy_check_mark:\* | -| HESAI | Pandar 128E4X | Pandar128E4X | Pandar128E4X.yaml | :warning: | -| Velodyne | VLP-16 | VLP16 | VLP16.yaml | :warning: | -| Velodyne | VLP-16-HiRes | VLP16 | | :x: | -| Velodyne | VLP-32 | VLP32 | VLP32.yaml | :warning: | -| Velodyne | VLS-128 | VLS128 | VLS128.yaml | :warning: | -| Continental | ARS548 | ARS548 | ARS548.yaml | :warning: | - -Test status:\ -:heavy_check_mark:: complete\ -:warning:: some functionality yet to be tested\ -:x:: untested\ -\*: AT128 needs software version 3.50.8 or newer for the `scan_angle` setting to work correctly. - -## ROS parameters - -### Common ROS parameters - -Parameters shared by all supported models: - -| Parameter | Type | Default | Accepted values | Description | -| ------------ | ------ | ---------------- | -------------------------- | ---------------- | -| sensor_model | string | | See supported models | | -| return_mode | string | | See supported return modes | | -| frame_id | string | Sensor dependent | | ROS frame ID | -| scan_phase | double | 0.0 | degrees [0.0, 360.0] | Scan start angle | - -### Hesai specific parameters - -#### Supported return modes per model - -| Sensor model | return_mode | Mode | -| ------------ | -------------- | ------ | -| Pandar XT32M | Last | Single | -| Pandar XT32M | Strongest | Single | -| Pandar XT32M | LastStrongest | Dual | -| Pandar XT32M | First | Single | -| Pandar XT32M | LastFirst | Dual | -| Pandar XT32M | FirstStrongest | Dual | -| Pandar XT32M | Dual | Dual | -| --- | --- | --- | -| Pandar AT128 | Last | Single | -| Pandar AT128 | Strongest | Single | -| Pandar AT128 | LastStrongest | Dual | -| Pandar AT128 | First | Single | -| Pandar AT128 | LastFirst | Dual | -| Pandar AT128 | FirstStrongest | Dual | -| Pandar AT128 | Dual | Dual | -| --- | --- | --- | -| Pandar QT128 | Last | Single | -| Pandar QT128 | Strongest | Single | -| Pandar QT128 | LastStrongest | Dual | -| Pandar QT128 | First | Single | -| Pandar QT128 | LastFirst | Dual | -| Pandar QT128 | FirstStrongest | Dual | -| Pandar QT128 | Dual | Dual | -| --- | --- | --- | -| Pandar QT64 | Last | Single | -| Pandar QT64 | Dual | Dual | -| Pandar QT64 | First | Single | -| --- | --- | --- | -| Pandar 40P | Last | Single | -| Pandar 40P | Strongest | Single | -| Pandar 40P | Dual | Dual | -| --- | --- | --- | -| Pandar 64 | Last | Single | -| Pandar 64 | Strongest | Single | -| Pandar 64 | Dual | Dual | - -#### Hardware interface parameters - -| Parameter | Type | Default | Accepted values | Description | -| ------------------------------ | ------ | --------------- | ----------------- | ------------------------------ | -| frame_id | string | hesai | | ROS frame ID | -| sensor_ip | string | 192.168.1.201 | | Sensor IP | -| host_ip | string | 255.255.255.255 | | Host IP | -| data_port | uint16 | 2368 | | Sensor port | -| gnss_port | uint16 | 2369 | | GNSS port | -| frequency_ms | uint16 | 100 | milliseconds, > 0 | Time per scan | -| packet_mtu_size | uint16 | 1500 | | Packet MTU size | -| rotation_speed | uint16 | 600 | | Rotation speed | -| cloud_min_angle | uint16 | 0 | degrees [0, 360] | FoV start angle | -| cloud_max_angle | uint16 | 359 | degrees [0, 360] | FoV end angle | -| dual_return_distance_threshold | double | 0.1 | | Dual return distance threshold | -| diag_span | uint16 | 1000 | milliseconds, > 0 | Diagnostic span | -| setup_sensor | bool | True | True, False | Configure sensor settings | - -#### Driver parameters - -| Parameter | Type | Default | Accepted values | Description | -| ---------------- | ------ | ------- | --------------- | ---------------------- | -| frame_id | string | hesai | | ROS frame ID | -| calibration_file | string | | | LiDAR calibration file | -| correction_file | string | | | LiDAR correction file | - -### Velodyne specific parameters - -#### Supported return modes - -| return_mode | Mode | -| --------------- | ------------------ | -| SingleFirst | Single (First) | -| SingleStrongest | Single (Strongest) | -| SingleLast | Single (Last) | -| Dual | Dual | - -#### Hardware interface parameters - -| Parameter | Type | Default | Accepted values | Description | -| --------------- | ------ | --------------- | ----------------- | --------------- | -| frame_id | string | velodyne | | ROS frame ID | -| sensor_ip | string | 192.168.1.201 | | Sensor IP | -| host_ip | string | 255.255.255.255 | | Host IP | -| data_port | uint16 | 2368 | | Sensor port | -| gnss_port | uint16 | 2369 | | GNSS port | -| frequency_ms | uint16 | 100 | milliseconds, > 0 | Time per scan | -| packet_mtu_size | uint16 | 1500 | | Packet MTU size | -| cloud_min_angle | uint16 | 0 | degrees [0, 360] | FoV start angle | -| cloud_max_angle | uint16 | 359 | degrees [0, 360] | FoV end angle | - -#### Driver parameters - -| Parameter | Type | Default | Accepted values | Description | -| ---------------- | ------ | -------- | ---------------- | ----------------------------- | -| frame_id | string | velodyne | | ROS frame ID | -| calibration_file | string | | | LiDAR calibration file | -| min_range | double | 0.3 | meters, >= 0.3 | Minimum point range published | -| max_range | double | 300.0 | meters, <= 300.0 | Maximum point range published | -| cloud_min_angle | uint16 | 0 | degrees [0, 360] | FoV start angle | -| cloud_max_angle | uint16 | 359 | degrees [0, 360] | FoV end angle | - -## Software design overview - -![DriverOrganization](docs/diagram.png) - -## Hesai Sensor Setup - -New Hesai sensors do not provide a Web UI to verify and set up the sensor parameters. Instead, these offer a TCP-based protocol to obtain and set the configuration. Nebula sets these sensors at launch. However, settings such as Destination IP, Sensor IP, IP Mask, and Data Port might cause undesired sensor functioning if the driver gets mistakenly launched with inappropriate values. To overcome this problem, Nebula provides an additional setup script for these settings to avoid such scenarios. - -The script requires the installation of dependencies via pip: - -`$ pip3 install scripts/requirements.txt # first-time setup` - -Once the dependencies are installed, the setup script can be invoked using the following command: - -`$ python3 scripts/hesai_config --sensor-ip X.X.X.X` - -To set the parameters, please use the corresponding arguments as defined below: - -``` -usage: hesai_config.py [-h] --sensor-ip SENSOR_IP [--destination-ip DESTINATION_IP] - [--data-port DATA_PORT] [--new-sensor-ip NEW_SENSOR_IP] [--mask MASK] - -options: - -h, --help Show this help message and exit - --sensor-ip SENSOR_IP - The current sensor IP address - --destination-ip DESTINATION_IP - Change the current destination IP address to the given one - --data-port DATA_PORT - Change the current destination LiDAR data port to the given one - --new-sensor-ip NEW_SENSOR_IP - Change the current sensor IP address to the given one - --mask MASK Change the current net mask to the given one. You can pass it in either a - CIDR notation or dotted-decimal notation. -``` - -## How to evaluate performance - -You can evaluate Nebula performance on a given rosbag and sensor model using the below tools. -The profiling runner is most accurate when assigning isolated cores via the `-c `. -CPU frequencies are locked/unlocked automatically by the runner to increase repeatability. - -Run profiling for each version you want to compare: - -```bash -./scripts/profiling_runner.bash baseline -m Pandar64 -b ~/my_rosbag -c 2 -t 20 -n 3 -git checkout my_improved_branch -./scripts/profiling_runner.bash improved -m Pandar64 -b ~/my_rosbag -c 2 -t 20 -n 3 -``` - -Show results: - +For example, for a Hesai Pandar40P sensor: ```bash -pip3 install scripts/requirements.txt # first-time setup -python3 scripts/plot_times.py baseline improved +ros2 launch nebula_ros hesai_launch_all_hw.xml sensor_model:=Pandar40P ``` diff --git a/docs/about.md b/docs/about.md index e69de29bb..db95e44a5 100644 --- a/docs/about.md +++ b/docs/about.md @@ -0,0 +1,7 @@ +# About Nebula + +WIP, please check back soon! + + + + diff --git a/docs/add_sensor.md b/docs/add_sensor.md deleted file mode 100644 index 73e1c183b..000000000 --- a/docs/add_sensor.md +++ /dev/null @@ -1,7 +0,0 @@ -# How to add your sensor - -1. Add your sensor to the `SensorModel` enumeration class located in the `nebula_common.hpp` header inside the `nebula_common` package. -2. Add your sensor model string to the `SensorModelFromString` method in the `nebula_common.hpp` header inside the `nebula_common` package. -3. Write the sensor decoder for your sensor. This class is in charge of converting raw packets to point clouds. This class should implement the abstract class defined in `nebula_driver_base.hpp` inside the `nebula_decoders` package. Add methods as the sensor requires. -4. Write the sensor hardware interface. This class is in charge of obtaining raw packets from the sensor using the `transport_drivers` library, accumulating them to form a scan, and making them available for consumption through callbacks. This class should implement the `nebula_hw_interface_base.hpp` inside the `nebula_hw_interfaces` package. Add methods as the sensor requires. -5. Write the ROS wrappers. The ROS wrappers use the sensor libraries to obtain raw data, decode it and convert it to PointCloud2 ROS messages. The Decoder wrapper receives the configuration and calibration data from files and sends them as structures to the decoder and the hw_interface. diff --git a/docs/contributing.md b/docs/contributing.md new file mode 100644 index 000000000..ab0ef86ba --- /dev/null +++ b/docs/contributing.md @@ -0,0 +1,3 @@ +# Contributing to Nebula + +WIP - please check back soon! \ No newline at end of file diff --git a/docs/design.md b/docs/design.md index 30ef4a09f..de352d4a9 100644 --- a/docs/design.md +++ b/docs/design.md @@ -1,102 +1,5 @@ -# Nebula requirements +# Nebula design -The driver follows the following functional requirements: -ドライバは、次の機能的な要求に応えなければならない。 - -## Hardware interface independent - -The data acquisition and communication with the sensor must not be bound to a specific hardware interface. -センサでのデータ取得と通信は、特定のハードウェアに縛られてはならない。 - -### Why? - -Writing a general-purpose driver independent of the interface will support different types of hardware interfaces. -インターフェイスに依存しない汎用ドライバを書くことで、異なったタイプのハードウェアインターフェイスに対応することができる。 - -## Sensor Control - -The driver should obtain, set, and confirm the desired sensor configuration at launch, i.e., scan frequency, synchronization methods, etc. -ドライバは起動時に、望ましいセンサ設定(スキャン周波数、同期方法等)を取得、設定、確認できる必要がある。 - -### Why? - -The sensor control will ensure that the sensor works in the expected mode as it was initially intended. -これによって、センサが当初より意図していたモードで動いていることが確認できる。 - -## Configurable output cloud - -The ROS wrapper should be able to define the desired output format of the point cloud. i.e., customize the fields to be contained in the final output cloud. -ROS ラッパーは点群の望ましい出力フォーマットで定義できなければならない(最終的な出力クラウドに含まれるフィールドをカスタマイズできる) -In addition, it should be able to generate the corresponding 2D range image for the output point cloud. - -さらに、出力された点群を対応する二次元レンジ画像に生成することができなければならない。 -If the sensor allows it, have an option to add a minimum and maximum range distance as an option. For instance, if the user launches the driver with a range limit set to 0, the driver will not perform any filtering. -センサが許可している場合は、オプションとして最小値と最大値のレンジ距離を追加することができる。例えば、ユーザーが範囲制限を 0 に設定してドライバーを起動した場合、ドライバはフィルタリングを行わない。 -The driver should have an option to define if the output cloud is of a fixed size or dynamic size. If a fixed size is selected, the output cloud must include NaN values for those lasers without any return. If a dynamic size is selected, the lasers with no valid returns are to be removed. -ドライバは、出力クラウドを固定されたサイズか、もしくはダイナミックサイズにするかを定義するオプションが必要である。固定されたサイズを選択した場合、出力クラウドは、リターンのないレーザの NaN 値を含まなければならない。ダイナミックサイズを選択した場合、リターンのないレーザは削除される。 -Default behavior: Dynamic, remove invalid laser returns (NaN). -デフォルトの動作:ダイナミック、無効なレーザリターンを削除。(NaN) - -### Why? - -The configurable output will allow the generation of the point cloud according to the expected use case application. -これによって、予定したユースケースアプリケーションにより必要な出力を生成することができる。 - -## Sensor Metadata - -The driver should include the following metadata for each generated point cloud: -ドライバは、生成された点群それぞれに、次のメタデータが含まれなければならない: - -### Calibration data キャリブレーションデータ - -Contains the sensor calibration parameters used to generate the point cloud from the raw data. -生データから点群を生成するのに使用したセンサキャリブレーションパラメータ - -### Sensor settings センサ設定 - -The configuration mode in which the sensor is being executed: -センサが実行された設定モード - -### Synchronization mode (PTP, PPS/NMEA) 同期モード(PTP, PPS/NMEA) - -Sensor Type -センサタイプ -Sensor Model -センサモデル -Scan frequency -スキャン周波数 - -### Why? - -The processed point cloud or the raw data does not always contain the state on which the sensor was run. Moreover, having this information at hand will help identify, classify and understand the situation of the recorded data. -処理した点群、つまり生データは、常にセンサが作動した状態を含んでいるとは限らない。手元に情報があることは、記録データの状況を素早く把握し、分類し、理解することの助けになる。 - -## Multi echo compatible - -The sensor should consider the possibility of the future inclusion of more than two echos. -センサは2つ以上のエコーが将来的に含まれる可能性があることを考慮すべきである。 - -### Why? - -Multi-echo support will help to future-proof the driver according to new features included or used in new sensors. In addition, multiple echo support has been proven to improve sensor resilience against weather conditions such as rain, fog, and snow. -これによって、新しいセンサに搭載された、もしくは、開発された新機能によって、ドライバの将来性を高めることができる。複数のエコーに対応することで、雨や霧、雪などの天候条件に対して、センサの回復力が改善されることが証明されている。 - -## ROS independent - -The objects used inside the driver must be ROS independent. -ドライバ内に使用されている API 等の対象物は、ROS に依存してはならない。 - -### Why? - -The third-party dependency reduction allows any software to be quickly updated without waiting for external dependencies to be updated. -これにより、どんなソフトウェアでも、アップデートのための外部依存を待つ必要がなく、素早くアップデートすることができる。 - -## Offline ready - -The data parser API inside the driver should not be designed to expect the data to be received in a real-time stream. -ドライバ内のデータパーサ API は、データをリアルタイムストリームで受け取るように設計されるべきではない。 - -### Why? - -Offline processing will help process the data faster than in real-time. -これにより、データがセンサの代わりにログファイルから発信された時にデータ処理をリアルタイムより速く処理することができる。 +WIP - please check back soon! +For now, here is some related information about the Hesai decoder design: +[Hesai decoder design](hesai_decoder_design.md) diff --git a/docs/index.md b/docs/index.md index ea4de66a7..c5c3153b1 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,72 +1,32 @@ -# Nebula introduction - -The project is separated into four main parts: -プロジェクトは主となる 4 つのパートに分かれている: -Lidar ドライバ、ROS ラッパー、HWI インターフェイスだ。 - -- Common: `nebula_common`. This packages contains the structures, data types, calibration and configuration definitions used among all the packages. -- Drivers: `nebula_decoders`. The Drivers take care of all the data parsing and conversion. Lidar ドライバは、全てのセンサ通信とデータパーシングを管理している。 -- ROS Nodes Wrappers: `nebula_ros`, The ROSWrappers are a lightweight layer responsible for the data conversion between the LidarDriver point cloud and the corresponding ROS counterparts. The ROSWrapper also provides methods for configuration and the obtention of the status information of the Lidar. ROS ラッパーは、Lidar ドライバ点群と対応する ROS のカウンターパーツのデータ変換を掌る軽量のレイヤである。 ROS ラッパーは、構成方法、Lidar のステータス情報取得の方法を提供している。 -- HWInterface: `nebula_hw_interfaces`. The HWInterface offers an abstraction layer between the parser and the sensor communication. HW インターフェイスは、パーサとセンサ間の抽象化レイヤを提供している。 - -# Nebula Common - -The Nebula common package contains structure definition such as configuration, calibration, point types. -It also contains other common status strings and conversions used among all the packages. - -## Point Types - -Nebula supports three point cloud output types. -However, it can easily be extended to support other custom point cloud types. - -These definitions can be found in the `nebula_common/include/point_types.hpp`. - -### PointXYZIR - -| Field | Type | Units | Description | -| ------------- | ------- | ----- | -------------------------------------------------------------------- | -| `x` | `float` | `m` | Contains the abscissa member of the point in cartesian coordinates. | -| `y` | `float` | `m` | Contains the ordinate member of the point in cartesian coordinates. | -| `z` | `float` | `m` | Contains the applicate member of the point in cartesian coordinates. | -| `intensity` | `uint8` | | Contains the laser energy return value as reported by the sensor. | -| `return type` | `uint8` | | Contains the lase return type according to the sensor configuration. | - -### PointXYZICAETR - -| Field | Type | Units | Description | -| ------------- | ------- | ----- | -------------------------------------------------------------------- | -| `x` | `float` | `m` | Contains the abscissa member of the point in cartesian coordinates. | -| `y` | `float` | `m` | Contains the ordinate member of the point in cartesian coordinates. | -| `z` | `float` | `m` | Contains the applicate member of the point in cartesian coordinates. | -| `intensity` | `uint8` | | Contains the laser energy return value as reported by the sensor. | -| `channel` | `uint8` | | Contains the laser channel id. | -| `azimuth` | `float` | `rad` | Contains the azimuth of the current point. | -| `elevation` | `float` | `rad` | Contains the elevation of the current point. | -| `timestamp` | `float` | `ns` | Contains the relative time to the triggered scan time. | -| `return type` | `uint8` | | Contains the lase return type according to the sensor configuration. | - -### PointXYZICATR - -| Field | Type | Units | Description | -| ------------- | ------- | --------- | -------------------------------------------------------------------- | -| `x` | `float` | `m` | Contains the abscissa member of the point in cartesian coordinates. | -| `y` | `float` | `m` | Contains the ordinate member of the point in cartesian coordinates. | -| `z` | `float` | `m` | Contains the applicate member of the point in cartesian coordinates. | -| `intensity` | `uint8` | | Contains the laser energy return value as reported by the sensor. | -| `channel` | `uint8` | | Contains the laser channel id. | -| `azimuth` | `float` | `degrees` | Contains the azimuth of the current point. | -| `timestamp` | `float` | `ns` | Contains the relative time to the triggered scan time. | -| `return type` | `uint8` | | Contains the lase return type according to the sensor configuration. | - -### PointXYZIRADT - -| Field | Type | Units | Description | -| ------------- | ------- | --------- | -------------------------------------------------------------------------- | -| `x` | `float` | `m` | Contains the abscissa member of the point in cartesian coordinates. | -| `y` | `float` | `m` | Contains the ordinate member of the point in cartesian coordinates. | -| `z` | `float` | `m` | Contains the applicate member of the point in cartesian coordinates. | -| `intensity` | `uint8` | | Contains the laser energy return value as reported by the sensor. | -| `return type` | `uint8` | | Contains the lase return type according to the sensor configuration. | -| `azimuth` | `float` | `degrees` | Contains the azimuth of the current point. | -| `distance` | `float` | `m` | Contains the distance from the sensor origin to this echo on the XY plane. | -| `timestamp` | `float` | `ns` | Contains the relative time to the triggered scan time. | +# Welcome to the Nebula documentation +Welcome to the Nebula documentation. Here you will find information about the background of the project, how to install and use with ROS 2, and also how to add new sensors to the Nebula driver. + +# About Nebula +Nebula is a sensor driver platform that is designed to provide a unified framework for as wide a variety of devices as possible. +While it primarily targets Ethernet-based LiDAR sensors, it aims to be easily extendable to support new sensors and interfaces. +Nebula works with ROS 2 and is the recommended sensor driver for the [Autoware](https://autoware.org/) project. The project aims to provide: + +- A universal sensor driver + - Supporting an increasing number of LiDAR, radar and camera sensors +- 100% open source, with a no-binaries policy +- ROS 2 wrappers for easy inclusion in robotics and self-driving vehicle projects +- A driver solution to suit current Autoware requirements + - Interfaces and pointcloud type updates made in unison with Autoware developments + +For more information, please refer to [About Nebula](about.md). + +# Getting started +- [Installation](installation.md) +- [Launching with ROS 2](usage.md) + +# Nebula architecture +- [Design](design.md) +- [Parameters](parameters.md) +- [Point cloud types](point_types.md) + +# Supported sensors +- [Supported sensors](supported_sensors.md) + +# Development +- [Tutorials](tutorials.md) +- [Contributing](contributing.md) \ No newline at end of file diff --git a/docs/installation.md b/docs/installation.md new file mode 100644 index 000000000..07e5eec43 --- /dev/null +++ b/docs/installation.md @@ -0,0 +1,39 @@ +# Installing Nebula + +## Requirements +Nebula requires ROS 2 (Galactic or Humble) to build the ROS 2 wrapper. +Please see the [ROS 2 documentation](https://docs.ros.org/en/humble/index.html) for how to install. + + +## Getting the source and building +> **Note** +> +> A [TCP enabled version of ROS' Transport Driver](https://github.com/mojomex/transport_drivers/tree/mutable-buffer-in-udp-callback) is required to use Nebula. +> It is installed automatically into your workspace using the below commands. However, if you already have ROS transport driver binaries installed, you will have to uninstall them to avoid conflicts (replace `humble` with your ROS distribution): +> `sudo apt remove ros-humble-udp-driver ros-humble-io-context` + +To build Nebula run the following commands in your workspace: + +```bash +# In workspace +mkdir src +git clone https://github.com/tier4/nebula.git src +# Import dependencies +vcs import src < src/build_depends.repos +rosdep install --from-paths src --ignore-src -y -r +# Build Nebula +colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Release +``` + +## Testing your build + +To run Nebula unit tests: +```bash +colcon test --event-handlers console_cohesion+ --packages-above nebula_common +``` + +Show results: + +```bash +colcon test-result --all +``` \ No newline at end of file diff --git a/docs/parameters.md b/docs/parameters.md new file mode 100644 index 000000000..466b05c44 --- /dev/null +++ b/docs/parameters.md @@ -0,0 +1,121 @@ +# ROS parameters for supported sensors + +> **Note** +> +> The information on this page may be out of date. +> Please refer to the configuration in the relevant `*sensor_model*.param.yaml` file for you sensor, to confirm what parameters are available, + +## Common ROS parameters + +Parameters shared by all supported models: + +| Parameter | Type | Default | Accepted values | Description | +| ------------ | ------ | ---------------- | -------------------------- | ---------------- | +| sensor_model | string | | See supported models | | +| return_mode | string | | See supported return modes | | +| frame_id | string | Sensor dependent | | ROS frame ID | +| scan_phase | double | 0.0 | degrees [0.0, 360.0] | Scan start angle | + +## Hesai specific parameters + +### Supported return modes per model + +| Sensor model | return_mode | Mode | +| ------------ | -------------- | ------ | +| Pandar XT32M | Last | Single | +| Pandar XT32M | Strongest | Single | +| Pandar XT32M | LastStrongest | Dual | +| Pandar XT32M | First | Single | +| Pandar XT32M | LastFirst | Dual | +| Pandar XT32M | FirstStrongest | Dual | +| Pandar XT32M | Dual | Dual | +| --- | --- | --- | +| Pandar AT128 | Last | Single | +| Pandar AT128 | Strongest | Single | +| Pandar AT128 | LastStrongest | Dual | +| Pandar AT128 | First | Single | +| Pandar AT128 | LastFirst | Dual | +| Pandar AT128 | FirstStrongest | Dual | +| Pandar AT128 | Dual | Dual | +| --- | --- | --- | +| Pandar QT128 | Last | Single | +| Pandar QT128 | Strongest | Single | +| Pandar QT128 | LastStrongest | Dual | +| Pandar QT128 | First | Single | +| Pandar QT128 | LastFirst | Dual | +| Pandar QT128 | FirstStrongest | Dual | +| Pandar QT128 | Dual | Dual | +| --- | --- | --- | +| Pandar QT64 | Last | Single | +| Pandar QT64 | Dual | Dual | +| Pandar QT64 | First | Single | +| --- | --- | --- | +| Pandar 40P | Last | Single | +| Pandar 40P | Strongest | Single | +| Pandar 40P | Dual | Dual | +| --- | --- | --- | +| Pandar 64 | Last | Single | +| Pandar 64 | Strongest | Single | +| Pandar 64 | Dual | Dual | + +### Hardware interface parameters + +| Parameter | Type | Default | Accepted values | Description | +| ------------------------------ | ------ | --------------- | ----------------- | ------------------------------ | +| frame_id | string | hesai | | ROS frame ID | +| sensor_ip | string | 192.168.1.201 | | Sensor IP | +| host_ip | string | 255.255.255.255 | | Host IP | +| data_port | uint16 | 2368 | | Sensor port | +| gnss_port | uint16 | 2369 | | GNSS port | +| frequency_ms | uint16 | 100 | milliseconds, > 0 | Time per scan | +| packet_mtu_size | uint16 | 1500 | | Packet MTU size | +| rotation_speed | uint16 | 600 | | Rotation speed | +| cloud_min_angle | uint16 | 0 | degrees [0, 360] | FoV start angle | +| cloud_max_angle | uint16 | 359 | degrees [0, 360] | FoV end angle | +| dual_return_distance_threshold | double | 0.1 | | Dual return distance threshold | +| diag_span | uint16 | 1000 | milliseconds, > 0 | Diagnostic span | +| setup_sensor | bool | True | True, False | Configure sensor settings | + +### Driver parameters + +| Parameter | Type | Default | Accepted values | Description | +| ---------------- | ------ | ------- | --------------- | ---------------------- | +| frame_id | string | hesai | | ROS frame ID | +| calibration_file | string | | | LiDAR calibration file | +| correction_file | string | | | LiDAR correction file | + +## Velodyne specific parameters + +### Supported return modes + +| return_mode | Mode | +| --------------- | ------------------ | +| SingleFirst | Single (First) | +| SingleStrongest | Single (Strongest) | +| SingleLast | Single (Last) | +| Dual | Dual | + +### Hardware interface parameters + +| Parameter | Type | Default | Accepted values | Description | +| --------------- | ------ | --------------- | ----------------- | --------------- | +| frame_id | string | velodyne | | ROS frame ID | +| sensor_ip | string | 192.168.1.201 | | Sensor IP | +| host_ip | string | 255.255.255.255 | | Host IP | +| data_port | uint16 | 2368 | | Sensor port | +| gnss_port | uint16 | 2369 | | GNSS port | +| frequency_ms | uint16 | 100 | milliseconds, > 0 | Time per scan | +| packet_mtu_size | uint16 | 1500 | | Packet MTU size | +| cloud_min_angle | uint16 | 0 | degrees [0, 360] | FoV start angle | +| cloud_max_angle | uint16 | 359 | degrees [0, 360] | FoV end angle | + +### Driver parameters + +| Parameter | Type | Default | Accepted values | Description | +| ---------------- | ------ | -------- | ---------------- | ----------------------------- | +| frame_id | string | velodyne | | ROS frame ID | +| calibration_file | string | | | LiDAR calibration file | +| min_range | double | 0.3 | meters, >= 0.3 | Minimum point range published | +| max_range | double | 300.0 | meters, <= 300.0 | Maximum point range published | +| cloud_min_angle | uint16 | 0 | degrees [0, 360] | FoV start angle | +| cloud_max_angle | uint16 | 359 | degrees [0, 360] | FoV end angle | \ No newline at end of file diff --git a/docs/point_types.md b/docs/point_types.md new file mode 100644 index 000000000..f19f5d30b --- /dev/null +++ b/docs/point_types.md @@ -0,0 +1,56 @@ +# Nebula point cloud types + +Nebula supports three point cloud output types. +However, it can easily be extended to support other custom point cloud types. + +These definitions can be found in the `nebula_common/include/point_types.hpp`. + +## PointXYZIR + +| Field | Type | Units | Description | +| ------------- | ------- | ----- | -------------------------------------------------------------------- | +| `x` | `float` | `m` | Contains the abscissa member of the point in cartesian coordinates. | +| `y` | `float` | `m` | Contains the ordinate member of the point in cartesian coordinates. | +| `z` | `float` | `m` | Contains the applicate member of the point in cartesian coordinates. | +| `intensity` | `uint8` | | Contains the laser energy return value as reported by the sensor. | +| `return type` | `uint8` | | Contains the lase return type according to the sensor configuration. | + +## PointXYZICAETR + +| Field | Type | Units | Description | +| ------------- | ------- | ----- | -------------------------------------------------------------------- | +| `x` | `float` | `m` | Contains the abscissa member of the point in cartesian coordinates. | +| `y` | `float` | `m` | Contains the ordinate member of the point in cartesian coordinates. | +| `z` | `float` | `m` | Contains the applicate member of the point in cartesian coordinates. | +| `intensity` | `uint8` | | Contains the laser energy return value as reported by the sensor. | +| `channel` | `uint8` | | Contains the laser channel id. | +| `azimuth` | `float` | `rad` | Contains the azimuth of the current point. | +| `elevation` | `float` | `rad` | Contains the elevation of the current point. | +| `timestamp` | `float` | `ns` | Contains the relative time to the triggered scan time. | +| `return type` | `uint8` | | Contains the lase return type according to the sensor configuration. | + +## PointXYZICATR + +| Field | Type | Units | Description | +| ------------- | ------- | --------- | -------------------------------------------------------------------- | +| `x` | `float` | `m` | Contains the abscissa member of the point in cartesian coordinates. | +| `y` | `float` | `m` | Contains the ordinate member of the point in cartesian coordinates. | +| `z` | `float` | `m` | Contains the applicate member of the point in cartesian coordinates. | +| `intensity` | `uint8` | | Contains the laser energy return value as reported by the sensor. | +| `channel` | `uint8` | | Contains the laser channel id. | +| `azimuth` | `float` | `degrees` | Contains the azimuth of the current point. | +| `timestamp` | `float` | `ns` | Contains the relative time to the triggered scan time. | +| `return type` | `uint8` | | Contains the lase return type according to the sensor configuration. | + +## PointXYZIRADT + +| Field | Type | Units | Description | +| ------------- | ------- | --------- | -------------------------------------------------------------------------- | +| `x` | `float` | `m` | Contains the abscissa member of the point in cartesian coordinates. | +| `y` | `float` | `m` | Contains the ordinate member of the point in cartesian coordinates. | +| `z` | `float` | `m` | Contains the applicate member of the point in cartesian coordinates. | +| `intensity` | `uint8` | | Contains the laser energy return value as reported by the sensor. | +| `return type` | `uint8` | | Contains the lase return type according to the sensor configuration. | +| `azimuth` | `float` | `degrees` | Contains the azimuth of the current point. | +| `distance` | `float` | `m` | Contains the distance from the sensor origin to this echo on the XY plane. | +| `timestamp` | `float` | `ns` | Contains the relative time to the triggered scan time. \ No newline at end of file diff --git a/docs/supported_sensors.md b/docs/supported_sensors.md new file mode 100644 index 000000000..a142677f4 --- /dev/null +++ b/docs/supported_sensors.md @@ -0,0 +1,45 @@ +# Supported sensors + +Nebula currently supports the following sensor models, where `sensor_model` is the ROS parameter to be used at launch: + +## Hesai LiDARs + +| Model | `sensor_model` | Configuration file | Test status | +| ------------- | -------------- | ------------------ | -------------------- | +| Pandar64 | Pandar64 | Pandar64.yaml | ✅ | +| Pandar 40P | Pandar40P | Pandar40P.yaml | ✅ | +| Pandar XT32 | PandarXT32 | PandarXT32.yaml | ✅ | +| Pandar XT32M | PandarXT32M | PandarXT32M.yaml | ⚠️ | +| Pandar QT64 | PandarQT64 | PandarQT64.yaml | ✅ | +| Pandar QT128 | PandarQT128 | PandarQT128.yaml | ⚠️ | +| Pandar AT128 | PandarAT128 | PandarAT128.yaml | ✅\* | +| Pandar 128E4X | Pandar128E4X | Pandar128E4X.yaml | ⚠️ | + +## Velodyne LiDARs + +| Model | `sensor_model` | Configuration file | Test status | +| ------------- | -------------- | ------------------ | -------------------- | +| VLP-16 | VLP16 | VLP16.yaml | ⚠️ | +| VLP-16-HiRes | VLP16 | | ❌ | +| VLP-32 | VLP32 | VLP32.yaml | ⚠️ | +| VLS-128 | VLS128 | VLS128.yaml | ⚠️ | + +## Robosense LiDARs + +| Model | `sensor_model` | Configuration file | Test status | +| ------------- | -------------- | ------------------ | -------------------- | +| Bpearl | Bpearl | Bpearl.yaml | ⚠️ | +| Helios | Helios | Helios.yaml | ⚠️ | + +## Continental radars + +| Model | `sensor_model` | Configuration file | Test status | +| ------------- | -------------- | ------------------ | -------------------- | +| ARS548 | ARS548 | ARS548.yaml | ⚠️ | + + +Test status:\ +✅: complete\ +⚠️: some functionality yet to be tested\ +❌: untested\ +\*: AT128 needs software version 3.50.8 or newer for the `scan_angle` setting to work correctly. \ No newline at end of file diff --git a/docs/tutorials.md b/docs/tutorials.md new file mode 100644 index 000000000..78be591cc --- /dev/null +++ b/docs/tutorials.md @@ -0,0 +1,4 @@ +# Nebula tutorials + +WIP - we are currently working on making tutorials for Nebula development, so please check back soon! +In the meantime, check out the [tutorial branch](https://github.com/mojomex/nebula/tree/single-node-refactor-tutorial). \ No newline at end of file diff --git a/docs/usage.md b/docs/usage.md new file mode 100644 index 000000000..5448cf389 --- /dev/null +++ b/docs/usage.md @@ -0,0 +1,16 @@ +# Running Nebula + +## Launch with default parameters +To launch Nebula as a ROS 2 node with default parameters for your sensor model: + +```bash +ros2 launch nebula_ros *sensor_vendor_name*_launch_all_hw.xml sensor_model:=*sensor_model_name* +``` + +For example, for a Hesai Pandar40P sensor: +```bash +ros2 launch nebula_ros hesai_launch_all_hw.xml sensor_model:=Pandar40P +``` + +## Sensor configuration +WIP \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index febbda15c..4b8513cec 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -35,13 +35,18 @@ use_directory_urls: true ### Navigation ### nav: - Home: index.md + - About: about.md + - Installation: installation.md + - Launching: usage.md - Design: design.md - - About Nebula: about.md - - Add Your Sensor: add_sensor.md - - Hesai Decoder Design: hesai_decoder_design.md - - Nebula Common: nebula_common/links.md - - Nebula Decoders: nebula_decoders/links.md - - Nebula HW Interfaces: nebula_hw_interfaces/links.md + - Parameters: parameters.md + - Point cloud types: point_types.md + - Supported sensors: supported_sensors.md + - Tutorials: tutorials.md + - Contributing: contributing.md + - Nebula common: nebula_common/links.md + - Nebula decoders: nebula_decoders/links.md + - Nebula HW interfaces: nebula_hw_interfaces/links.md - Nebula ROS: nebula_ros/links.md ### Extra Settings ###