/* * Copyright (c) Contributors to the Open 3D Engine Project. * For complete copyright and license terms please see the LICENSE at the root of this distribution. * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ #include #include #include #include #include #include #include #include #include #include #include namespace ROS2 { void ROS2SystemComponent::Reflect(AZ::ReflectContext* context) { // Reflect structs not strictly owned by any single component QoS::Reflect(context); TopicConfiguration::Reflect(context); VehicleDynamics::VehicleModelComponent::Reflect(context); ROS2::Controllers::PidConfiguration::Reflect(context); if (AZ::SerializeContext* serialize = azrtti_cast(context)) { serialize->Class()->Version(0); if (AZ::EditContext* ec = serialize->GetEditContext()) { ec->Class("ROS2 System Component", "[Description of functionality provided by this System Component]") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("System")) ->Attribute(AZ::Edit::Attributes::Category, "ROS2") ->Attribute(AZ::Edit::Attributes::AutoExpand, true); } } } void ROS2SystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) { provided.push_back(AZ_CRC_CE("ROS2Service")); } void ROS2SystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { incompatible.push_back(AZ_CRC_CE("ROS2Service")); } void ROS2SystemComponent::GetRequiredServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& required) { required.push_back(AZ_CRC("AssetDatabaseService", 0x3abf5601)); required.push_back(AZ_CRC("RPISystem", 0xf2add773)); } void ROS2SystemComponent::GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent) { } ROS2SystemComponent::ROS2SystemComponent() { if (ROS2Interface::Get() == nullptr) { ROS2Interface::Register(this); } } ROS2SystemComponent::~ROS2SystemComponent() { if (ROS2Interface::Get() == this) { ROS2Interface::Unregister(this); } rclcpp::shutdown(); } void ROS2SystemComponent::Init() { rclcpp::init(0, 0); m_ros2Node = std::make_shared("o3de_ros2_node"); m_executor = AZStd::make_shared(); m_executor->add_node(m_ros2Node); } void ROS2SystemComponent::Activate() { m_staticTFBroadcaster = AZStd::make_unique(m_ros2Node); m_dynamicTFBroadcaster = AZStd::make_unique(m_ros2Node); auto* passSystem = AZ::RPI::PassSystemInterface::Get(); AZ_Assert(passSystem, "Cannot get the pass system."); m_loadTemplatesHandler = AZ::RPI::PassSystemInterface::OnReadyLoadTemplatesEvent::Handler( [this]() { this->LoadPassTemplateMappings(); }); passSystem->ConnectEvent(m_loadTemplatesHandler); ROS2RequestBus::Handler::BusConnect(); AZ::TickBus::Handler::BusConnect(); } void ROS2SystemComponent::Deactivate() { AZ::TickBus::Handler::BusDisconnect(); ROS2RequestBus::Handler::BusDisconnect(); m_loadTemplatesHandler.Disconnect(); m_dynamicTFBroadcaster.reset(); m_staticTFBroadcaster.reset(); } builtin_interfaces::msg::Time ROS2SystemComponent::GetROSTimestamp() const { return m_simulationClock.GetROSTimestamp(); } std::shared_ptr ROS2SystemComponent::GetNode() const { return m_ros2Node; } const SimulationClock& ROS2SystemComponent::GetSimulationClock() const { return m_simulationClock; } void ROS2SystemComponent::BroadcastTransform(const geometry_msgs::msg::TransformStamped& t, bool isDynamic) const { if (isDynamic) { m_dynamicTFBroadcaster->sendTransform(t); } else { m_staticTFBroadcaster->sendTransform(t); } } void ROS2SystemComponent::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time) { if (rclcpp::ok()) { m_simulationClock.Tick(); m_executor->spin_some(); } } void ROS2SystemComponent::LoadPassTemplateMappings() { AZ_Printf("ROS2CameraSensorComponent", "LoadPassTemplateMappings\n"); auto* passSystem = AZ::RPI::PassSystemInterface::Get(); AZ_Assert(passSystem, "PassSystemInterface is null"); const char* passTemplatesFile = "Passes/ROSPassTemplates.azasset"; [[maybe_unused]] bool isOk = passSystem->LoadPassTemplateMappings(passTemplatesFile); AZ_Assert(isOk, "LoadPassTemplateMappings return false "); } } // namespace ROS2