// Copyright 2019-2021 Robotec.ai. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using System; using System.Collections.Generic; using UnityEngine; using UnityEditor; namespace ROS2 { /// /// A class representing a ros2 node. Multiple nodes can be used. Node can be removed by GC when not used anymore, /// but will also be removed properly with Ros2cs Shutdown, which ROS2 for Unity performs on application quit /// The node should be constructed through ROS2UnityComponent class, which also handles spinning /// public class ROS2Node { internal INode node; public ROS2Clock clock; public string name; // Use ROS2UnityComponent to create a node internal ROS2Node(string unityROS2NodeName = "unity_ros2_node") { name = unityROS2NodeName; node = Ros2cs.CreateNode(name); clock = new ROS2Clock(); } ~ROS2Node() { Ros2cs.RemoveNode(node); } private static void ThrowIfUninitialized(string callContext) { if (!Ros2cs.Ok()) { throw new InvalidOperationException("Ros2 For Unity is not initialized, can't " + callContext); } } /// /// Create a publisher with QoS suitable for sensor data /// /// The publisher /// topic that will be used for publishing public Publisher CreateSensorPublisher(string topicName) where T : Message, new() { QualityOfServiceProfile sensorProfile = new QualityOfServiceProfile(QosPresetProfile.SENSOR_DATA); return CreatePublisher(topicName, sensorProfile); } /// /// Create a publisher with indicated QoS. /// /// The publisher /// topic that will be used for publishing /// QoS for publishing. If no QoS is selected, it will default to reliable, keep 10 last public Publisher CreatePublisher(string topicName, QualityOfServiceProfile qos = null) where T : Message, new() { ThrowIfUninitialized("create publisher"); return node.CreatePublisher(topicName, qos); } /// /// Create a subscription /// /// The subscription /// topic to subscribe to /// QoS for subscription. If no QoS is selected, it will default to reliable, keep 10 last public Subscription CreateSubscription(string topicName, Action callback, QualityOfServiceProfile qos = null) where T : Message, new() { if (qos == null) { qos = new QualityOfServiceProfile(QosPresetProfile.DEFAULT); } ThrowIfUninitialized("create subscription"); return node.CreateSubscription(topicName, callback, qos); } /// /// Remove existing subscription (returned earlier with CreateSubscription) /// /// The whether subscription was found (e. g. false if removed earlier elsewhere) /// subscrition to remove, returned from CreateSubscription public bool RemoveSubscription(ISubscriptionBase subscription) { ThrowIfUninitialized("remove subscription"); return node.RemoveSubscription(subscription); } /// /// Remove existing publisher /// /// The whether publisher was found (e. g. false if removed earlier elsewhere) /// publisher to remove, returned from CreatePublisher or CreateSensorPublisher public bool RemovePublisher(IPublisherBase publisher) { ThrowIfUninitialized("remove publisher"); return node.RemovePublisher(publisher); } /// public Service CreateService(string topic, Func callback, QualityOfServiceProfile qos = null) where I : Message, new() where O : Message, new() { ThrowIfUninitialized("create service"); return node.CreateService(topic, callback, qos); } /// public bool RemoveService(IServiceBase service) { ThrowIfUninitialized("remove service"); return node.RemoveService(service); } /// public Client CreateClient(string topic, QualityOfServiceProfile qos = null) where I : Message, new() where O : Message, new() { ThrowIfUninitialized(callContext: "create client"); return node.CreateClient(topic, qos); } /// public bool RemoveClient(IClientBase client) { ThrowIfUninitialized(callContext: "remove client"); return node.RemoveClient(client); } } } // namespace ROS2