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

Feat/feelers #6

Draft
wants to merge 56 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
a1fe7ca
initial feelers commit
danielbrownmsm Sep 19, 2024
a8fc4b2
c++ and python feeler and feeler_node files
danielbrownmsm Sep 19, 2024
6986147
translate feeler.py's update() function into C++
danielbrownmsm Sep 24, 2024
b0e5434
fix errors to make feelers build
danielbrownmsm Sep 24, 2024
7686b43
Merge branch 'feat/autonav-messages' into feat/feelers
danielbrownmsm Sep 24, 2024
d0a3a78
heavily expand feelerNode and (almost) finish implementing Feeler
danielbrownmsm Sep 26, 2024
8e3a26a
we don't need python versions of the c++ files considering how far al…
danielbrownmsm Sep 26, 2024
9ac57e9
minor bugfixes
danielbrownmsm Sep 26, 2024
75ac69f
Merge branch 'main' into feat/feelers
danielbrownmsm Sep 27, 2024
c7fbb75
feeler node is closer to actually building
danielbrownmsm Sep 27, 2024
568a54b
Merge branch 'feat/autonav-messages' into feat/feelers
danielbrownmsm Sep 27, 2024
12abb85
fix errors
danielbrownmsm Oct 1, 2024
cbaaa32
add some waypoints stuff to feelers node and move the motor publishin…
danielbrownmsm Oct 2, 2024
5b52322
moving manual package into the ws
antonioc76 Oct 4, 2024
a429ac4
add north/south detection, remove python feelers from cmake, and fix …
danielbrownmsm Oct 4, 2024
9259d17
FEELER NODE BUILDS
danielbrownmsm Oct 4, 2024
bb8dab3
Merge branch 'main' into feat/feelers
danielbrownmsm Oct 4, 2024
1725bce
added some logging to feelers for testing purposes
danielbrownmsm Oct 9, 2024
c4c6264
manual24 ported fully, manual 25 robot local controls implemented. Pr…
antonioc76 Oct 9, 2024
cc07956
Merge branch 'main' into feat/feelers
danielbrownmsm Oct 11, 2024
c17971f
manual for swerve done in theory
antonioc76 Oct 11, 2024
ba4fdd3
make feelers work
danielbrownmsm Oct 11, 2024
98e4feb
copypasta all the setup script stuff from last year and change a few …
danielbrownmsm Oct 15, 2024
13646a0
forgot dockerfile for CI
danielbrownmsm Oct 15, 2024
2eb7a2d
fix dockerfile?
danielbrownmsm Oct 15, 2024
e05761c
actually fix the setup script fr trust bro this time
danielbrownmsm Oct 15, 2024
5c4b8e4
pip bad venv bad break all the python packages
danielbrownmsm Oct 15, 2024
2e82362
Merge pull request #8 from SoonerRobotics/setup
danielbrownmsm Oct 15, 2024
cd4c801
Add custom ros configuration messages
dylanzemlin Oct 29, 2024
ca8c4e6
Added nlohmann json
dylanzemlin Oct 29, 2024
90ae833
Finished configuration system
dylanzemlin Oct 30, 2024
7989474
Fixed a typo in the init function
dylanzemlin Oct 30, 2024
f83dd68
Merge pull request #11 from SoonerRobotics/feat/shared_configuration
dylanzemlin Oct 30, 2024
4fc0470
Merge branch 'main' into feat/manual
antonioc76 Oct 31, 2024
6db486f
added odometry to global space control for swerve, added config
antonioc76 Nov 1, 2024
9d2e750
polish
antonioc76 Nov 6, 2024
ad3e018
no longer requesting all configs
antonioc76 Nov 6, 2024
f8042f5
Merge pull request #12 from SoonerRobotics/feat/manual
antonioc76 Nov 6, 2024
9b1153f
copy/paste source for ROS-TCP-Endpoint per install instructions and r…
danielbrownmsm Nov 6, 2024
c454cb3
Merge pull request #17 from SoonerRobotics/feat/ros-unity-integration
antonioc76 Dec 4, 2024
6b58b4f
copy paste last year's vision code to start with
danielbrownmsm Dec 12, 2024
9186b50
remove unecessary code
danielbrownmsm Dec 12, 2024
bc32612
pipeline is working, images are flowing and combining
danielbrownmsm Dec 12, 2024
68c35e5
hsv thresholding works
danielbrownmsm Dec 13, 2024
ff813b6
debug publishing works
danielbrownmsm Dec 13, 2024
14121a1
complete top down view works now, both masked and unfiltered debug
danielbrownmsm Dec 13, 2024
0fcc40e
Merge branch 'feat/feelers' into feat/daniel-vision
danielbrownmsm Dec 13, 2024
d710e1d
update feeler node to ue latest configuration
danielbrownmsm Dec 13, 2024
7dbf344
feelers kind of works, minus the debug image, but that's fine?
danielbrownmsm Dec 13, 2024
2d25266
debugging feelers, now we're writing three videos at once
danielbrownmsm Dec 14, 2024
216793e
try to remove some potential C++ pointer magic BS (it didn't work)
danielbrownmsm Dec 14, 2024
673e93a
made a "fake" vision node that just reads the images from the videos …
danielbrownmsm Dec 14, 2024
fc41d89
fixed multiple silly little bugs with feelers, drawing and stuff is m…
danielbrownmsm Dec 14, 2024
58e8c8f
rewrite feeler_node to not do everything inside publishMotorOutput().
danielbrownmsm Dec 15, 2024
b5c95cf
FEELERS WORKS! it was a stupid c++ loop pointer thing after all.
danielbrownmsm Dec 15, 2024
e4b5eb1
testing flattening
danielbrownmsm Dec 24, 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
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,9 @@ Zone.Identifier

deps/songs
autonav_ws/src/scr/include/scr/websocketpp/**/*:Zone.Identifier

# python
**/venv

# temporary feeler node testing
autonav_ws/data
11 changes: 6 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
FROM osrf/ros:jazzy-desktop-full

RUN mkdir -p /autonav/autonav_ws/src
# RUN mkdir -p /autonav/setup
RUN mkdir -p /autonav/setup
# RUN mkdir -p /autonav/deps

COPY autonav_ws/src /autonav/autonav_ws/src
# COPY setup /autonav/setup
# COPY vectorsecrets.txt /autonav/setup/vectorsecrets.txt
COPY setup /autonav/setup
COPY vectorsecrets.txt /autonav/setup/vectorsecrets.txt
# COPY deps /autonav/deps

# WORKDIR /autonav/setup
# RUN /bin/bash -c "./setup.sh"
WORKDIR /autonav/setup
RUN /bin/bash -c "sudo chmod +x ./setup.sh"
RUN /bin/bash -c "./setup.sh"

WORKDIR /autonav/autonav_ws
RUN /bin/bash -c "source /opt/ros/jazzy/setup.bash; colcon build"
30 changes: 30 additions & 0 deletions autonav_ws/src/autonav_example_cpp/src/example.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,36 @@
#include "autonav_shared/node.hpp"


struct ExampleCPPConfig
{
float alpha;
std::string beta;
int gamma;
bool delta;
std::vector<float> epsilon;
std::vector<std::string> zeta;
std::map<std::string, std::string> eta;
int rid;

NLOHMANN_DEFINE_TYPE_INTRUSIVE(ExampleCPPConfig, alpha, beta, gamma, delta, epsilon, zeta)
};

class ExampleCPP : public AutoNav::Node
{
public:
ExampleCPP() : AutoNav::Node("example_cpp")
{
auto config = ExampleCPPConfig();
config.alpha = 0.5;
config.beta = "Hello";
config.gamma = 42;
config.delta = true;
config.epsilon = {0.1, 0.2, 0.3};
config.zeta = {"A", "B", "C"};
config.eta = {{"A", "1"}, {"B", "2"}, {"C", "3"}};
config.rid = 1;
write_config(config);

log("Hello from ExampleCPP", AutoNav::Logging::DEBUG);
log("Hello from ExampleCPP", AutoNav::Logging::INFO);
log("Hello from ExampleCPP", AutoNav::Logging::WARN);
Expand All @@ -20,6 +46,10 @@ class ExampleCPP : public AutoNav::Node

perf_start("ExampleCPP::init");
perf_stop("ExampleCPP::init", true);

request_all_configs();

log("Beta (CONFIG): " + config["beta"].get<std::string>(), AutoNav::Logging::DEBUG);
}
};

Expand Down
22 changes: 19 additions & 3 deletions autonav_ws/src/autonav_example_py/src/example.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,24 @@
from autonav_shared.node import Node
from autonav_shared.types import LogLevel, DeviceState, SystemState
import rclpy
import time


class Example(Node):
class ExamplePyConfig:
def __init__(self):
self.alpha = 0.5
self.beta = "Hello"
self.gamma = 42
self.delta = True
self.epsilon = [0.1, 0.2, 0.3]
self.zeta = ["A", "B", "C"]
self.eta = {"A": 1, "A": 2, "A": 3}
self.rid = 2


class ExamplePy(Node):
def __init__(self):
super().__init__("autonav_example_py")
self.write_config(ExamplePyConfig())

self.log("Hello from ExamplePy", LogLevel.DEBUG)
self.log("Hello from ExamplePy", LogLevel.INFO)
Expand All @@ -22,10 +34,14 @@ def init(self):

self.perf_start("example")
self.perf_stop("example", True)

self.request_all_configs()

self.log(f"Beta (CONFIG): {self.config.beta}", LogLevel.DEBUG)

def main():
rclpy.init()
example = Example()
example = ExamplePy()
rclpy.spin(example)
rclpy.shutdown()

Expand Down
33 changes: 33 additions & 0 deletions autonav_ws/src/autonav_feelers/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
cmake_minimum_required(VERSION 3.8)
project(autonav_feelers)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(rclpy REQUIRED)
find_package(rosidl_default_generators REQUIRED)
find_package(autonav_msgs REQUIRED)
find_package(autonav_shared REQUIRED)
find_package(cv_bridge REQUIRED)
find_package(image_transport REQUIRED)
find_package(OpenCV REQUIRED)

# Install Python programs
install(PROGRAMS
src/fake_vision_node.py
DESTINATION lib/${PROJECT_NAME}
)

# C++
add_executable(feeler_node src/feeler_node.cpp)
ament_target_dependencies(feeler_node rclcpp autonav_msgs cv_bridge image_transport autonav_shared OpenCV)

install(TARGETS
feeler_node
DESTINATION lib/${PROJECT_NAME}
)
ament_package()
26 changes: 26 additions & 0 deletions autonav_ws/src/autonav_feelers/package.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>autonav_feelers</name>
<version>2025.0.1</version>
<description>Package to take all of the obstacle and GPS data and output commands to move the robot to avoid obstacles and hit GPS waypoints using SCR FEELERS (C) TM.</description>
<maintainer email="[email protected]">Daniel Brown</maintainer>
<license>MIT</license>

<buildtool_depend>ament_cmake</buildtool_depend>

<depend>rclcpp</depend>
<depend>rclpy</depend>
<depend>autonav_msgs</depend>
<depend>autonav_shared</depend>
<depend>cv_bridge</depend>
<depend>image_transport</depend>

<build_depend>rosidl_default_generators</build_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<member_of_group>rosidl_interface_packages</member_of_group>

<export>
<build_type>ament_cmake</build_type>
</export>
</package>
98 changes: 98 additions & 0 deletions autonav_ws/src/autonav_feelers/src/fake_vision_node.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#!/usr/bin/env python3

import rclpy
import cv2, time
import numpy as np

import rclpy.qos
from sensor_msgs.msg import CompressedImage
from cv_bridge import CvBridge

from autonav_shared.node import Node
from autonav_shared.types import LogLevel, DeviceState, SystemState



bridge = CvBridge()

IMAGE_WIDTH = 640
IMAGE_HEIGHT = 480

#TODO use like max() or min() in case we play with the dimensions
# or like, combine them better so the total combined image is only 640x480 or something
COMBINED_IMAGE_WIDTH = IMAGE_HEIGHT*2 # left and right cameras are 480 pixels tall but turned on their sides so it's 480 pixels wide and then next to each other, and the top/bottom cameras are only 640 wide so this is fine
COMBINED_IMAGE_HEIGHT = IMAGE_HEIGHT*2 + IMAGE_WIDTH # top and bottom cameras are 480 pixels tall, plus the left/right cameras turned on their side which adds 640 pixels


class ImageCombiner(Node):
def __init__(self):
super().__init__("autonav_vision_combiner")

def init(self):
self.set_device_state(DeviceState.WARMING)

# subscribers
self.feeler_debug_image_subscriber = self.create_subscription(CompressedImage, "/autonav/feelers/debug", self.on_feelers_received, 1) # TEMP TODO FIXME
self.feeler_debug_image = None

self.feeler_video_writer = cv2.VideoWriter("./data/debug_feeler_test.mp4", cv2.VideoWriter.fourcc(*"mp4v"), 15.0, (COMBINED_IMAGE_WIDTH, COMBINED_IMAGE_HEIGHT)) #TODO

# publishers
self.combined_image_publisher = self.create_publisher(CompressedImage, "/autonav/vision/combined/filtered", 1)
self.video_reader = cv2.VideoCapture("./data/combined.mp4")

self.combined_debug_image_publisher = self.create_publisher(CompressedImage, "/autonav/vision/combined/debug", 1)
self.debug_video_reader = cv2.VideoCapture("./data/debug_combined.mp4")

#TODO make timers
self.publish_timer = self.create_timer(.1, self.publish_combined_images)

self.frame = 0
self.writtenFrames = 0

self.log("starting image combiner...", LogLevel.WARN)
self.set_device_state(DeviceState.READY)


# just write that straight to output
def on_feelers_received(self, msg):
self.writtenFrames += 1
print(f"Receiving frame: {self.writtenFrames}")
self.feeler_video_writer.write(bridge.compressed_imgmsg_to_cv2(msg))

def publish_combined_images(self):
print(f"Publishing frame: {self.frame}")

ret1, combined_image = self.video_reader.read()
ret2, debug_image = self.debug_video_reader.read()

# if not ret1 or not ret2 or self.frame > 3:
if not ret1 or not ret2:
self.log("OUT OF IMAGES", LogLevel.FATAL)

self.video_reader.release()
self.debug_video_reader.release()
self.feeler_video_writer.release()

raise SystemExit

self.frame += 1

self.combined_image_publisher.publish(bridge.cv2_to_compressed_imgmsg(combined_image))
self.combined_debug_image_publisher.publish(bridge.cv2_to_compressed_imgmsg(debug_image)) #FIXME there's got to be a better way to handle this feelers-side, but for now just send this first so that feelers can draw on it before it gets overwritten


def main():
rclpy.init()

node = ImageCombiner()
rclpy.spin(node)

node.feeler_video_writer.release()
cv2.destroyAllWindows() # just in case

rclpy.shutdown()


if __name__ == "__main__":
main()
Loading
Loading