// 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