/// <summary> /// Registers with the correct services /// </summary> public void Register() { try { // "Activate" the NameService singleton. objectDirectory = (ObjectDirectory)Activator.GetObject(typeof(ObjectDirectory), wkst[0].ObjectUri); // Retreive the directory of messaging channels IChannelFactory channelFactory = (IChannelFactory)objectDirectory.Resolve("ChannelFactory"); // Retreive the Messaging Service channels we want to push to simulationMessageChannel = channelFactory.GetChannel("SimulationMessageChannel", ChannelMode.UdpMulticast); // Rebind the Simulator as the simulator remote facade server objectDirectory.Rebind(this, "SimulationServer"); // Notify user of success SimulatorOutput.WriteLine("Connection to Name Service and Registration of Simulation Server as Simulator Facade Successful"); // let clients know the sim is alive simulationMessageChannel.PublishUnreliably(SimulationMessage.Alive); } catch (Exception e) { SimulatorOutput.WriteLine("Error Registering With Remoting Services: " + e.ToString()); } }
/// <summary> /// Register a client with the simulation /// </summary> /// <param name="clientName"></param> /// <returns></returns> public override bool Register(string clientName) { try { // resolve the client SimulatorClientFacade scf = (SimulatorClientFacade)objectDirectory.Resolve(clientName); // client name string name = scf.Name(); // invoke changes this.simulation.BeginInvoke(new MethodInvoker(delegate() { // notify this.simulation.clientHandler.AddClient(name, scf, this.simulation.simEngine.Vehicles); this.simulation.OnClientsChanged(); })); // return success return(true); } catch (Exception e) { this.simulation.BeginInvoke(new MethodInvoker(delegate() { // notify SimulatorOutput.WriteLine("Error Registering Client: " + clientName + ". \n" + e.ToString()); })); // return error return(false); } }
/// <summary> /// End simulation /// </summary> public void EndSimulation() { // stop sim this.SimulationState = SimulationState.Stopped; // notify SimulatorOutput.WriteLine("Simulation Stopped"); // state this.simulationMain.SimulationModeLabel.Text = "Simulation Stopped"; this.simulationMain.SimulationModeLabel.Image = global::Simulator.Properties.Resources.Light_Bulb_Off_16_n_p; }
/// <summary> /// Remove a client /// </summary> /// <param name="vehicleId"></param> /// <returns></returns> public bool Remove(SimVehicleId vehicleId) { // check to see if this vehicle is associated with a client if (VehicleToClientMap.ContainsKey(vehicleId)) { // get name of client vehicle associated with string client = VehicleToClientMap[vehicleId]; try { // remove vehicle from client to vehicle map this.ClientToVehicleMap.Remove(client); // remove client from vehicle to client map this.VehicleToClientMap.Remove(vehicleId); // remove vehicle from client this.AvailableClients[client].SetVehicle(null); // notify success SimulatorOutput.WriteLine("Successfully removed vehicle: " + vehicleId.ToString() + " from clients"); // return success return(true); } catch (Exception e) { // there was an error SimulatorOutput.WriteLine("Error removing vehicle: " + vehicleId.ToString() + " from clients: \n" + e.ToString()); // cleanup vehicle to client map if (this.VehicleToClientMap.ContainsKey(vehicleId)) { this.VehicleToClientMap.Remove(vehicleId); } // cleanup client to vehicle map if (this.ClientToVehicleMap.ContainsKey(client)) { this.ClientToVehicleMap.Remove(client); } // return unsuccessful return(false); } } else { return(true); } }
public void Step() { if (stepMode) { stepEvent.Set(); if (!this.simulationMain.IsDisposed) { this.simulationMain.BeginInvoke(new MethodInvoker(delegate() { SimulatorOutput.WriteLine("Stepping Sim"); })); } } }
/// <summary> /// Configures remoting /// </summary> public void Configure() { try { // configure RemotingConfiguration.Configure("Simulator.exe.config", false); wkst = RemotingConfiguration.GetRegisteredWellKnownServiceTypes(); // notfy SimulatorOutput.WriteLine("Remoting Configured Successfully"); } catch (Exception e) { SimulatorOutput.WriteLine("Error Configuring Remoting: " + e.ToString()); } }
/// <summary> /// Just run the sim /// </summary> public void RunSimulation() { // running this.SimulationState = SimulationState.Running; // notify SimulatorOutput.WriteLine("Simulation Started"); // start thread Thread d = new Thread(Simulate); d.Priority = ThreadPriority.AboveNormal; d.IsBackground = true; d.Start(); // state this.simulationMain.SimulationModeLabel.Text = "Simulation Running"; this.simulationMain.SimulationModeLabel.Image = global::Simulator.Properties.Resources.Light_Bulb_On_16_n_p; }
/// <summary> /// Runs to maintain the simulation and clients /// </summary> private void Maintenance() { while (true) { // to remove List <string> toRemove = new List <string>(); lock (((ICollection)this.simulation.clientHandler.AvailableClients).SyncRoot) { // attempt to ping all clients foreach (KeyValuePair <string, SimulatorClientFacade> client in this.simulation.clientHandler.AvailableClients) { try { client.Value.Ping(); } catch (Exception e) { toRemove.Add(client.Key); Console.WriteLine(e.ToString()); } } } foreach (string s in toRemove) { this.simulation.BeginInvoke(new MethodInvoker(delegate() { // notify SimulatorOutput.WriteLine("Error Maintaining Client: " + s + ", Removed"); // remove client this.simulation.clientHandler.Remove(s); this.simulation.OnClientsChanged(); })); } Thread.Sleep(2000); } }
/// <summary> /// Add a client to the simulation /// </summary> /// <param name="client"></param> /// <param name="scf"></param> /// <param name="vehicles"></param> /// <returns></returns> public bool AddClient(string client, SimulatorClientFacade scf, Dictionary <SimVehicleId, SimVehicle> vehicles) { try { // check if already a client if (this.AvailableClients.ContainsKey(client)) { // remove if already bound for some reason this.Remove(client); } // lock lock (((ICollection)this.AvailableClients).SyncRoot) { // add to available clients this.AvailableClients.Add(client, scf); } // notify success SimulatorOutput.WriteLine("Successfully added client: " + client); // attempt to rebind the vehicles this.ReBindAll(vehicles); // return success return(true); } catch (Exception e) { // notify failure SimulatorOutput.WriteLine("Error adding client: " + client + ": \n" + e.ToString()); // return false return(false); } }
/// <summary> /// The simulation main thread /// </summary> public void Simulate() { // run sim at 10Hz MMWaitableTimer timer = new MMWaitableTimer((uint)this.settings.SimCycleTime); // notify this.simulationMain.SimulationModeLabel.Text = "Simulation Running"; this.simulationMain.SimulationModeLabel.Image = global::Simulator.Properties.Resources.Light_Bulb_On_16_n_p; // run while on while (this.SimulationState == SimulationState.Running) { if (stepMode) { // if we're in step mode, then wait on the step event or time out bool gotEvent = stepEvent.WaitOne(250, false); // if we timed out, start the loop over if (!gotEvent) { continue; } } else { // wait for 10hz timer.WaitEvent.WaitOne(); } try { // get world state WorldState ws = this.WorldService.GetWorldState(); lock (this.simulationMain.clientHandler) { // set world state to each client in the sim foreach (string client in this.simulationMain.clientHandler.VehicleToClientMap.Values) { try { // update client SimVehicleState nextState = this.simulationMain.clientHandler.AvailableClients[client].Update(ws, (double)this.settings.SimCycleTime / 1000.0); if (nextState != null) { // update state this.Vehicles[this.simulationMain.clientHandler.ClientToVehicleMap[client]].SimVehicleState = nextState; } else { throw new Exception("Received null SimVehicleState from " + client); } } catch (Exception e) { if (!this.simulationMain.IsDisposed) { this.simulationMain.BeginInvoke(new MethodInvoker(delegate() { // notify SimulatorOutput.WriteLine("Error Updating Client: " + client + ", Simulation Stopped"); // set state this.simulationMain.SimulationModeLabel.Text = "Simulation Stopped"; this.simulationMain.SimulationModeLabel.Image = global::Simulator.Properties.Resources.Light_Bulb_Off_16_n_p; // stop this.EndSimulation(); })); Console.WriteLine(e.ToString()); // leave break; } } } } // redraw this.simulationMain.BeginInvoke(new MethodInvoker(delegate() { // notify this.simulationMain.roadDisplay1.Invalidate(); })); } catch (Exception e) { if (!this.simulationMain.IsDisposed) { this.simulationMain.BeginInvoke(new MethodInvoker(delegate() { // notify SimulatorOutput.WriteLine("Error in outer sim loop:" + e.ToString()); })); } } } }
/// <summary> /// Associate the vehicle with a enw client /// </summary> /// <param name="vehicleId"></param> /// <returns></returns> public bool ReBind(SimVehicleId vehicleId) { // make sure that the vehicle is not already associated with a client if (!VehicleToClientMap.ContainsKey(vehicleId)) { // loop over all clients looking for an open client foreach (string s in this.AvailableClients.Keys) { // make sure the client is not associated with a vehicle if (!ClientToVehicleMap.ContainsKey(s)) { try { // get the client SimulatorClientFacade scf = this.AvailableClients[s]; // set the vehicle in the client scf.SetVehicle(vehicleId); // set vehicle as having client VehicleToClientMap.Add(vehicleId, s); // set client as having vehicle ClientToVehicleMap.Add(s, vehicleId); // success SimulatorOutput.WriteLine("Vehicle: " + vehicleId.ToString() + " Bound to client: " + s); // return that the rebind was successful return(true); } catch (Exception e) { // there was an error SimulatorOutput.WriteLine("Error binding vehicle: " + vehicleId.ToString() + " to client: " + s + "\n" + e.ToString()); // cleanup vehicle to client map if (this.VehicleToClientMap.ContainsKey(vehicleId)) { this.VehicleToClientMap.Remove(vehicleId); } // cleanup client to vehicle map if (this.ClientToVehicleMap.ContainsKey(s)) { this.ClientToVehicleMap.Remove(s); } // return that the attempt was unsuccessful return(false); } } } // success SimulatorOutput.WriteLine("Vehicle: " + vehicleId.ToString() + " Could not be bound to any clients, lack of availability"); // notify that we never got to this point return(false); } else { return(true); } }
/// <summary> /// Removes a client /// </summary> /// <param name="client"></param> /// <returns></returns> public bool Remove(string client) { // check if the client is associated with a vehicle if (this.ClientToVehicleMap.ContainsKey(client)) { // get vehicle associated with teh client SimVehicleId svi = this.ClientToVehicleMap[client]; try { // remove vehicle from client map if (this.ClientToVehicleMap.ContainsKey(client)) { this.ClientToVehicleMap.Remove(client); } // remove client from vehicle map if (this.VehicleToClientMap.ContainsKey(svi)) { this.VehicleToClientMap.Remove(svi); } // lock the clients lock (((ICollection)this.AvailableClients).SyncRoot) { // kill the client this.AvailableClients[client].Kill(); // remove the client from the available clients this.AvailableClients.Remove(client); } } catch (Exception e) { // lock the clients lock (((ICollection)this.AvailableClients).SyncRoot) { // remove the client from available if (this.AvailableClients.ContainsKey(client)) { this.AvailableClients.Remove(client); } } Console.WriteLine(e.ToString()); } // notify success SimulatorOutput.WriteLine("Successfully removed client: " + client); // rebind teh vehicle associated with the client return(this.ReBind(svi)); } else { // lock the clients lock (((ICollection)this.AvailableClients).SyncRoot) { try { // kill the client this.AvailableClients[client].Kill(); // remove the client from the available clients this.AvailableClients.Remove(client); } catch (Exception e) { // remove the client from available if (this.AvailableClients.ContainsKey(client)) { this.AvailableClients.Remove(client); } Console.WriteLine(e.ToString()); } } // notify success SimulatorOutput.WriteLine("Successfully removed client: " + client); // return success return(true); } }