/// <summary> /// Internal ROS deinitialization method. Called by checkForShutdown. /// </summary> private static void _shutdown() { if (started) { logger.LogInformation("ROS is shutting down."); RaiseRosShuttingDown(); SimTime.Terminate(); RosOutAppender.Terminate(); GlobalNodeHandle.Shutdown().Wait(); GlobalCallbackQueue.Disable(); GlobalCallbackQueue.Clear(); XmlRpcManager.Instance.Unbind("shutdown"); Param.Terminate(); TopicManager.Terminate(); ServiceManager.Terminate(); XmlRpcManager.Terminate(); ConnectionManager.Terminate(); lock (startMutex) { started = false; ResetStaticMembers(); } RaiseRosShutDown(); } }
/// <summary> /// Initializes ROS /// </summary> /// <param name="remappingArgs"> dictionary of remapping args </param> /// <param name="name"> node name </param> /// <param name="options"> options </param> public static void Init(IDictionary <string, string> remappingArgs, string name, InitOptions options = 0) { lock (typeof(ROS)) { // register process unload and cancel (CTRL+C) event handlers if (!atExitRegistered) { atExitRegistered = true; #if NETCORE AssemblyLoadContext.Default.Unloading += (AssemblyLoadContext obj) => { Shutdown(); WaitForShutdown(); }; #else Process.GetCurrentProcess().EnableRaisingEvents = true; Process.GetCurrentProcess().Exited += (o, args) => { Shutdown(); WaitForShutdown(); }; #endif Console.CancelKeyPress += (o, args) => { Shutdown(); WaitForShutdown(); args.Cancel = true; }; } // crate global callback queue if (globalCallbackQueue == null) { globalCallbackQueue = new CallbackQueue(); } // run the actual ROS initialization if (!initialized) { MessageTypeRegistry.Default.Reset(); ServiceTypeRegistry.Default.Reset(); var msgRegistry = MessageTypeRegistry.Default; var srvRegistry = ServiceTypeRegistry.Default; // Load RosMessages from MessageBase assembly msgRegistry.ParseAssemblyAndRegisterRosMessages(typeof(RosMessage).GetTypeInfo().Assembly); // Load RosMessages from all assemblies that reference Uml.Robotics.Ros.MessageBas var candidates = MessageTypeRegistry.GetCandidateAssemblies("Uml.Robotics.Ros.MessageBase"); foreach (var assembly in candidates) { logger.LogDebug($"Parse assembly: {assembly.Location}"); msgRegistry.ParseAssemblyAndRegisterRosMessages(assembly); srvRegistry.ParseAssemblyAndRegisterRosServices(assembly); } initOptions = options; _ok = true; Param.Reset(); SimTime.Reset(); RosOutAppender.Reset(); Network.Init(remappingArgs); Master.Init(remappingArgs); ThisNode.Init(name, remappingArgs, options); Param.Init(remappingArgs); SimTime.Instance.SimTimeEvent += SimTimeCallback; lock (shuttingDownMutex) { switch (shutdownTask?.Status) { case null: case TaskStatus.RanToCompletion: break; default: throw new InvalidOperationException("ROS was not shut down correctly"); } shutdownTask = new Task(_shutdown); } initialized = true; GlobalNodeHandle = new NodeHandle(ThisNode.Namespace, remappingArgs); RosOutAppender.Instance.Start(); } } }