-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add the ZED Wrapper and Object Detector (#3)
* starter files * starter code * finding zed sdk * building zed sdk * y no build * gets paramaters * gets more aprameters * why no callback * variants :))))) * logic error * more params * most init done * no build :( * almost builds * builds :))))) * wat svo? * builds * AHHHHHHHH POINTERS AHHHHHHHHH * STD MOVE FTW * undefined symbols :( * undefined symbols :( * Builds * Runs * Better includes * Works * 62 Hz * begin porting voer obj detect * more errors * learning lib builds * brah * bruhhhh * works * better type safety * got rid of compiler warnings * starter files * starter code * finding zed sdk * building zed sdk * y no build * gets paramaters * gets more aprameters * why no callback * variants :))))) * logic error * more params * most init done * no build :( * almost builds * builds :))))) * wat svo? * builds * AHHHHHHHH POINTERS AHHHHHHHHH * STD MOVE FTW * undefined symbols :( * undefined symbols :( * Builds * Runs * Better includes * Works * 62 Hz * begin porting voer obj detect * more errors * learning lib builds * brah * bruhhhh * works * better type safety * got rid of compiler warnings * Update zed_wrapper.bridge.cpp * Updated CUDA * Updated CUDA * Update zed_wrapper.bridge.cpp * CLANG FORMAT IS CRACCCCCCKKKKKKED bro :)))))))))))) * CLANG FORMAT IS CRACCCCCCKKKKKKED bro :)))))))))))) * CLANG FORMAT IS CRACCCCCCKKKKKKED bro :)))))))))))) * CLANG FORMAT IS CRACCCCCCKKKKKKED bro :)))))))))))) * BLACK * builds * no engine * redundant * Ashwin Suggestions * No more engine * Updating compiler flags * Final Refactoring * od still works * zed default params * od default params * Works with new parameters * Better pathing on zed launch * Better launch file configuration * works
- Loading branch information
Showing
27 changed files
with
1,723 additions
and
3 deletions.
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
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,18 @@ | ||
|
||
# All units are in SI | ||
# =================== | ||
# Time: second, hz | ||
# Angle: radian | ||
# Distance: meter | ||
|
||
/object_detector: | ||
ros__parameters: | ||
camera_frame: "zed_left_camera_frame" | ||
world_frame: "map" | ||
increment_weight: 2 | ||
decrement_weight: 1 | ||
hitcount_threshold: 5 | ||
hitcount_max: 10 | ||
model_name: "Large-Dataset" | ||
model_score_threshold: 0.75 | ||
model_nms_threshold: 0.5 |
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,22 @@ | ||
# All units are in SI | ||
# =================== | ||
# Time: second, hz | ||
# Angle: radian | ||
# Distance: meter | ||
|
||
/zed_wrapper: | ||
ros__parameters: | ||
depth_confidence: 70 | ||
serial_number: -1 | ||
grab_target_fps: 60 | ||
texture_confidence: 100 | ||
image_width: 1280 | ||
image_height: 720 | ||
svo_file: "" | ||
use_depth_stabilization: false | ||
grab_resolution: "HD720" | ||
depth_mode: "PERFORMANCE" | ||
depth_maximum_distance: 12.0 | ||
use_builtin_visual_odom: false | ||
use_pose_smoothing: true | ||
use_area_memory: true |
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 @@ | ||
*.engine |
Git LFS file not shown
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,28 @@ | ||
from pathlib import Path | ||
|
||
from ament_index_python import get_package_share_directory | ||
|
||
from launch import LaunchDescription | ||
from launch.actions import DeclareLaunchArgument | ||
from launch.substitutions import LaunchConfiguration | ||
from launch_ros.actions import Node, ComposableNodeContainer | ||
from launch_ros.descriptions import ComposableNode | ||
from launch.conditions import LaunchConfigurationEquals | ||
|
||
|
||
def generate_launch_description(): | ||
zed_node = Node( | ||
package="mrover", | ||
executable="zed", | ||
name="zed_wrapper", | ||
parameters=[Path(get_package_share_directory("mrover"), "config", "zed.yaml")], | ||
) | ||
|
||
object_detector_node = Node( | ||
package="mrover", | ||
executable="object_detector", | ||
name="object_detector", | ||
parameters=[Path(get_package_share_directory("mrover"), "config", "object_detector.yaml")], | ||
) | ||
|
||
return LaunchDescription([zed_node, object_detector_node]) |
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,104 @@ | ||
#include <vector> | ||
#include <string> | ||
#include <variant> | ||
#include <exception> | ||
#include <rclcpp/rclcpp.hpp> | ||
|
||
// Overloads pattern for visit | ||
template<class... Ts> struct overload : Ts... { using Ts::operator()...; }; | ||
template<class... Ts> overload(Ts...) -> overload<Ts...>; | ||
|
||
|
||
namespace mrover { | ||
class ParameterWrapper { | ||
private: | ||
static inline std::shared_ptr<rclcpp::ParameterCallbackHandle> cbHande; | ||
|
||
public: | ||
rclcpp::ParameterType mType; | ||
|
||
std::string mParamDescriptor; | ||
|
||
std::variant<int*, std::string*, bool*, double*, float*> mData; | ||
|
||
std::variant<int, std::string, bool, double, float> mDefaultValue; | ||
|
||
ParameterWrapper(std::string paramDescriptor, int& variable, int defaultValue = 0) : mType{rclcpp::ParameterType::PARAMETER_INTEGER}, mParamDescriptor{std::move(paramDescriptor)}, mData{&variable}, mDefaultValue{defaultValue}{} | ||
|
||
ParameterWrapper(std::string paramDescriptor, std::string& variable, std::string defaultValue = "") : mType{rclcpp::ParameterType::PARAMETER_STRING}, mParamDescriptor{std::move(paramDescriptor)}, mData{&variable}, mDefaultValue{std::move(defaultValue)}{} | ||
|
||
ParameterWrapper(std::string paramDescriptor, bool& variable, bool defaultValue = false) : mType{rclcpp::ParameterType::PARAMETER_BOOL}, mParamDescriptor{std::move(paramDescriptor)}, mData{&variable}, mDefaultValue{defaultValue}{} | ||
|
||
ParameterWrapper(std::string paramDescriptor, double& variable, double defaultValue = 0.0) : mType{rclcpp::ParameterType::PARAMETER_DOUBLE}, mParamDescriptor{std::move(paramDescriptor)}, mData{&variable}, mDefaultValue{defaultValue}{} | ||
|
||
ParameterWrapper(std::string paramDescriptor, float& variable, float defaultValue = 0.0) : mType{rclcpp::ParameterType::PARAMETER_DOUBLE}, mParamDescriptor{std::move(paramDescriptor)}, mData{&variable}, mDefaultValue{defaultValue}{} | ||
|
||
void visit(rclcpp::Node* node){ | ||
std::visit(overload{ | ||
[&](int* arg){ | ||
try{ | ||
*arg = static_cast<int>(node->get_parameter(mParamDescriptor).as_int()); | ||
}catch(rclcpp::exceptions::ParameterUninitializedException& e){ | ||
try{ | ||
*arg = std::get<int>(mDefaultValue); | ||
}catch (std::bad_variant_access const& ex){ | ||
throw std::runtime_error("Bad Variant Access: Type not int"); | ||
} | ||
} | ||
}, | ||
[&](std::string* arg){ | ||
try{ | ||
*arg = node->get_parameter(mParamDescriptor).as_string(); | ||
}catch(rclcpp::exceptions::ParameterUninitializedException& e){ | ||
try{ | ||
*arg = std::get<std::string>(mDefaultValue); | ||
}catch (std::bad_variant_access const& ex){ | ||
throw std::runtime_error("Bad Variant Access: Type not std::string"); | ||
} | ||
} | ||
}, | ||
[&](bool* arg){ | ||
try{ | ||
*arg = node->get_parameter(mParamDescriptor).as_bool(); | ||
}catch(rclcpp::exceptions::ParameterUninitializedException& e){ | ||
try{ | ||
*arg = std::get<bool>(mDefaultValue); | ||
}catch (std::bad_variant_access const& ex){ | ||
throw std::runtime_error("Bad Variant Access: Type not bool"); | ||
} | ||
} | ||
}, | ||
[&](double* arg){ | ||
try{ | ||
*arg = node->get_parameter(mParamDescriptor).as_double(); | ||
}catch(rclcpp::exceptions::ParameterUninitializedException& e){ | ||
try{ | ||
*arg = std::get<double>(mDefaultValue); | ||
}catch (std::bad_variant_access const& ex){ | ||
throw std::runtime_error("Bad Variant Access: Type not double"); | ||
} | ||
} | ||
}, | ||
[&](float* arg){ | ||
try{ | ||
*arg = static_cast<float>(node->get_parameter(mParamDescriptor).as_double()); | ||
}catch(rclcpp::exceptions::ParameterUninitializedException& e){ | ||
try{ | ||
*arg = std::get<float>(mDefaultValue); | ||
}catch (std::bad_variant_access const& ex){ | ||
throw std::runtime_error("Bad Variant Access: Type not float"); | ||
} | ||
} | ||
} | ||
}, mData); | ||
} | ||
|
||
static inline auto declareParameters(rclcpp::Node* node, std::vector<ParameterWrapper>& params) -> void{ | ||
RCLCPP_INFO(rclcpp::get_logger("param_logger"), "Declaring %zu parameters...", params.size()); | ||
for(auto& param : params){ | ||
node->declare_parameter(param.mParamDescriptor, param.mType); | ||
param.visit(node); | ||
} | ||
} | ||
}; | ||
}; |
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,47 @@ | ||
#include "object_detector.hpp" | ||
|
||
namespace mrover { | ||
|
||
ObjectDetectorBase::ObjectDetectorBase() : rclcpp::Node(NODE_NAME), mLoopProfiler{get_logger()} { | ||
|
||
std::vector<ParameterWrapper> params{ | ||
{"camera_frame", mCameraFrame, "zed_left_camera_frame"}, | ||
{"world_frame", mWorldFrame, "map"}, | ||
{"increment_weight", mObjIncrementWeight, 2}, | ||
{"decrement_weight", mObjDecrementWeight, 1}, | ||
{"hitcount_threshold", mObjHitThreshold, 5}, | ||
{"hitcount_max", mObjMaxHitcount, 10}, | ||
{"model_name", mModelName, "Large-Dataset"}, | ||
{"model_score_threshold", mModelScoreThreshold, 0.75}, | ||
{"model_nms_threshold", mModelNmsThreshold, 0.5} | ||
}; | ||
|
||
ParameterWrapper::declareParameters(this, params); | ||
|
||
std::filesystem::path packagePath = std::filesystem::path{ament_index_cpp::get_package_prefix("mrover")} / ".." / ".." / "src" / "mrover"; | ||
|
||
RCLCPP_INFO_STREAM(get_logger(), "Opening Model " << mModelName); | ||
|
||
RCLCPP_INFO_STREAM(get_logger(), "Found package path " << packagePath); | ||
|
||
mTensorRT = TensortRT{mModelName, packagePath.string()}; | ||
|
||
mDebugImgPub = create_publisher<sensor_msgs::msg::Image>("object_detector/debug_img", 1); | ||
|
||
RCLCPP_INFO_STREAM(get_logger(), std::format("Object detector initialized with model: {} and thresholds: {} and {}", mModelName, mModelScoreThreshold, mModelNmsThreshold)); | ||
} | ||
|
||
StereoObjectDetector::StereoObjectDetector() { | ||
mSensorSub = create_subscription<sensor_msgs::msg::PointCloud2>("/camera/left/points", 1, [this](sensor_msgs::msg::PointCloud2::UniquePtr const& msg) { | ||
StereoObjectDetector::pointCloudCallback(msg); | ||
}); | ||
} | ||
} // namespace mrover | ||
|
||
|
||
auto main(int argc, char** argv) -> int { | ||
rclcpp::init(argc, argv); | ||
rclcpp::spin(std::make_shared<mrover::StereoObjectDetector>()); | ||
rclcpp::shutdown(); | ||
return EXIT_SUCCESS; | ||
} |
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 @@ | ||
#pragma once | ||
|
||
#include "pch.hpp" | ||
|
||
namespace mrover { | ||
|
||
class ObjectDetectorBase : public rclcpp::Node { | ||
|
||
protected: | ||
static constexpr char const* NODE_NAME = "object_detector"; | ||
|
||
std::unique_ptr<tf2_ros::Buffer> mTfBuffer = std::make_unique<tf2_ros::Buffer>(get_clock()); | ||
std::shared_ptr<tf2_ros::TransformBroadcaster> mTfBroadcaster = std::make_shared<tf2_ros::TransformBroadcaster>(this); | ||
std::shared_ptr<tf2_ros::TransformListener> mTfListener = std::make_shared<tf2_ros::TransformListener>(*mTfBuffer); | ||
|
||
std::string mCameraFrame; | ||
std::string mWorldFrame; | ||
|
||
std::string mModelName; | ||
|
||
LoopProfiler mLoopProfiler; | ||
|
||
TensortRT mTensorRT; | ||
|
||
cv::Mat mRgbImage, mImageBlob; | ||
sensor_msgs::msg::Image mDetectionsImageMessage; | ||
|
||
rclcpp::Publisher<sensor_msgs::msg::Image>::SharedPtr mDebugImgPub; | ||
rclcpp::Subscription<sensor_msgs::msg::PointCloud2>::SharedPtr mSensorSub; | ||
|
||
// TODO(quintin): Do not hard code exactly two classes | ||
std::vector<int> mObjectHitCounts{0, 0}; | ||
|
||
int mObjIncrementWeight{}; | ||
int mObjDecrementWeight{}; | ||
int mObjHitThreshold{}; | ||
int mObjMaxHitcount{}; | ||
float mModelScoreThreshold{}; | ||
float mModelNmsThreshold{}; | ||
|
||
auto spiralSearchForValidPoint(sensor_msgs::msg::PointCloud2::UniquePtr const& cloudPtr, | ||
std::size_t u, std::size_t v, | ||
std::size_t width, std::size_t height) const -> std::optional<SE3d>; | ||
|
||
auto updateHitsObject(sensor_msgs::msg::PointCloud2::UniquePtr const& msg, | ||
std::span<Detection const> detections, | ||
cv::Size const& imageSize = {640, 640}) -> void; | ||
|
||
auto publishDetectedObjects(cv::InputArray image) -> void; | ||
|
||
static auto drawDetectionBoxes(cv::InputOutputArray image, std::span<Detection const> detections) -> void; | ||
|
||
public: | ||
explicit ObjectDetectorBase(); | ||
|
||
~ObjectDetectorBase() override = default; | ||
}; | ||
|
||
class StereoObjectDetector final : public ObjectDetectorBase { | ||
public: | ||
explicit StereoObjectDetector(); | ||
|
||
static auto convertPointCloudToRGB(sensor_msgs::msg::PointCloud2::UniquePtr const& msg, cv::Mat const& image) -> void; | ||
|
||
auto pointCloudCallback(sensor_msgs::msg::PointCloud2::UniquePtr const& msg) -> void; | ||
}; | ||
} // namespace mrover |
Oops, something went wrong.