Class Diagrams

The library is structured around two main classes: SoarRunner and SoarAgent. SoarRunner owns the sml::Kernel, the run thread and the ROS2 service interfaces. SoarAgent wraps a single sml::Agent and owns all ROS2 I/O objects (publishers, subscribers, services, clients) for that agent.

class SoarRunner : public rclcpp::Node

Inheritance diagram for soar_ros::SoarRunner:

digraph {
    graph [bgcolor="#00000000"]
    node [shape=rectangle style=filled fillcolor="#FFFFFF" font=Helvetica padding=2]
    edge [color="#1414CE"]
    "2" [label="rclcpp::Node" tooltip="rclcpp::Node"]
    "1" [label="soar_ros::SoarRunner" tooltip="soar_ros::SoarRunner" fillcolor="#BFBFBF"]
    "1" -> "2" [dir=forward tooltip="public-inheritance"]
}

Collaboration diagram for soar_ros::SoarRunner:

digraph {
    graph [bgcolor="#00000000"]
    node [shape=rectangle style=filled fillcolor="#FFFFFF" font=Helvetica padding=2]
    edge [color="#1414CE"]
    "2" [label="rclcpp::Node" tooltip="rclcpp::Node"]
    "1" [label="soar_ros::SoarRunner" tooltip="soar_ros::SoarRunner" fillcolor="#BFBFBF"]
    "1" -> "2" [dir=forward tooltip="public-inheritance"]
}

ROS2 node that manages a Soar kernel and its agents.

Responsibilities:

  • Own the sml::Kernel and the spin thread.

  • Create sml::Agent instances on request and wrap them in SoarAgent.

  • Expose ROS2 service interfaces to start/stop the kernel and launch the Soar Java debugger.

I/O wiring is done on each SoarAgent returned from addAgent(), not here.

class SoarAgent

Per-agent wrapper that owns all ROS I/O wiring for one Soar agent.

Returned by SoarRunner::addAgent() as a shared_ptr<SoarAgent>. User code registers interfaces directly on the agent:

auto agent = node->addAgent("MyAgent", path);
agent->addPublisher(std::make_shared<MyPub>(agent->getSmlAgent(), node, "cmd"));
agent->addSubscriber(std::make_shared<MySub>(agent->getSmlAgent(), node, "topic"));

SoarRunner calls updateWorld() on every SoarAgent each decision cycle via the smlEVENT_AFTER_ALL_OUTPUT_PHASES callback.

The following class diagram of the soar_ros::Service class (inheritance diagram) provides a basic overview of the ROS2 interface wrappers.

All ROS wrapper classes adjusted for usage with Soar are based on the input or output base classes as well as the shared interface.

template<typename T, typename pRequestType = typename T::Request::SharedPtr, typename pResponseType = typename T::Response::SharedPtr>
class Service : public virtual soar_ros::Input<typename T::Request::SharedPtr>, public virtual soar_ros::Output<typename T::Response::SharedPtr>, public soar_ros::Interface

Inheritance diagram for soar_ros::Service:

digraph {
    graph [bgcolor="#00000000"]
    node [shape=rectangle style=filled fillcolor="#FFFFFF" font=Helvetica padding=2]
    edge [color="#1414CE"]
    "2" [label="soar_ros::Input< typename T::Request::SharedPtr >" tooltip="soar_ros::Input< typename T::Request::SharedPtr >"]
    "3" [label="soar_ros::InputBase" tooltip="soar_ros::InputBase"]
    "6" [label="soar_ros::Interface" tooltip="soar_ros::Interface"]
    "4" [label="soar_ros::Output< typename T::Response::SharedPtr >" tooltip="soar_ros::Output< typename T::Response::SharedPtr >"]
    "5" [label="soar_ros::OutputBase" tooltip="soar_ros::OutputBase"]
    "1" [label="soar_ros::Service< T, pRequestType, pResponseType >" tooltip="soar_ros::Service< T, pRequestType, pResponseType >" fillcolor="#BFBFBF"]
    "2" -> "3" [dir=forward tooltip="public-inheritance"]
    "4" -> "5" [dir=forward tooltip="public-inheritance"]
    "1" -> "2" [dir=forward tooltip="public-inheritance"]
    "1" -> "4" [dir=forward tooltip="public-inheritance"]
    "1" -> "6" [dir=forward tooltip="public-inheritance"]
}

Collaboration diagram for soar_ros::Service:

digraph {
    graph [bgcolor="#00000000"]
    node [shape=rectangle style=filled fillcolor="#FFFFFF" font=Helvetica padding=2]
    edge [color="#1414CE"]
    "2" [label="soar_ros::Input< typename T::Request::SharedPtr >" tooltip="soar_ros::Input< typename T::Request::SharedPtr >"]
    "3" [label="soar_ros::InputBase" tooltip="soar_ros::InputBase"]
    "6" [label="soar_ros::Interface" tooltip="soar_ros::Interface"]
    "4" [label="soar_ros::Output< typename T::Response::SharedPtr >" tooltip="soar_ros::Output< typename T::Response::SharedPtr >"]
    "5" [label="soar_ros::OutputBase" tooltip="soar_ros::OutputBase"]
    "1" [label="soar_ros::Service< T, pRequestType, pResponseType >" tooltip="soar_ros::Service< T, pRequestType, pResponseType >" fillcolor="#BFBFBF"]
    "2" -> "3" [dir=forward tooltip="public-inheritance"]
    "4" -> "5" [dir=forward tooltip="public-inheritance"]
    "1" -> "2" [dir=forward tooltip="public-inheritance"]
    "1" -> "4" [dir=forward tooltip="public-inheritance"]
    "1" -> "6" [dir=forward tooltip="public-inheritance"]
}

The difference between service and client from the libraries perspective is only the reversal of output and input calls.

template<typename T, typename pRequestType = typename T::Request::SharedPtr, typename pResponseType = typename T::Response::SharedPtr>
class Client : public virtual soar_ros::Output<typename T::Request::SharedPtr>, public virtual soar_ros::Input<typename T::Response::SharedPtr>, public soar_ros::Interface

Inheritance diagram for soar_ros::Client:

digraph {
    graph [bgcolor="#00000000"]
    node [shape=rectangle style=filled fillcolor="#FFFFFF" font=Helvetica padding=2]
    edge [color="#1414CE"]
    "1" [label="soar_ros::Client< T, pRequestType, pResponseType >" tooltip="soar_ros::Client< T, pRequestType, pResponseType >" fillcolor="#BFBFBF"]
    "4" [label="soar_ros::Input< typename T::Response::SharedPtr >" tooltip="soar_ros::Input< typename T::Response::SharedPtr >"]
    "5" [label="soar_ros::InputBase" tooltip="soar_ros::InputBase"]
    "6" [label="soar_ros::Interface" tooltip="soar_ros::Interface"]
    "2" [label="soar_ros::Output< typename T::Request::SharedPtr >" tooltip="soar_ros::Output< typename T::Request::SharedPtr >"]
    "3" [label="soar_ros::OutputBase" tooltip="soar_ros::OutputBase"]
    "1" -> "2" [dir=forward tooltip="public-inheritance"]
    "1" -> "4" [dir=forward tooltip="public-inheritance"]
    "1" -> "6" [dir=forward tooltip="public-inheritance"]
    "4" -> "5" [dir=forward tooltip="public-inheritance"]
    "2" -> "3" [dir=forward tooltip="public-inheritance"]
}

Collaboration diagram for soar_ros::Client:

digraph {
    graph [bgcolor="#00000000"]
    node [shape=rectangle style=filled fillcolor="#FFFFFF" font=Helvetica padding=2]
    edge [color="#1414CE"]
    "1" [label="soar_ros::Client< T, pRequestType, pResponseType >" tooltip="soar_ros::Client< T, pRequestType, pResponseType >" fillcolor="#BFBFBF"]
    "4" [label="soar_ros::Input< typename T::Response::SharedPtr >" tooltip="soar_ros::Input< typename T::Response::SharedPtr >"]
    "5" [label="soar_ros::InputBase" tooltip="soar_ros::InputBase"]
    "6" [label="soar_ros::Interface" tooltip="soar_ros::Interface"]
    "2" [label="soar_ros::Output< typename T::Request::SharedPtr >" tooltip="soar_ros::Output< typename T::Request::SharedPtr >"]
    "3" [label="soar_ros::OutputBase" tooltip="soar_ros::OutputBase"]
    "1" -> "2" [dir=forward tooltip="public-inheritance"]
    "1" -> "4" [dir=forward tooltip="public-inheritance"]
    "1" -> "6" [dir=forward tooltip="public-inheritance"]
    "4" -> "5" [dir=forward tooltip="public-inheritance"]
    "2" -> "3" [dir=forward tooltip="public-inheritance"]
}

Publisher and subscriber only have either the input or the output functionality:

template<typename T>
class Publisher : public soar_ros::Output<T>, public soar_ros::Interface

Inheritance diagram for soar_ros::Publisher:

digraph {
    graph [bgcolor="#00000000"]
    node [shape=rectangle style=filled fillcolor="#FFFFFF" font=Helvetica padding=2]
    edge [color="#1414CE"]
    "4" [label="soar_ros::Interface" tooltip="soar_ros::Interface"]
    "2" [label="soar_ros::Output< T >" tooltip="soar_ros::Output< T >"]
    "3" [label="soar_ros::OutputBase" tooltip="soar_ros::OutputBase"]
    "1" [label="soar_ros::Publisher< T >" tooltip="soar_ros::Publisher< T >" fillcolor="#BFBFBF"]
    "2" -> "3" [dir=forward tooltip="public-inheritance"]
    "1" -> "2" [dir=forward tooltip="public-inheritance"]
    "1" -> "4" [dir=forward tooltip="public-inheritance"]
}

Collaboration diagram for soar_ros::Publisher:

digraph {
    graph [bgcolor="#00000000"]
    node [shape=rectangle style=filled fillcolor="#FFFFFF" font=Helvetica padding=2]
    edge [color="#1414CE"]
    "4" [label="soar_ros::Interface" tooltip="soar_ros::Interface"]
    "2" [label="soar_ros::Output< T >" tooltip="soar_ros::Output< T >"]
    "3" [label="soar_ros::OutputBase" tooltip="soar_ros::OutputBase"]
    "1" [label="soar_ros::Publisher< T >" tooltip="soar_ros::Publisher< T >" fillcolor="#BFBFBF"]
    "2" -> "3" [dir=forward tooltip="public-inheritance"]
    "1" -> "2" [dir=forward tooltip="public-inheritance"]
    "1" -> "4" [dir=forward tooltip="public-inheritance"]
}
template<typename T>
class Subscriber : public soar_ros::Input<T>, public soar_ros::Interface

Inheritance diagram for soar_ros::Subscriber:

digraph {
    graph [bgcolor="#00000000"]
    node [shape=rectangle style=filled fillcolor="#FFFFFF" font=Helvetica padding=2]
    edge [color="#1414CE"]
    "2" [label="soar_ros::Input< T >" tooltip="soar_ros::Input< T >"]
    "3" [label="soar_ros::InputBase" tooltip="soar_ros::InputBase"]
    "4" [label="soar_ros::Interface" tooltip="soar_ros::Interface"]
    "1" [label="soar_ros::Subscriber< T >" tooltip="soar_ros::Subscriber< T >" fillcolor="#BFBFBF"]
    "2" -> "3" [dir=forward tooltip="public-inheritance"]
    "1" -> "2" [dir=forward tooltip="public-inheritance"]
    "1" -> "4" [dir=forward tooltip="public-inheritance"]
}

Collaboration diagram for soar_ros::Subscriber:

digraph {
    graph [bgcolor="#00000000"]
    node [shape=rectangle style=filled fillcolor="#FFFFFF" font=Helvetica padding=2]
    edge [color="#1414CE"]
    "2" [label="soar_ros::Input< T >" tooltip="soar_ros::Input< T >"]
    "3" [label="soar_ros::InputBase" tooltip="soar_ros::InputBase"]
    "4" [label="soar_ros::Interface" tooltip="soar_ros::Interface"]
    "1" [label="soar_ros::Subscriber< T >" tooltip="soar_ros::Subscriber< T >" fillcolor="#BFBFBF"]
    "2" -> "3" [dir=forward tooltip="public-inheritance"]
    "1" -> "2" [dir=forward tooltip="public-inheritance"]
    "1" -> "4" [dir=forward tooltip="public-inheritance"]
}