Skip to content
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

refactor(hesai)!: combine Hesai ROS wrappers into a single node #127

Merged
merged 57 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
7fae72d
fix(hesai_decoder): print config instead of config address
mojomex Mar 21, 2024
694f28d
refactor(nebula_ros): combine Hesai wrapper nodes into one
mojomex Mar 21, 2024
c10c6ab
refactor: remove pandarScan pub/sub, decode one packet at a time
mojomex Mar 21, 2024
4f014c3
reword later
mojomex Mar 26, 2024
be47714
temporary progress
mojomex Mar 26, 2024
17c8163
fix(hesai_ros_wrapper): remove changes wrongly merged during rebase
mojomex Apr 4, 2024
c7dcab9
fix(hesai_ros_wrapper): increase packet buffering to stop internal pa…
mojomex Apr 4, 2024
991100d
feat(nebula_common): add instrumentation tools
mojomex Apr 4, 2024
cbaccee
feat(hesai_ros_wrapper): instrument code on critical path
mojomex Apr 4, 2024
5db3474
disable instrumentation
mojomex Apr 5, 2024
a723c29
feat(hesai): move received buffer into ros message instead of copy
mojomex Apr 5, 2024
a7dc57b
feat(hesai_ros_wrapper: add thread-safe queue between udp receiver an…
mojomex Apr 5, 2024
d297b15
feat(nebula_common): more instrumentation tools
mojomex Apr 5, 2024
185d584
fix: update link to transport_drivers fork
mojomex Apr 5, 2024
79de4b6
update GitHub PR view
mojomex Apr 8, 2024
5d64e9b
refactor(mt_queue): make variables more readable
mojomex Apr 8, 2024
5571d84
perf(hesai_ros_wrapper): update queue capacity to alleviate packet dr…
mojomex Apr 8, 2024
3e2b120
chore(hesai_ros_wrapper): remove unused pub/sub
mojomex Apr 8, 2024
8b59a58
refactor(hesai_ros_wrapper): clean up control flow, member variables
mojomex Apr 8, 2024
2cebae9
fix(hesai_hw_interface): add error handling
mojomex Mar 28, 2024
d039f12
fix(hesai_hw_monitor_ros_wrapper): fixed wrong range given for S/N copy
mojomex Apr 8, 2024
5a5a6a9
fix(hesai): print uint8, uint16 as numbers
mojomex Apr 8, 2024
5a11cf9
feat(hesai_ros_wrapper): publish/subscribe to legacy pandar_packets o…
mojomex Apr 9, 2024
dc50d12
change launch file back to single-threaded container
mojomex Apr 9, 2024
9aaedbc
attempt to make queue contention less bad
mojomex Apr 10, 2024
a0d24b9
chore(hesai_ros_wrapper): reduce logging output
mojomex Apr 11, 2024
dab6795
feat(hesai_ros_wrapper): print warning when connected to HW and recei…
mojomex Apr 11, 2024
d26473c
feat(nebula_launch.py): throw error when trying to launch Hesai senso…
mojomex Apr 12, 2024
91359d9
refactor(nebula_ros): split single wrapper file into 3 sub-wrappers
mojomex Apr 18, 2024
9145a6d
chore: update cspell ignore
mojomex Apr 16, 2024
de21908
chore(velodyne_calibration_decoder): fix spelling
mojomex Apr 18, 2024
21cdffc
chore(nebula_common): remove debug code
mojomex Apr 18, 2024
5dddb17
chore(velodyne_calibration_decoder): fix spelling
mojomex Apr 18, 2024
d8ab51a
fix(hesai_decoder): initialize last_phase to prevent empty pointclou…
mojomex Apr 18, 2024
efa730a
fix(nebula_tests): make Hesai tests compile again
mojomex Apr 18, 2024
784db44
fix(nebula_examples): make Hesai examples compile again
mojomex Apr 18, 2024
01f5839
chore(velodyne_calibration_decoder): fix spelling once and for all
mojomex Apr 18, 2024
ae28a71
fix(nebula_examples): fix test failure (remove ament_lint_common)
mojomex Apr 18, 2024
f2494ff
fix(hesai_hw_interface): add missing check for PTC error, make error …
mojomex Apr 22, 2024
36931bc
refactor(hesai): re-introduce parameter update mechanism
mojomex Apr 23, 2024
7c91ce7
feat(hesai_ros): add watchdog timer for pointcloud output
mojomex Apr 23, 2024
76fbd38
fix(hesai): change to possibly more accurate high_resolution_clock
mojomex Apr 25, 2024
2e9ca91
fix(hesai): fix crash on QT128
mojomex Apr 25, 2024
5c527fa
refactor(hesai_hw_interface): refactor repeated error handling code
mojomex Apr 30, 2024
b9f446a
fix(hesai_launch_all_hw.xml): set valid RPM when AT128 is selected
mojomex Apr 30, 2024
10487e6
refactor(hesai_decoder): remove redundant arguments for correction/ca…
mojomex Apr 30, 2024
9fadf8a
refactor(nebula_ros): move mt_queue to common
mojomex May 11, 2024
bf581c8
chore(nebula_examples): change output rosbag format to NebulaPackets,…
mojomex May 22, 2024
c32de1e
chore(hesai/decoder_wrapper): clarify watchdog behavior in decoder
mojomex May 22, 2024
906904f
chore(hesai/hw_monitor_wrapper): fix typo in diagnostics name
mojomex May 22, 2024
539d5af
chore(hesai_ros_decoder_test): fix unclear naming in console output
mojomex May 22, 2024
d8d52c6
chore: run pre-commit and implement suggested fixes (not including co…
mojomex May 22, 2024
dc1a59c
fix(expected.hpp): revert explicit constructors
mojomex May 22, 2024
5f36804
chore: remove erroneously added node_modules folder
mojomex May 22, 2024
18f193a
chore(gitconfig): exclude node_modules from git
mojomex May 22, 2024
b2552dc
fix(hesai/decoder_wrapper): store downloaded sensor calibration witho…
mojomex May 22, 2024
11bdda1
chore(nebula_examples,nebula_tests): remove more dangling comments an…
mojomex May 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"DHAVE",
"Difop",
"extrinsics",
"fout",
"gprmc",
"gptp",
"Helios",
Expand All @@ -32,6 +33,8 @@
"PANDARQT",
"PANDARXT",
"Pdelay",
"Piyush",
"piyushk",
"QT",
"rclcpp",
"schedutil",
Expand All @@ -46,8 +49,6 @@
"Vdat",
"XT",
"XTM",
"piyushk",
"Piyush",
"fout"
"yukkysaito"
mojomex marked this conversation as resolved.
Show resolved Hide resolved
]
}
}
48 changes: 26 additions & 22 deletions nebula_common/include/nebula_common/hesai/hesai_common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
#include <cmath>
#include <fstream>
#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <vector>
namespace nebula
{
namespace drivers
Expand Down Expand Up @@ -47,7 +50,8 @@ struct HesaiCalibrationConfigurationBase : public CalibrationConfigurationBase
{
virtual nebula::Status LoadFromBytes(const std::vector<uint8_t> & buf) = 0;
virtual nebula::Status LoadFromFile(const std::string & calibration_file) = 0;
virtual nebula::Status SaveToFileFromBytes(const std::string & calibration_file, const std::vector<uint8_t> & buf) = 0;
virtual nebula::Status SaveToFileFromBytes(
const std::string & calibration_file, const std::vector<uint8_t> & buf) = 0;
};

/// @brief struct for Hesai calibration configuration
Expand All @@ -63,12 +67,13 @@ struct HesaiCalibrationConfiguration : public HesaiCalibrationConfigurationBase
return Status::INVALID_CALIBRATION_FILE;
}
std::ostringstream ss;
ss << ifs.rdbuf(); // reading data
ss << ifs.rdbuf(); // reading data
ifs.close();
return LoadFromString(ss.str());
}

nebula::Status LoadFromBytes(const std::vector<uint8_t> & buf) {
nebula::Status LoadFromBytes(const std::vector<uint8_t> & buf)
{
std::string calibration_string = std::string(buf.begin(), buf.end());
return LoadFromString(calibration_string);
}
Expand All @@ -82,14 +87,12 @@ struct HesaiCalibrationConfiguration : public HesaiCalibrationConfigurationBase
ss << calibration_content;
std::string line;
constexpr size_t expected_cols = 3;
while(std::getline(ss, line)) {
while (std::getline(ss, line)) {
boost::char_separator<char> sep(",");
boost::tokenizer<boost::char_separator<char>> tok(line, sep);

std::vector<std::string> actual_tokens(tok.begin(), tok.end());
if (actual_tokens.size() < expected_cols
|| actual_tokens.size() > expected_cols
) {
if (actual_tokens.size() < expected_cols || actual_tokens.size() > expected_cols) {
std::cerr << "Ignoring line with unexpected data:" << line << std::endl;
continue;
}
Expand All @@ -100,10 +103,9 @@ struct HesaiCalibrationConfiguration : public HesaiCalibrationConfigurationBase
float azimuth = std::stof(actual_tokens[2]);
elev_angle_map[laser_id - 1] = elevation;
azimuth_offset_map[laser_id - 1] = azimuth;
} catch (const std::invalid_argument& ia) {
} catch (const std::invalid_argument & ia) {
continue;
}

}
return Status::OK;
}
Expand All @@ -129,7 +131,9 @@ struct HesaiCalibrationConfiguration : public HesaiCalibrationConfigurationBase
return Status::OK;
}

nebula::Status SaveToFileFromBytes(const std::string & calibration_file, const std::vector<uint8_t> & buf) override {
nebula::Status SaveToFileFromBytes(
const std::string & calibration_file, const std::vector<uint8_t> & buf) override
{
std::string calibration_string = std::string(buf.begin(), buf.end());
return SaveFileFromString(calibration_file, calibration_string);
}
Expand All @@ -138,7 +142,8 @@ struct HesaiCalibrationConfiguration : public HesaiCalibrationConfigurationBase
/// @param calibration_file path
/// @param calibration_string calibration string
/// @return Resulting status
inline nebula::Status SaveFileFromString(const std::string & calibration_file, const std::string & calibration_string)
inline nebula::Status SaveFileFromString(
const std::string & calibration_file, const std::string & calibration_string)
{
std::ofstream ofs(calibration_file);
if (!ofs) {
Expand Down Expand Up @@ -176,9 +181,8 @@ struct HesaiCorrection : public HesaiCalibrationConfigurationBase
inline nebula::Status LoadFromBytes(const std::vector<uint8_t> & buf) override
{
size_t index;
for (index = 0; index < buf.size()-1; index++) {
if(buf[index]==0xee && buf[index+1]==0xff)
break;
for (index = 0; index < buf.size() - 1; index++) {
if (buf[index] == 0xee && buf[index + 1] == 0xff) break;
}
delimiter = (buf[index] & 0xff) << 8 | ((buf[index + 1] & 0xff));
versionMajor = buf[index + 2] & 0xff;
Expand Down Expand Up @@ -285,7 +289,7 @@ struct HesaiCorrection : public HesaiCalibrationConfigurationBase
// int cnt = 0;
while (!ifs.eof()) {
unsigned char c;
ifs.read((char *)&c, sizeof(unsigned char));
ifs.read(reinterpret_cast<char *>(&c), sizeof(unsigned char));
buf.emplace_back(c);
}
LoadFromBytes(buf);
Expand All @@ -298,7 +302,8 @@ struct HesaiCorrection : public HesaiCalibrationConfigurationBase
/// @param correction_file path
/// @param buf correction binary
/// @return Resulting status
inline nebula::Status SaveToFileFromBytes(const std::string & correction_file, const std::vector<uint8_t> & buf) override
inline nebula::Status SaveToFileFromBytes(
const std::string & correction_file, const std::vector<uint8_t> & buf) override
{
std::cerr << "Saving in:" << correction_file << "\n";
std::ofstream ofs(correction_file, std::ios::trunc | std::ios::binary);
Expand All @@ -308,21 +313,20 @@ struct HesaiCorrection : public HesaiCalibrationConfigurationBase
}
std::cerr << "Writing start...." << buf.size() << "\n";
bool sop_received = false;
for (const auto &byte : buf) {
for (const auto & byte : buf) {
if (!sop_received) {
if (byte == 0xEE) {
std::cerr << "SOP received....\n";
sop_received = true;
}
}
if(sop_received) {
if (sop_received) {
ofs << byte;
}
}
std::cerr << "Closing file\n";
ofs.close();
if(sop_received)
return Status::OK;
if (sop_received) return Status::OK;
return Status::INVALID_CALIBRATION_FILE;
}

Expand Down Expand Up @@ -452,8 +456,8 @@ inline int IntFromReturnModeHesai(const ReturnMode return_mode, const SensorMode
case SensorModel::HESAI_PANDARQT128:
if (return_mode == ReturnMode::LAST) return 0;
if (return_mode == ReturnMode::STRONGEST) return 1;
if (return_mode == ReturnMode::DUAL_LAST_STRONGEST
|| return_mode == ReturnMode::DUAL) return 2;
if (return_mode == ReturnMode::DUAL_LAST_STRONGEST || return_mode == ReturnMode::DUAL)
return 2;
if (return_mode == ReturnMode::FIRST) return 3;
if (return_mode == ReturnMode::DUAL_LAST_FIRST) return 4;
if (return_mode == ReturnMode::DUAL_FIRST_STRONGEST) return 5;
Expand Down
37 changes: 15 additions & 22 deletions nebula_common/include/nebula_common/nebula_common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
#define NEBULA_COMMON_H

#include <nebula_common/point_types.hpp>

#include <boost/tokenizer.hpp>

#include <algorithm>
#include <map>
#include <ostream>
#include <string>
Expand Down Expand Up @@ -342,24 +345,11 @@ enum class datatype {
FLOAT64 = 8
};

enum class PtpProfile {
IEEE_1588v2 = 0,
IEEE_802_1AS,
IEEE_802_1AS_AUTO,
UNKNOWN_PROFILE
};
enum class PtpProfile { IEEE_1588v2 = 0, IEEE_802_1AS, IEEE_802_1AS_AUTO, UNKNOWN_PROFILE };

enum class PtpTransportType {
UDP_IP = 0,
L2,
UNKNOWN_TRANSPORT
};
enum class PtpTransportType { UDP_IP = 0, L2, UNKNOWN_TRANSPORT };

enum class PtpSwitchType {
NON_TSN = 0,
TSN,
UNKNOWN_SWITCH
};
enum class PtpSwitchType { NON_TSN = 0, TSN, UNKNOWN_SWITCH };

/// @brief not used?
struct PointField
Expand Down Expand Up @@ -618,8 +608,9 @@ inline PtpProfile PtpProfileFromString(const std::string & ptp_profile)
{
// Hesai
auto tmp_str = ptp_profile;
std::transform(tmp_str.begin(), tmp_str.end(), tmp_str.begin(),
[](unsigned char c){ return std::tolower(c); });
std::transform(tmp_str.begin(), tmp_str.end(), tmp_str.begin(), [](unsigned char c) {
return std::tolower(c);
});
if (tmp_str == "1588v2") return PtpProfile::IEEE_1588v2;
if (tmp_str == "802.1as") return PtpProfile::IEEE_802_1AS;
if (tmp_str == "automotive") return PtpProfile::IEEE_802_1AS_AUTO;
Expand Down Expand Up @@ -657,8 +648,9 @@ inline PtpTransportType PtpTransportTypeFromString(const std::string & transport
{
// Hesai
auto tmp_str = transport_type;
std::transform(tmp_str.begin(), tmp_str.end(), tmp_str.begin(),
[](unsigned char c){ return std::tolower(c); });
std::transform(tmp_str.begin(), tmp_str.end(), tmp_str.begin(), [](unsigned char c) {
return std::tolower(c);
});
if (tmp_str == "udp") return PtpTransportType::UDP_IP;
if (tmp_str == "l2") return PtpTransportType::L2;

Expand Down Expand Up @@ -692,8 +684,9 @@ inline PtpSwitchType PtpSwitchTypeFromString(const std::string & switch_type)
{
// Hesai
auto tmp_str = switch_type;
std::transform(tmp_str.begin(), tmp_str.end(), tmp_str.begin(),
[](unsigned char c){ return std::tolower(c); });
std::transform(tmp_str.begin(), tmp_str.end(), tmp_str.begin(), [](unsigned char c) {
return std::tolower(c);
});
if (tmp_str == "tsn") return PtpSwitchType::TSN;
if (tmp_str == "non_tsn") return PtpSwitchType::NON_TSN;

Expand Down
47 changes: 26 additions & 21 deletions nebula_common/include/nebula_common/util/expected.hpp
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
#pragma once

#include <variant>
#include <string>
#include <exception>
#include <string>
#include <variant>

namespace nebula
{
namespace util
{

struct bad_expected_access : public std::exception {
bad_expected_access(const std::string & msg) : std::exception(), msg_(msg) {}
struct bad_expected_access : public std::exception
{
explicit bad_expected_access(const std::string & msg) : std::exception(), msg_(msg) {}

const char* what() const noexcept override {
return msg_.c_str();
}
const char * what() const noexcept override { return msg_.c_str(); }

private:
const std::string msg_;
const std::string msg_;
};

/// @brief A poor man's backport of C++23's std::expected.
Expand All @@ -39,14 +38,16 @@ struct expected

/// @brief Retrieve the value, or throw `bad_expected_access` if an error is contained.
/// @return The value of type `T`
T value() {
T value()
{
if (!has_value()) {
throw bad_expected_access("value() called but containing error");
}
return std::get<T>(value_);
return std::get<T>(value_);
}

/// @brief Return the contained value, or, if an error is contained, return the given `default_` instead.
/// @brief Return the contained value, or, if an error is contained, return the given `default_`
/// instead.
/// @return The contained value, if any, else `default_`
T value_or(const T & default_)
{
Expand All @@ -57,34 +58,38 @@ struct expected
/// @brief If the instance has a value, return the value, else throw std::runtime_error(error_msg)
/// @param error_msg The message to be included in the thrown exception
/// @return The value
T value_or_throw(const std::string & error_msg) {
T value_or_throw(const std::string & error_msg)
{
if (has_value()) return value();
throw std::runtime_error(error_msg);
}

/// @brief Retrieve the error, or throw `bad_expected_access` if a value is contained.
/// @return The error of type `E`
E error() {
E error()
{
if (has_value()) {
throw bad_expected_access("error() called but containing value");
}
return std::get<E>(value_);
return std::get<E>(value_);
}

/// @brief Return the contained error, or, if a value is contained, return the given `default_` instead.
/// @brief Return the contained error, or, if a value is contained, return the given `default_`
/// instead.
/// @return The contained error, if any, else `default_`
E error_or(const E & default_) {
E error_or(const E & default_)
{
if (!has_value()) return error();
return default_;
}
return default_;
}

expected(const T & value) { value_ = value; }
explicit expected(const T & value) { value_ = value; }

expected(const E & error) { value_ = error; }
explicit expected(const E & error) { value_ = error; }

private:
std::variant<T, E> value_;
};

} // namespace util
} // namespace nebula
} // namespace nebula
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@ class AngleCorrector
/// @param sync_azimuth The azimuth set in the sensor configuration, for which the
/// timestamp is aligned to the full second
/// @return true if the current azimuth is in a different scan than the last one, false otherwise
virtual bool hasScanned(uint32_t current_azimuth, uint32_t last_azimuth, uint32_t sync_azimuth) = 0;
virtual bool hasScanned(
uint32_t current_azimuth, uint32_t last_azimuth, uint32_t sync_azimuth) = 0;
};

} // namespace drivers
} // namespace nebula
} // namespace nebula
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "nebula_decoders/nebula_decoders_hesai/decoders/angle_corrector.hpp"

#include <cstdint>
#include <memory>

namespace nebula
{
Expand Down Expand Up @@ -79,10 +80,10 @@ class AngleCorrectorCalibrationBased : public AngleCorrector<HesaiCalibrationCon
(MAX_AZIMUTH_LEN + current_azimuth - sync_azimuth) % MAX_AZIMUTH_LEN;
uint32_t last_diff_from_sync =
(MAX_AZIMUTH_LEN + last_azimuth - sync_azimuth) % MAX_AZIMUTH_LEN;

return current_diff_from_sync < last_diff_from_sync;
}
};

} // namespace drivers
} // namespace nebula
} // namespace nebula
Loading