Skip to content
Snippets Groups Projects
Commit c5a6ab85 authored by Markus Handstedt's avatar Markus Handstedt
Browse files

WIP cowl watcher

parent 0828bd42
No related branches found
No related tags found
No related merge requests found
FROM ros:jazzy-ros-base
# Install some dependencies packages
# Install dependencies for COWL and ROS2
RUN apt update -q \
&& apt upgrade -q -y \
&& apt install -y --no-install-recommends \
......@@ -8,11 +8,31 @@ RUN apt update -q \
python3-pip \
build-essential \
libboost-all-dev \
xauth \
libxml2-dev \
libcurl4-openssl-dev \
libssl-dev \
cmake \
git \
flex \
bison \
doxygen \
&& apt clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Create workspace directory
# Clone COWL repository with submodules
RUN git clone --recursive https://github.com/sisinflab-swot/cowl.git /root/cowl
# Build COWL
WORKDIR /root/cowl
RUN cmake -B cmake-build -DCMAKE_BUILD_TYPE=Release \
&& cmake --build cmake-build --config Release \
&& cmake --install cmake-build --prefix /root/cowl/install
# Set environment variables to point to the COWL headers and libraries
ENV COWL_INCLUDE_DIR=/root/cowl/install/include
ENV COWL_LIB_DIR=/root/cowl/install/lib
# Create workspace directory for ROS 2
RUN mkdir -p /root/ros2_ws/src
WORKDIR /root/ros2_ws
......@@ -23,4 +43,4 @@ RUN echo 'source /opt/ros/$ROS_DISTRO/setup.bash' >> /root/.bashrc \
# Setup entrypoint
COPY ./ros_entrypoint.sh /
ENTRYPOINT ["/ros_entrypoint.sh"]
CMD ["bash"]
\ No newline at end of file
CMD ["bash"]
......@@ -33,12 +33,9 @@
}
},
"workspaceMount": "src=${localWorkspaceFolder},dst=/root/ros2_ws,type=bind",
//"workspaceMount": "src=/home/leolol/Code/dyknow-ros-2,dst=/root/ros2_ws,type=volume",
"workspaceFolder": "/root/ros2_ws",
//"mounts": ["src=/home/leolol/Code/dyknow-ros-2,dst=/root/ros2_ws,type=bind"],
"mounts": [],
"runArgs": [
"--net=host"
]
}
\ No newline at end of file
}
cmake_minimum_required(VERSION 3.8)
project(dyknow_cowl_watchdog)
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
find_package(geometry_msgs REQUIRED)
find_package(message_filters REQUIRED)
find_package(rosidl_default_generators REQUIRED)
set(msg_files
"msg/Lidar.msg"
)
rosidl_generate_interfaces(${PROJECT_NAME}
${msg_files}
DEPENDENCIES std_msgs
)
ament_export_dependencies(rosidl_default_runtime)
include_directories(
include
${rclcpp_INCLUDE_DIRS}
${std_msgs_INCLUDE_DIRS}
${geometry_msgs_INCLUDE_DIRS}
${message_filters_INCLUDE_DIRS}
${rosidl_default_generators_INCLUDE_DIRS}
${CMAKE_BINARY_DIR}/rosidl_generator_cpp # Include path for generated message headers
/root/cowl/include
/root/cowl/lib/ulib/include
)
# Create the library
add_library(dyknow_cowl_watchdog_lib SHARED
src/cowl_watcher.cpp
)
ament_target_dependencies(dyknow_cowl_watchdog_lib
rclcpp
std_msgs
geometry_msgs
message_filters
)
# Ensure that the generated message headers are available to this target
add_dependencies(dyknow_cowl_watchdog_lib ${PROJECT_NAME}__rosidl_typesupport_cpp)
install(TARGETS dyknow_cowl_watchdog_lib
EXPORT export_${PROJECT_NAME}
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
)
install(DIRECTORY include/
DESTINATION include/${PROJECT_NAME}/
)
# Install the CMake configuration files
install(
FILES cmake/dyknow_cowl_watchdogConfig.cmake
DESTINATION share/${PROJECT_NAME}/cmake
)
install(
EXPORT export_${PROJECT_NAME}
DESTINATION share/${PROJECT_NAME}/cmake
)
ament_package()
include(CMakeFindDependencyMacro)
find_dependency(ament_cmake)
find_dependency(rclcpp)
find_dependency(std_msgs)
find_dependency(geometry_msgs)
find_dependency(message_filters)
include("${CMAKE_CURRENT_LIST_DIR}/dyknow_cowl_watchdogTargets.cmake")
\ No newline at end of file
#ifndef INCLUDE_COWL_WATCHER_HPP_
#define INCLUDE_COWL_WATCHER_HPP_
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
#include "cowl.h"
class CowlWatcher : public rclcpp::Node {
public:
CowlWatcher();
~CowlWatcher();
private:
CowlOntology *ontology_;
std::unordered_map<std::string, rclcpp::SubscriptionBase::SharedPtr> subscriptions_;
rclcpp::TimerBase::SharedPtr discovery_timer_;
rclcpp::CallbackGroup::SharedPtr callback_group_;
std::vector<std::string> active_topics_;
void discoverTopics();
void subscribeToTopic(const std::string &topic_name);
void processMessage(const std::string &topic, const std::string &data);
};
#endif /* INCLUDE_COWL_WATCHER_HPP_ */
\ No newline at end of file
@prefix ex: <http://example.org#> .
# Define sensor classes
ex:LIDAR a rdfs:Class .
ex:Gyroscope a rdfs:Class .
ex:IR_Sensor a rdfs:Class .
# Define properties (sensor data)
ex:hasDistance a rdf:Property ; rdfs:domain ex:LIDAR ; rdfs:range xsd:float .
ex:hasAngle a rdf:Property ; rdfs:domain ex:Gyroscope ; rdfs:range xsd:float .
ex:hasTemperature a rdf:Property ; rdfs:domain ex:IR_Sensor ; rdfs:range xsd:float .
# Instances of sensors
ex:sensor1 a ex:LIDAR ; ex:hasDistance "10.5" .
ex:sensor2 a ex:Gyroscope ; ex:hasAngle "45.0" .
ex:sensor3 a ex:IR_Sensor ; ex:hasTemperature "22.5" .
<?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>dyknow_cowl_watchdog</name>
<version>0.0.0</version>
<description>TODO: Package description</description>
<maintainer email="root@todo.todo">root</maintainer>
<license>TODO: License declaration</license>
<buildtool_depend>ament_cmake</buildtool_depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<build_depend>rosidl_default_generators</build_depend>
<build_depend>std_msgs</build_depend>
<depend>builtin_interfaces</depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<exec_depend>std_msgs</exec_depend>
<buildtool_depend>rosidl_default_generators</buildtool_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>
#include "dyknow_cowl_watchdog/cowl_watcher.hpp"
#include <unordered_map>
CowlWatcher::CowlWatcher() : Node("cowl_watcher") {
cowl_init();
ontology_ = cowl_ontology_new();
// Use Reentrant callback group for parallel processing
callback_group_ = this->create_callback_group(rclcpp::CallbackGroupType::Reentrant);
// Timer to check for new topics every 5 seconds
discovery_timer_ = this->create_wall_timer(
std::chrono::seconds(5),
std::bind(&CowlWatcher::discoverTopics, this)
);
// Initial topic discovery
discoverTopics();
}
CowlWatcher::~CowlWatcher() {
cowl_ontology_free(ontology_);
}
void CowlWatcher::discoverTopics() {
auto topic_names_and_types = this->get_topic_names_and_types();
for (const auto &topic : topic_names_and_types) {
const std::string &topic_name = topic.first;
if(std::find(active_topics_.begin(), active_topics_.end(), topic_name) == active_topics_.end()) {
RCLCPP_INFO(this->get_logger(), "New topic detected: %s", topic_name.c_str());
subscribeToTopic(topic_name);
active_topics_.push_back(topic_name);
}
}
}
void CowlWatcher::subscribeToTopic(const std::string &topic_name) {
auto sub = this->create_subscription<std_msgs::msg::String>(
topic_name, 10,
[this, topic_name](const std_msgs::msg::String::SharedPtr msg) {
processMessage(topic_name, msg->data);
},
rclcpp::SubscriptionOptions().callback_group(callback_group_)
);
subscriptions_[topic_name] = sub;
}
void CowlWatcher::processMessage(const std::string &topic, const std::string &data) {
// Convert message into RDF triple
std::string subject = "ex:" + topic;
std::string predicate = "ex::hasValue";
std::string object = '"' + data + '"';
// Create Cowl strings for subject, predicate, and object
CowlString *subject_str = cowl_string_new(subject.c_str());
CowlString *predicate_str = cowl_string_new(predicate.c_str());
CowlString *object_str = cowl_string_new(object.c_str());
CowlAxiom* axiom = cowl_axiom_new(subject_str, predicate_str, object_str);
cowl_ontology_add_axiom(ontology_, axiom);
RCLCPP_INFO(this->get_logger(), "Added RDF: (%s, %s, %s)", subject.c_str(), predicate.c_str(), object.c_str());
cowl_release(subject_str);
cowl_release(predicate_str);
cowl_release(object_str);
}
int main(int argc, char **argv) {
rclcpp::init(argc, argv);
auto node = std::make_shared<CowlWatcher>();
rclcpp::executors::MultiThreadedExecutor executor;
executor.add_node(node);
executor.spin();
rclcpp::shutdown();
return 0;
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment