Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
80720ad
creating can package: debugging docker up
Miekale Mar 12, 2025
fa96f7e
interfacing docker workind
Miekale Mar 12, 2025
627b418
updating arch (#5)
Miekale Apr 18, 2025
12ff3d9
adding doc comment
Miekale Apr 20, 2025
1057754
Miekale embedded structure (#6)
Miekale Apr 20, 2025
43c5b69
updating to new structure
Miekale Apr 27, 2025
6509a52
moving to autonomy
Miekale Apr 27, 2025
6e3eb0d
adding changes
Miekale May 8, 2025
a0eff26
Mounting CANable onto /dev/canable port
gavintranquilino May 21, 2025
04a2de4
Convert CAN package to C++
gavintranquilino May 23, 2025
5176ec0
Add CAN package README.md template
gavintranquilino May 23, 2025
a4bcd12
Added TODOs
gavintranquilino May 26, 2025
7ff6029
Successfully run slcand to initialize can0 as a can device with maste…
gavintranquilino May 27, 2025
92469ed
Remove unecessary params
gavintranquilino May 27, 2025
4da0611
Added TODO comments on the empty functions
gavintranquilino May 27, 2025
fcc36c5
Add README.md
gavintranquilino May 27, 2025
3171dcd
Add setup script comment
gavintranquilino May 27, 2025
f892ae7
Fix README.md Typo
gavintranquilino Jun 2, 2025
4c77a44
Add a test_controller node that can be run in the container to publis…
gavintranquilino Jun 2, 2025
fcdfa2b
Create subscriber for any list of topics in params.yaml
gavintranquilino Jun 2, 2025
7e735db
Updated the README.md for how to enable/disable test publisher nodes
gavintranquilino Jun 2, 2025
a686316
removing debug statements from the test_controller
gavintranquilino Jun 2, 2025
5aac94c
Remove CAN bus publishing from Can Node
gavintranquilino Jun 2, 2025
8cf4207
simplified CAN core and node
gavintranquilino Jun 3, 2025
db538a2
Create High Level CAN Message struct
gavintranquilino Jun 4, 2025
5e351bd
Send ROS2 topics over CAN bus with SocketCAN successfully
gavintranquilino Jun 4, 2025
b76914c
Review and change some comments
gavintranquilino Jun 5, 2025
35c3d60
Cleaning up debug logs for sending messages. Only send logs of sendin…
gavintranquilino Jun 6, 2025
f58fc7e
Message listener
gavintranquilino Jun 6, 2025
bbdb16b
Package level documenation for common_msgs
gavintranquilino Jun 11, 2025
e8e5495
Update each message description
gavintranquilino Jun 11, 2025
0b642d6
Merge branch 'main' of https://github.com/WATonomous/humanoid into gt…
gavintranquilino Jun 11, 2025
4bc0bc0
Merge branch 'gtranqui-main' of https://github.com/WATonomous/humanoi…
gavintranquilino Jun 11, 2025
459c025
adding support for topic specific handlers
Miekale Jun 21, 2025
50c6ddf
adding dummy topics
Miekale Jun 21, 2025
1e0e809
adding dummy topics
Miekale Jun 21, 2025
64e16ba
commenting out info
Miekale Jun 21, 2025
07769f7
adding mit motors files
Miekale Jun 21, 2025
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.env
__pycache__
.vscode/
cursor/

watod-config.local.sh
76 changes: 76 additions & 0 deletions autonomy/interfacing/aggregator/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
cmake_minimum_required(VERSION 3.10)
project(aggregator)

# Set compiler to use C++ 17 standard
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 17)
endif()

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

# Search for dependencies required for building this package
find_package(ament_cmake REQUIRED) # ROS2 build tool
find_package(rclcpp REQUIRED) # ROS2 C++ package
find_package(sample_msgs REQUIRED) # Custom package containing ROS2 messages

# Compiles source files into a library
# A library is not executed, instead other executables can link
# against it to access defined methods and classes.
# We build a library so that the methods defined can be used by
# both the unit test and ROS2 node executables.
add_library(aggregator_lib
src/aggregator_core.cpp)
# Indicate to compiler where to search for header files
target_include_directories(aggregator_lib
PUBLIC include)
# Add ROS2 dependencies required by package
ament_target_dependencies(aggregator_lib rclcpp sample_msgs)

# By default tests are built. This can be overridden by modifying the
# colcon build command to include the -DBUILD_TESTING=OFF flag.
option(BUILD_TESTING "Build tests" ON)
if(BUILD_TESTING)
# Search for dependencies required for building tests + linting
find_package(ament_cmake_gtest REQUIRED)
find_package(ament_lint_auto REQUIRED)
find_package(ament_lint_common REQUIRED)

# Remove the default C++ and copyright linter
list(APPEND AMENT_LINT_AUTO_EXCLUDE
ament_cmake_cpplint
ament_cmake_copyright)

# Reinstall cpplint ignoring copyright errors
ament_cpplint(FILTERS "-legal/copyright")

ament_lint_auto_find_test_dependencies()

# Create test executable from source files
ament_add_gtest(aggregator_test test/aggregator_test.cpp)
# Link to the previously built library to access Aggregator classes and methods
target_link_libraries(aggregator_test aggregator_lib)

# Copy executable to installation location
install(TARGETS
aggregator_test
DESTINATION lib/${PROJECT_NAME})
endif()

# Create ROS2 node executable from source files
add_executable(aggregator_node src/aggregator_node.cpp)
# Link to the previously built library to access Aggregator classes and methods
target_link_libraries(aggregator_node aggregator_lib)

# Copy executable to installation location
install(TARGETS
aggregator_node
DESTINATION lib/${PROJECT_NAME})

# Copy launch files to installation location
install(DIRECTORY
launch
DESTINATION share/${PROJECT_NAME})

ament_package()
71 changes: 71 additions & 0 deletions autonomy/interfacing/aggregator/include/aggregator_core.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#ifndef AGGREGATOR_CORE_HPP_
#define AGGREGATOR_CORE_HPP_

#include "rclcpp/rclcpp.hpp"

#include "sample_msgs/msg/filtered_array.hpp"
#include "sample_msgs/msg/unfiltered.hpp"

namespace samples {

/**
* Implementation of the internal logic used by the Aggregator Node to
* calculate the operating frequency of topics.
*/
class AggregatorCore {
public:
/**
* Aggregator constructor.
*
* @param timestamp the Unix timestamp https://en.wikipedia.org/wiki/Unix_time
*/
explicit AggregatorCore(int64_t timestamp);

/**
* Calculates the operating frequency on the "unfiltered" topic. Handles
* invalid timestamps and division by zero by returning zero.
*
* @returns frequency of messages on "unfiltered" topic
*/
double raw_frequency() const;
/**
* Calculates the operating frequency on the "filtered" topic. Handles
* invalid timestamps and division by zero by returning zero.
*
* @returns frequency of messages on "filtered" topic
*/
double filtered_frequency() const;

/**
* Used to keep track of latest timestamp and number of messages received
* over the "unfiltered" topic. Should be called before raw_frequency().
*
* @param msg
*/
void add_raw_msg(const sample_msgs::msg::Unfiltered::SharedPtr msg);
/**
* Used to keep track of latest timestamp and number of messages received
* over the "filtered" topic. Should be called before filtered_frequency().
*
* @param msg
*/
void add_filtered_msg(const sample_msgs::msg::FilteredArray::SharedPtr msg);

private:
// Number of message received on "unfiltered" and "filtered" topics.
int raw_msg_count_;
int filtered_msg_count_;

// Unix timestamp used to determine the amount of time that has passed
// since the beginning of the program.
int64_t start_;

// Unix timestamps for last time a message was received on the "unfiltered"
// and "filtered" topics.
int64_t latest_raw_time_;
int64_t latest_filtered_time_;
};

} // namespace samples

#endif // AGGREGATOR_CORE_HPP_
56 changes: 56 additions & 0 deletions autonomy/interfacing/aggregator/include/aggregator_node.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#ifndef AGGREGATOR_NODE_HPP_
#define AGGREGATOR_NODE_HPP_

#include "rclcpp/rclcpp.hpp"

#include "sample_msgs/msg/filtered_array.hpp"
#include "sample_msgs/msg/unfiltered.hpp"

#include "aggregator_core.hpp"

/**
* Implementation of a ROS2 node that listens to the "unfiltered" and "filtered"
* topics and echoes the operating frequency of the topic to the console.
*/
class AggregatorNode : public rclcpp::Node {
public:
// Configure pubsub nodes to keep last 20 messages.
// https://docs.ros.org/en/foxy/Concepts/About-Quality-of-Service-Settings.html
static constexpr int ADVERTISING_FREQ = 20;

/**
* Aggregator node constructor.
*/
AggregatorNode();

private:
/**
* A ROS2 subscription node callback used to unpack raw data from the
* "unfiltered" topic and echo the operating frequency of the topic to the
* console.
*
* @param msg a raw message from the "unfiltered" topic
*/
void unfiltered_callback(const sample_msgs::msg::Unfiltered::SharedPtr msg);

/**
* A ROS2 subscription node callback used to unpack processed data from the
* "filtered" topic and echo the operating frequency of the topic to the
* console.
*
* @param msg a processed message from the "filtered" topic
*/
void filtered_callback(const sample_msgs::msg::FilteredArray::SharedPtr msg);

// ROS2 subscriber listening to the unfiltered topic.
rclcpp::Subscription<sample_msgs::msg::Unfiltered>::SharedPtr raw_sub_;

// ROS2 subscriber listening to the filtered topic.
rclcpp::Subscription<sample_msgs::msg::FilteredArray>::SharedPtr
filtered_sub_;

// Object containing methods to determine the operating frequency on topics.
samples::AggregatorCore aggregator_;
};

#endif // AGGREGATOR_NODE_HPP_
14 changes: 14 additions & 0 deletions autonomy/interfacing/aggregator/launch/aggregator.launch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from launch import LaunchDescription
from launch_ros.actions import Node


def generate_launch_description():
"""Launch aggregator node."""
aggregator_node = Node(
package='aggregator',
executable='aggregator_node',
)

return LaunchDescription([
aggregator_node
])
23 changes: 23 additions & 0 deletions autonomy/interfacing/aggregator/package.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0"?>
<package format="3">
<name>aggregator</name>
<version>0.0.0</version>
<description>A sample ROS package for pubsub communication</description>

<maintainer email="cmahalingam@watonomous.ca">Cheran Mahalingam</maintainer>
<license>Apache2.0</license>

<!--https://www.ros.org/reps/rep-0149.html#dependency-tags-->
<buildtool_depend>ament_cmake</buildtool_depend>
<depend>rclcpp</depend>
<depend>sample_msgs</depend>

<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<test_depend>ament_cmake_gtest</test_depend>

<!--https://www.ros.org/reps/rep-0149.html#export-->
<export>
<build_type>ament_cmake</build_type>
</export>
</package>
42 changes: 42 additions & 0 deletions autonomy/interfacing/aggregator/src/aggregator_core.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include <algorithm>

#include "aggregator_core.hpp"

namespace samples {

AggregatorCore::AggregatorCore(int64_t timestamp)
: raw_msg_count_(0), filtered_msg_count_(0), start_(timestamp),
latest_raw_time_(-1), latest_filtered_time_(-1) {}

double AggregatorCore::raw_frequency() const {
if (latest_raw_time_ <= start_) {
return 0.0;
}
return static_cast<double>(raw_msg_count_) / (latest_raw_time_ - start_);
}

double AggregatorCore::filtered_frequency() const {
if (latest_filtered_time_ <= start_) {
return 0.0;
}
return static_cast<double>(filtered_msg_count_) /
(latest_filtered_time_ - start_);
}

void AggregatorCore::add_raw_msg(
const sample_msgs::msg::Unfiltered::SharedPtr msg) {
latest_raw_time_ =
std::max(static_cast<int64_t>(msg->timestamp), latest_raw_time_);
raw_msg_count_++;
}

void AggregatorCore::add_filtered_msg(
const sample_msgs::msg::FilteredArray::SharedPtr msg) {
for (auto filtered_msg : msg->packets) {
latest_filtered_time_ = std::max(
static_cast<int64_t>(filtered_msg.timestamp), latest_filtered_time_);
}
filtered_msg_count_++;
}

} // namespace samples
41 changes: 41 additions & 0 deletions autonomy/interfacing/aggregator/src/aggregator_node.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#include <chrono>
#include <memory>

#include "aggregator_node.hpp"

AggregatorNode::AggregatorNode()
: Node("aggregator"),
aggregator_(samples::AggregatorCore(
std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count())) {
raw_sub_ = this->create_subscription<sample_msgs::msg::Unfiltered>(
"/unfiltered_topic", ADVERTISING_FREQ,
std::bind(&AggregatorNode::unfiltered_callback, this,
std::placeholders::_1));
filtered_sub_ = this->create_subscription<sample_msgs::msg::FilteredArray>(
"/filtered_topic", ADVERTISING_FREQ,
std::bind(&AggregatorNode::filtered_callback, this,
std::placeholders::_1));
}

void AggregatorNode::unfiltered_callback(
const sample_msgs::msg::Unfiltered::SharedPtr msg) {
aggregator_.add_raw_msg(msg);
RCLCPP_INFO(this->get_logger(), "Raw Frequency(msg/s): %f",
aggregator_.raw_frequency() * 1000);
}

void AggregatorNode::filtered_callback(
const sample_msgs::msg::FilteredArray::SharedPtr msg) {
aggregator_.add_filtered_msg(msg);
RCLCPP_INFO(this->get_logger(), "Filtered Frequency(msg/s): %f",
aggregator_.filtered_frequency() * 1000);
}

int main(int argc, char **argv) {
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<AggregatorNode>());
rclcpp::shutdown();
return 0;
}
Loading