generated from tier4/ros2-project-template
-
Notifications
You must be signed in to change notification settings - Fork 58
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
feat: support Aeva Aeries II #169
Open
mojomex
wants to merge
58
commits into
tier4:main
Choose a base branch
from
mojomex:aeva-aries2-support
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
58 commits
Select commit
Hold shift + click to select a range
c9be206
refactor(mt_queue): move to nebula_common
mojomex 438f986
refactor(expected): add shorthand value_or_throw function
mojomex ca35b24
feat(hw_interfaces): light-weight TCP/UDP interfaces with abstractions
mojomex e60b7e8
feat(nebula_common): add nlohmann_json and helper functions
mojomex d4d0e7c
chore(watchdog_timer): clean up watchdog timer
mojomex 2838e77
chore: make merged changed comply with pre-commit
mojomex 26aeef4
feat(aeva): add sensor model and type support
mojomex fa5665c
feat(aeva): add low-level Aeva TCP protocol support
mojomex 56bdf16
feat(aeva): add parsers for most important data streams
mojomex 15f00ca
feat(aeva): add hardware interface
mojomex 6f96519
test(aeva): add hw interface test
mojomex 9ce7ba6
feat(aeva): add decoder
mojomex 2db7929
feat(aeva): add ros wrapper
mojomex d23c93d
feat(aeva): add launch and config files, fix cspell
mojomex e00572c
docs(aeva): added to supported sensors
mojomex fdaac59
docs(aeva): add XYZVIRCAEDT point type
mojomex 9441d9d
fix(aeries2_decoder): un-mirror the pointcloud
mojomex 3b94166
refactor(aeva)!: rename `v` point field to `distance_rate`
mojomex 1ee0c92
fix(nebula_ros): remove erroneous header import
mojomex 903e1b7
fix(aeva): prevent fallthrough in telemetry parsing switch
mojomex cc353ce
fix(aeva): fix starving when registering raw packet callback
mojomex 9394cb6
chore(aeva): allow for slightly lower pointcloud frequency, more visi…
mojomex b309508
chore(aeva)!: change `distance_rate` point field to `range_rate`
mojomex 8964f6b
fix(aeva): output return types
mojomex 7011769
fix(aeva): display error codes correctly in monitor
mojomex e309ad5
chore(aeva): align format with pretty-printing PR
mojomex 32d80f3
feat(aeva): support runtime parameter changes
mojomex 2fb591b
chore(aeva): rename occurrences of `aries` to `aeries`
mojomex 7896bd1
fix(aeva_api): stop thread gracefully
mojomex 65258c3
test(aeva): fix tests
mojomex 185b0d8
fix(aeva): allow multiple responses in reconfig stream, thread safety…
mojomex f180138
feat(aeva): switch to json config, add many more config options
mojomex d6cd72f
chore(aeva): set frame id to `nebula`
mojomex 063d87b
feat(aeva): correct handling of the currently active return mode
mojomex 1519e99
chore: accept suggestion to make pointcloud topic namespace local
mojomex 6ac8184
chore: remove json_fwd header imports
mojomex e1be90c
chore: move diagnostics topic to local namespace
mojomex 03622ad
fix(aeva): increase buffer size for packet replay as drops were observed
mojomex a353f72
fix(aeva): add missing diagnostic_updater dependency in CMakeLists.txt
mojomex 7d15607
fix(aeva): delete elevation_auto_adjustment param that is not present…
mojomex 0c94de3
fix(aeva): change referenced function names after merge
mojomex 6c5b183
docs(aeva): add parameter table akin to #195
mojomex 8f8171f
docs(aeva): mention tested firmware version (14.0.0)
mojomex 0af2516
refactor(aeva): implement clang-tidy changes
mojomex c692aa2
chore(aeva): rename Aeries2 to Aeries II
mojomex 7bccfec
chore(aeva_api): put constants and types to the top of the file
mojomex 6c3bd3b
refactor(aeva): create aeva namespace inside connections namespace
mojomex 24d135f
chore(aeva): move hardcoded port numbers to constants
mojomex 4fcd9ee
chore(aeva): remove pointer hackery for cleaner code
mojomex 2b2fe38
chore(nebula_common): add version requirement for nlohmann_json
mojomex f039c36
chore(aeva): use arg with choices instead of textual descriptions for…
mojomex 8139c6d
feat(nebula_launch): add Aeva sensors to the generic launch file
mojomex 2dc01ad
chore(hesai): remove spurious mt_queue import after Aeva rebase
mojomex a75e32f
chore(aeva): remove pragma once in C file
mojomex b248dee
test(aeva): fix wrongly compiledand thus skipped unit test
mojomex 896943d
ci(pre-commit): autofix
pre-commit-ci[bot] 0c16d01
fix(aeva): remove JSON schemarequirement of now-non-existent parameter
mojomex dc8f483
Merge branch 'aeva-aries2-support' of github.com:mojomex/nebula into …
mojomex File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{{ json_to_markdown("nebula_ros/schema/Aeries2.schema.json") }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// Copyright 2024 TIER IV, Inc. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#pragma once | ||
|
||
#include "nebula_common/nebula_common.hpp" | ||
#include "nebula_common/util/parsing.hpp" | ||
|
||
#include <nlohmann/json.hpp> | ||
|
||
#include <optional> | ||
#include <ostream> | ||
#include <string> | ||
|
||
namespace nebula::drivers::aeva | ||
{ | ||
|
||
using nlohmann::json; | ||
|
||
struct Aeries2Config : public SensorConfigurationBase | ||
{ | ||
std::string sensor_ip; | ||
json tree; | ||
|
||
[[nodiscard]] std::optional<ReturnMode> get_return_mode() const | ||
{ | ||
auto mode_name = util::get_if_exists<std::string>(tree, {"dsp_control", "second_peak_type"}); | ||
|
||
if (!mode_name) return {}; | ||
if (mode_name == "strongest") return ReturnMode::DUAL_STRONGEST_SECONDSTRONGEST; | ||
if (mode_name == "farthest") return ReturnMode::DUAL_STRONGEST_LAST; | ||
if (mode_name == "closest") return ReturnMode::DUAL_STRONGEST_FIRST; | ||
|
||
return ReturnMode::UNKNOWN; | ||
} | ||
|
||
friend std::ostream & operator<<(std::ostream & os, const Aeries2Config & arg) | ||
{ | ||
os << "Aeva Aeries II Sensor Configuration:\n"; | ||
os << "Sensor Model: " << arg.sensor_model << '\n'; | ||
os << "Frame ID: " << arg.frame_id << '\n'; | ||
os << "Sensor IP: " << arg.sensor_ip; | ||
|
||
for (const auto & category : arg.tree.items()) { | ||
os << '\n' << category.key() << ":"; | ||
auto category_settings = category.value(); | ||
for (const auto & setting : category_settings.items()) { | ||
os << "\n " << setting.key() << ": " << setting.value(); | ||
} | ||
} | ||
|
||
return os; | ||
} | ||
}; | ||
|
||
} // namespace nebula::drivers::aeva |
196 changes: 196 additions & 0 deletions
196
nebula_common/include/nebula_common/aeva/packet_types.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
// Copyright 2024 TIER IV, Inc. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#pragma once | ||
|
||
#include <nlohmann/json.hpp> | ||
|
||
#include <cstddef> | ||
#include <cstdint> | ||
#include <optional> | ||
#include <ostream> | ||
#include <string> | ||
#include <vector> | ||
|
||
namespace nebula::drivers::aeva | ||
{ | ||
using nlohmann::json; | ||
|
||
#pragma pack(push, 1) | ||
|
||
template <typename storage_t, size_t n_fractional_bits> | ||
struct FixedPoint | ||
{ | ||
[[nodiscard]] float value() const { return value_ * std::pow(2., -1. * n_fractional_bits); } | ||
|
||
private: | ||
storage_t value_; | ||
}; | ||
|
||
template <size_t n_bytes> | ||
struct Padding | ||
{ | ||
uint8_t padding[n_bytes]; // NOLINT | ||
}; | ||
|
||
struct SomeIpHeader | ||
{ | ||
uint16_t service_id; | ||
uint16_t method_id; | ||
uint32_t message_length; | ||
uint16_t client_id; | ||
uint16_t session_id; | ||
uint8_t protocol; | ||
uint8_t interface_version; | ||
uint8_t message_type; | ||
uint8_t return_code; | ||
uint32_t tp_header_offset : 28; | ||
uint32_t tp_header : 4; | ||
}; | ||
|
||
struct MessageHeader | ||
{ | ||
uint8_t major_version : 4; | ||
uint8_t minor_version : 4; | ||
uint8_t message_type; | ||
uint16_t sequence_id; | ||
uint32_t message_length; | ||
int64_t acquisition_time_ns; | ||
int64_t publish_time_ns; | ||
}; | ||
|
||
struct PointcloudMsgSubheaderAndMetadata | ||
{ | ||
uint16_t aeva_marker; | ||
uint8_t platform; | ||
uint8_t reserved_1; | ||
uint16_t ns_per_index; | ||
uint64_t first_point_timestamp_ns; | ||
int32_t frame_sync_index; | ||
uint32_t period_ns; | ||
uint32_t n_entries; | ||
uint32_t capacity; | ||
uint16_t num_beams : 4; | ||
uint16_t num_peaks : 2; | ||
uint16_t range_scale : 10; | ||
uint8_t line_index; | ||
uint8_t max_line_index; | ||
uint32_t face_index : 4; | ||
uint32_t n_faces : 4; | ||
uint32_t reserved_2 : 3; | ||
uint32_t sensitivity_mode : 3; | ||
uint32_t frame_parity : 1; | ||
uint32_t reserved_3 : 1; | ||
uint32_t window_measurement : 1; | ||
uint32_t reserved_5 : 1; | ||
uint32_t discard_line : 1; | ||
uint32_t ping_pong : 1; | ||
uint32_t reserved_6 : 12; | ||
FixedPoint<int16_t, 9> mirror_rps; | ||
uint16_t dither_step : 5; | ||
uint16_t max_dither_step : 5; | ||
uint16_t reserved_7 : 6; | ||
uint8_t reserved_8[12]; | ||
}; | ||
|
||
struct PointCloudPoint | ||
{ | ||
FixedPoint<int16_t, 15> azimuth; | ||
FixedPoint<int16_t, 15> elevation; | ||
FixedPoint<uint16_t, 7> range; | ||
FixedPoint<int16_t, 8> velocity; | ||
uint8_t intensity; | ||
uint8_t signal_quality; | ||
uint32_t beam_id : 3; | ||
uint32_t peak_id : 2; | ||
uint32_t line_transition : 1; | ||
uint32_t valid : 1; | ||
uint32_t dynamic : 1; | ||
uint32_t reserved_1 : 1; | ||
uint32_t up_sweep : 1; | ||
uint32_t in_ambiguity_region : 1; | ||
uint32_t reserved_2 : 9; | ||
uint32_t peak_width : 4; | ||
uint32_t is_single_detection : 1; | ||
uint32_t reserved_3 : 7; | ||
}; | ||
|
||
struct PointCloudMessage | ||
{ | ||
PointcloudMsgSubheaderAndMetadata header; | ||
std::vector<PointCloudPoint> points; | ||
}; | ||
|
||
enum class TelemetryDataType : uint8_t { | ||
kUInt8 = 0, | ||
kInt8 = 1, | ||
kUInt16 = 2, | ||
kInt16 = 3, | ||
kUInt32 = 4, | ||
kInt32 = 5, | ||
kUInt64 = 6, | ||
kInt64 = 7, | ||
kFloat = 8, | ||
kDouble = 9, | ||
kChar = 10 | ||
}; | ||
|
||
enum class ReconfigRequestType : uint8_t { | ||
kManifestRequest = 0, | ||
kManifestResponse = 1, | ||
kChangeRequest = 2, | ||
kChangeApproved = 3, | ||
kChangeIgnored = 4, | ||
kInvalid = 5 | ||
}; | ||
|
||
inline std::ostream & operator<<(std::ostream & os, const ReconfigRequestType & arg) | ||
{ | ||
switch (arg) { | ||
case ReconfigRequestType::kManifestRequest: | ||
return os << "manifest request"; | ||
case ReconfigRequestType::kManifestResponse: | ||
return os << "manifest response"; | ||
case ReconfigRequestType::kChangeRequest: | ||
return os << "change request"; | ||
case ReconfigRequestType::kChangeApproved: | ||
return os << "change approved"; | ||
case ReconfigRequestType::kChangeIgnored: | ||
return os << "change ignored"; | ||
default: | ||
return os << "invalid: " + std::to_string(static_cast<int>(arg)); | ||
} | ||
} | ||
|
||
struct HealthCode | ||
{ | ||
explicit HealthCode(uint32_t value) : value_(value) {} | ||
|
||
[[nodiscard]] bool is_error() const { return (value_ & g_error_mask) != 0; } | ||
[[nodiscard]] uint32_t get() const { return value_ & ~g_error_mask; } | ||
|
||
private: | ||
uint32_t value_; | ||
static const uint32_t g_error_mask = 1u << 31u; | ||
}; | ||
|
||
struct ReconfigMessage | ||
{ | ||
ReconfigRequestType type = ReconfigRequestType::kInvalid; | ||
std::optional<json> body; | ||
}; | ||
|
||
#pragma pack(pop) | ||
|
||
} // namespace nebula::drivers::aeva |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// Copyright 2024 TIER IV, Inc. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#pragma once | ||
|
||
#include <pcl/point_types.h> | ||
|
||
namespace nebula::drivers::aeva | ||
{ | ||
|
||
struct EIGEN_ALIGN16 PointXYZVIRCAEDT | ||
{ | ||
float x; | ||
float y; | ||
float z; | ||
float range_rate; | ||
uint8_t intensity; | ||
uint8_t return_type; | ||
uint16_t channel; | ||
float azimuth; | ||
float elevation; | ||
float distance; | ||
uint32_t time_stamp; | ||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW | ||
}; | ||
|
||
} // namespace nebula::drivers::aeva | ||
|
||
POINT_CLOUD_REGISTER_POINT_STRUCT( // NOLINT | ||
nebula::drivers::aeva::PointXYZVIRCAEDT, | ||
(float, x, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yikes is this how pre-commit wanted the line break? :P There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, tried to coax it to do it differently but it's stubborn. |
||
x)(float, y, y)(float, z, z)(float, range_rate, range_rate)(std::uint8_t, intensity, intensity)( | ||
std::uint8_t, return_type, | ||
return_type)(std::uint16_t, channel, channel)(float, azimuth, azimuth)( | ||
float, elevation, elevation)(float, distance, distance)(std::uint32_t, time_stamp, time_stamp)) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: although no performance benefit in this case, a
switch
looks nicer (IMO)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
C++ doesn't allow switch statements for strings 🥲 I agree though