private void fn_SetState(COMM_STATE nComState, CONTROL_STATE nConState, PORT_STATE nPortState, PROCESS_STATE nProcState, ALARM_STATE nAlarmState) { stState.CommunicationState = (int)nComState; stState.ControlState = (int)nConState; stState.PortState = (int)nPortState; stState.ProcessState = (int)nProcState; stState.AlarmState = (int)nAlarmState; Server.SendPacket.DataClear(); Server.SendPacket.Reply = (int)REPLY.ack_Success; Server.SendPacket.PushData <State>(stState); Server.fn_PushSendQueue(Server.SendPacket); }
/*********************************************************************************************** * Thread Send */ public void ThreadSend() { int commCntr = 0; int commErrCntr = 0; int commErr2Cntr = 0; while (true) { try { // if (this.IsOpen) { if (commState == COMM_STATE.IDLE) { commState = COMM_STATE.SEND;// 转入发送状态 commErrCntr = 0; commErr2Cntr = 0; Thread.Sleep(200); // 在一次成功发送以后,需要对发送数据进行清零。 //SendCmdReset();// 对命令进行清除,避免重复发送同一命令 } else if (commState == COMM_STATE.SEND) { commState = COMM_STATE.SENDING; SendDataEncode(); // 数据编码 this.Write(sendBuff, 0, SendDataNum); // 发送数据 commCntr = 0; commState = COMM_STATE.RECV;// 转入接收状态 } } } catch (Exception e1) { Console.WriteLine(e1.ToString()); } finally { } } }
private void _Play() { // in case a reset if (timerWorker == null) { if (engine.GameOn != 0) InitializeGame(); engine.GameOn++; GameTicks = 0; timerWorker = new Timer { Interval = 1000 / FRAMES_PER_SECOND, Tag = rand.Next() }; timerWorker.Tick += FrameTick; } // we're running CommTimerClose(); commState = COMM_STATE.RUNNING; mainWindow.UpdateMap(); mainWindow.UpdatePlayers(); mainWindow.UpdateMenu(); timerWorker.Start(); if (PlaySounds) trafficPlayer.PlayLooping(); }
/// <summary> /// Player is ready to start. /// </summary> /// <param name="player">The player. null if a join, non-null (maybe) if a re-join.</param> /// <param name="root">The XML message.</param> private void MsgPlayerReady(Player player, XElement root) { List<Point> path; List<Passenger> pickup; ReadMessage(player, root, out path, out pickup); GameEngine.RemoteMessages.Enqueue(new Engine.AiMessage(player, path, pickup)); player.WaitingForReply = Player.COMM_MODE.RECEIVED_START; // if all ready (or all AI), we start if (engine.Players.All(pl => pl.WaitingForReply == Player.COMM_MODE.RECEIVED_START || pl.TcpGuid == null)) { if (commState == COMM_STATE.ACCEPTING_JOINS || commState == COMM_STATE.ACCEPTING_SETUP) commState = COMM_STATE.READY_TO_START; CommTimerClose(); mainWindow.SetupGame(); // test mode? If so we're good and so exit with code 0. if ((!string.IsNullOrEmpty(TestUser)) && player.Name == TestUser) { tcpServer.SendMessage(player.TcpGuid, "<exit/>"); Thread.Sleep(100); Environment.Exit(0); } if (DebugStartMode || AutoRunNumGames != 0) Play(); } }
private void InitializeGame() { commState = COMM_STATE.ACCEPTING_SETUP; // reset engine & players engine.Initialize(); // if all ready (or all AI), we start if (engine.Players.All(pl => pl.WaitingForReply == Player.COMM_MODE.RECEIVED_START || pl.TcpGuid == null)) commState = COMM_STATE.READY_TO_START; else CommTimerStart(); mainWindow.SetupGame(); }
private void CommTimeout(object sender, EventArgs e) { CommTimerClose(); commState = COMM_STATE.READY_TO_START; mainWindow.CtrlForInvoke.BeginInvoke((MethodInvoker) (() => mainWindow.SetupGame())); }
/// <summary> /// End the game. /// </summary> public void Stop() { FullSpeed = false; commState = COMM_STATE.GAME_OVER; CommTimerClose(); if (timerWorker != null) { timerWorker.Stop(); timerWorker.Dispose(); timerWorker = null; } if (PlaySounds) trafficPlayer.Stop(); commState = COMM_STATE.GAME_OVER; // update windows mainWindow.UpdateMap(); mainWindow.UpdateMenu(); }
public void Step() { // stop the ticker if (timerWorker != null) timerWorker.Stop(); else { // new game - we create the timer as that IDs if we're starting a new game. But we don't start it if (engine.GameOn != 0) InitializeGame(); engine.GameOn++; GameTicks = 0; timerWorker = new Timer { Interval = 1000 / FRAMES_PER_SECOND, Tag = rand.Next() }; timerWorker.Tick += FrameTick; CommTimerClose(); commState = COMM_STATE.PAUSED; } // run one tick commState = COMM_STATE.STEP; FrameTick(null, null); commState = COMM_STATE.PAUSED; // update windows mainWindow.UpdateMap(); mainWindow.UpdateMenu(); }
//--------------------------------------------------------------------------- public void fn_SetCommState(COMM_STATE state) { //curState = State(COMM_STATE.DISCONNECTED, CONTROL_STATE.OFFLINE, PORT_STATE.LOAD_READY, PROCESS_STATE.IDLE, ALARM_STATE.CLEAR); curState.CommunicationState = (int)state; }
/// <summary> /// Start or continue (from pause) the game. /// </summary> public void Play() { if (AutoRunNumGames != 0) FullSpeed = true; if ((commState == COMM_STATE.PAUSED) && (timerWorker != null)) { commState = COMM_STATE.RUNNING; timerWorker.Start(); if (PlaySounds) trafficPlayer.PlayLooping(); } else _Play(); }
public void PauseAtEndOfTurn() { commState = COMM_STATE.PAUSED; timerWorker.Stop(); if (PlaySounds) trafficPlayer.Stop(); // update windows mainWindow.UpdateMap(); mainWindow.UpdateMenu(); }
/// <summary> /// Create the engine. /// </summary> /// <param name="mainWindow">The main window.</param> public Framework(IUserDisplay mainWindow) { PlaySounds = true; MovesPerSecond = TileMovement.UNITS_PER_TILE * 4; this.mainWindow = mainWindow; string[] args = Environment.GetCommandLineArgs(); if (args.Length >= 3 && args[1] == "/t") TestUser = args[2].Trim(); if (args.Length > 4 && (args[1] == "/a")) { AutoRunNumGames = int.Parse(args[2]); AutoRunFilename = Path.GetFullPath(args[3]); AutoRunUsers = new List<string>(); for (int ind=4; ind<args.Length; ind++) AutoRunUsers.Add(args[ind]); } // get directory with maps string path = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath) ?? ""; if (path.ToLower().EndsWith("bin\\debug")) path = path.Substring(0, path.Length - 9); else if (path.ToLower().EndsWith("bin\\release")) path = path.Substring(0, path.Length - 12); // get maps ConfigurationManager.RefreshSection("Windwardopolis"); NameValueCollection coll = (NameValueCollection)ConfigurationManager.GetSection("Windwardopolis"); if (string.IsNullOrEmpty(coll["maps"])) { commState = COMM_STATE.NO_MAP; MessageBox.Show("There is no maps setting in the config file\nThe game will exit.", "Windwardopolis", MessageBoxButtons.OK); Environment.Exit(1); } string[] maps = coll["maps"].Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (string filename in maps.Select(mapOn => Path.Combine(path, mapOn)).Where(File.Exists)) mapFilenames.Add(filename); if (mapFilenames.Count == 0) { commState = COMM_STATE.NO_MAP; MessageBox.Show("The specified maps do not exist\nThe game will exit.", "Windwardopolis", MessageBoxButtons.OK); Environment.Exit(1); } // traffic noises using (Stream wavFile = Assembly.GetExecutingAssembly().GetManifestResourceStream("Windwardopolis.Resources.Town_Traffic_01.wav")) { trafficPlayer = new SoundPlayer(wavFile); trafficPlayer.Load(); } using (Stream wavFile = Assembly.GetExecutingAssembly().GetManifestResourceStream("Windwardopolis.Resources.Crowding Cheering Charge-SoundBible.com-284606164.wav")) { winPlayer = new SoundPlayer(wavFile); winPlayer.Load(); } engine = new Engine(this, mapFilenames[rand.Next(mapFilenames.Count())]); mainWindow.NewMap(); mainWindow.UpdateMap(); tcpServer.Start(this); }
/*********************************************************************************************** * Thread Send */ private void ThreadSend() { int commCntr = 0; int commErrCntr = 0; int commErr2Cntr = 0; while (true) { try { // if (this.IsOpen) { if (commState == COMM_STATE.IDLE) { commState = COMM_STATE.SEND;// 转入发送状态 commErrCntr = 0; commErr2Cntr = 0; // 在一次成功发送以后,需要对发送数据进行清零。 SendCmdReset();// 对命令进行清除,避免重复发送同一命令 //Thread.Sleep(50); } else if (commState == COMM_STATE.SEND) { commState = COMM_STATE.SENDING; SendDataEncode(); // 数据编码 this.Write(sendBuff, 0, SendDataNum); // 发送数据 commCntr = 0; commState = COMM_STATE.RECV;// 转入接收状态 } else { Thread.Sleep(10);// 休眠 10ms // 处于通信接收状态 COMM_STATE.RECV; if (commState == COMM_STATE.RECVING) { commCntr++; if (commCntr > 10) { // 这种情况一般是接收到了数据,但是接收的数据由错误。此时应该立刻重新发送数据 // 如果 5 * 10ms = 50ms 没有接收到数据 commState = COMM_STATE.SEND; // 重新发送 commErrCntr++; } /*if (commErrCntr == 50)// 只执行一次 * { * //SendCmdReset();// 通信线断了,那么这时候清除所有命令,避免因为长时间通信断后,恢复,机器突然动作。 * }*/ } if (commState == COMM_STATE.RECV) { commErr2Cntr++; if (commErr2Cntr % 100 == 0) // 固定1秒发送一次数据 { // 这种情况一般是发送了数据,但是过了1秒还没有接收到数据,那么重发该数据。 commState = COMM_STATE.SEND; // 重新发送 } else if (commErr2Cntr > 1000) // 1000*10ms = 10秒钟 { // 这种情况一般是重发了N次以后,依然还是收不到数据,说明通信彻底断了,重置数据。 commErr2Cntr = 0; SendCmdReset(); // 通信线断了,那么这时候清除所有命令,避免因为长时间通信断后,恢复,机器突然动作。 } } } } } catch (Exception e1) { Console.WriteLine(e1.ToString()); } finally { } } }
private void RecvDataDecode(Byte inData) { // 逐个字节进行解析 switch (recvStatus) { case RECV_STATUS.STATE_IDLE: if (inData == 0xAA) { recvStatus = RECV_STATUS.STATE_GOT_HEAD1; // 获得了 HEAD1 commState = COMM_STATE.RECVING; // 状态转变为正在接收 } break; case RECV_STATUS.STATE_GOT_HEAD1: if (inData == 0x55) { recvStatus = RECV_STATUS.STATE_GOT_HEAD2; // 获得了 HEAD2 RecvDataIndex = 0; } else { recvStatus = RECV_STATUS.STATE_IDLE; // 错误,返回初始状态 } break; case RECV_STATUS.STATE_GOT_HEAD2: recvBuff[RecvDataIndex + 2] = inData; RecvDataIndex++; if (RecvDataIndex >= PayloadDataNum) { recvStatus = RECV_STATUS.STATE_GOT_DATA; // 获得了 数据 RecvDataIndex = 0; } break; case RECV_STATUS.STATE_GOT_DATA: if (inData == 0xA5) { recvStatus = RECV_STATUS.STATE_GOT_END1; // 获得了 END1 } else { recvStatus = RECV_STATUS.STATE_IDLE; // 错误,返回初始状态 } break; case RECV_STATUS.STATE_GOT_END1: if (inData == 0x5A) { recvStatus = RECV_STATUS.STATE_IDLE; // 重新恢复到IDLE状态 // 成功获得了所有数据 //recvBuff[0] commState = COMM_STATE.IDLE; // 成功收到数据,切换为通信空闲状态 // GenericOp.xPos = 5 * BitConverter.ToInt16(recvBuff, 4); // 转化为 mm 单位 GenericOp.zPos = 5 * BitConverter.ToInt16(recvBuff, 6); // 转化为 mm 单位 GenericOp.xPos_servo = -5 * BitConverter.ToInt16(recvBuff, 8); // 转化为 mm 单位 GenericOp.zPos_servo = -5 * BitConverter.ToInt16(recvBuff, 10); // 转化为 mm 单位 gtryState = BitConverter.ToUInt32(recvBuff, 12); // 龙门机构状态 GenericOp.weight = (int)BitConverter.ToInt16(recvBuff, 16); // 载重量 // 龙门机构的急停状态的获取 if (SerialWireless.GetGtryState(SerialWireless.GTRY_STATE_ESTOP_STATE)) { gtry_estop_state_cntr++; if (gtry_estop_state_cntr % 20 == 0) // 每20包数据,检查一下PLC的急停状态 { GenericOp.EStop_Soft = true; // 根据 龙门急停状态 给 软急停标识 赋值,只赋值10次就不重复赋值。为了避免反复被刷新。 } } else { //gtry_estop_state_cntr = 0; } // 龙门原点回归请求 if (SerialWireless.GetGtryState(SerialWireless.GTRY_STATE_REQUEST_ZRN)) { gtry_request_zrn_cntr++; if (gtry_request_zrn_cntr > 5) { gtry_request_zrn_cntr = 5; GenericOp.RequestZRN = true; // 请求原点回归标识 置位 } } else { gtry_request_zrn_cntr = 0; GenericOp.RequestZRN = false; } } else { recvStatus = RECV_STATUS.STATE_IDLE; // 错误,返回初始状态 } break; } }
public void RestartJoins() { acceptMessages = false; foreach (Player player in engine.Players.Where(player => player.TcpGuid != null)) tcpServer.SendMessage(player.TcpGuid, "<exit/>"); Thread.Sleep(100); foreach (Player plyr in engine.Players) tcpServer.CloseConnection(plyr.TcpGuid); foreach (Player plyr in engine.Players) plyr.Dispose(); engine.Players.Clear(); commState = COMM_STATE.ACCEPTING_JOINS; acceptMessages = true; const string msg = "Clear players, re-open for joins"; log.Info(msg); mainWindow.StatusMessage(msg); mainWindow.ResetPlayers(); mainWindow.UpdateMenu(); }
private const int PayloadDataNum = RecvDataNum - 4; // 除去 AA 55 A5 5A头4字节后的有效数据长度。 private void RecvDataDecode(Byte inData) { // 逐个字节进行解析 switch (recvStatus) { case RECV_STATUS.STATE_IDLE: if (inData == 0xAA) { recvStatus = RECV_STATUS.STATE_GOT_HEAD1; // 获得了 HEAD1 commState = COMM_STATE.RECVING; // 状态转变为正在接收 } break; case RECV_STATUS.STATE_GOT_HEAD1: if (inData == 0x55) { recvStatus = RECV_STATUS.STATE_GOT_HEAD2; // 获得了 HEAD2 RecvDataIndex = 0; } else { recvStatus = RECV_STATUS.STATE_IDLE; // 错误,返回初始状态 } break; case RECV_STATUS.STATE_GOT_HEAD2: recvBuff[RecvDataIndex + 2] = inData; RecvDataIndex++; if (RecvDataIndex >= PayloadDataNum) { recvStatus = RECV_STATUS.STATE_GOT_DATA; // 获得了 数据 RecvDataIndex = 0; } break; case RECV_STATUS.STATE_GOT_DATA: if (inData == 0xA5) { recvStatus = RECV_STATUS.STATE_GOT_END1; // 获得了 END1 } else { recvStatus = RECV_STATUS.STATE_IDLE; // 错误,返回初始状态 } break; case RECV_STATUS.STATE_GOT_END1: if (inData == 0x5A) { recvStatus = RECV_STATUS.STATE_IDLE; // 重新恢复到IDLE状态 // 成功获得了所有数据 //recvBuff[0] commState = COMM_STATE.RECV; // 成功收到数据,切换为通信接受状态 //获取水槽温度 GenericOp.temperature1 = BitConverter.ToInt16(recvBuff, 2) / 10; // 1号水槽温度 GenericOp.temperature2 = BitConverter.ToInt16(recvBuff, 4) / 10; // 2号水槽温度 GenericOp.temperature3 = BitConverter.ToInt16(recvBuff, 6) / 10; // 3号水槽温度 GenericOp.temperature41 = BitConverter.ToInt16(recvBuff, 8) / 10; //4号炉子上温区温度 GenericOp.temperature42 = BitConverter.ToInt16(recvBuff, 10) / 10; //4号炉子下温区温度 GenericOp.temperature51 = BitConverter.ToInt16(recvBuff, 12) / 10; //5号炉子上温区温度 GenericOp.temperature52 = BitConverter.ToInt16(recvBuff, 14) / 10; //5号炉子下温区温度 GenericOp.temperature61 = BitConverter.ToInt16(recvBuff, 16) / 10; //6号炉子上温区温度 GenericOp.temperature62 = BitConverter.ToInt16(recvBuff, 18) / 10; //6号炉子下温区温度 GenericOp.temperature71 = BitConverter.ToInt16(recvBuff, 20) / 10; //7号炉子上温区温度 GenericOp.temperature72 = BitConverter.ToInt16(recvBuff, 22) / 10; //7号炉子上温区温度 GenericOp.temperature111 = BitConverter.ToInt16(recvBuff, 24) / 10; //11号炉子上温区温度 GenericOp.temperature112 = BitConverter.ToInt16(recvBuff, 26) / 10; //11号炉子下温区温度 GenericOp.temperature121 = BitConverter.ToInt16(recvBuff, 28) / 10; //12号炉子上温区温度 GenericOp.temperature122 = BitConverter.ToInt16(recvBuff, 30) / 10; //12号炉子下温区温度 GenericOp.temperature131 = BitConverter.ToInt16(recvBuff, 32) / 10; //13号炉子温度 } else { recvStatus = RECV_STATUS.STATE_IDLE; // 错误,返回初始状态 } break; } }
private void RecvDataDecode(Byte inData) { // 逐个字节进行解析 switch (recvStatus) { case RECV_STATUS.STATE_IDLE: if (inData == 0xAA) { recvStatus = RECV_STATUS.STATE_GOT_HEAD1; // 获得了 HEAD1 commState = COMM_STATE.RECVING; // 状态转变为正在接收 } break; case RECV_STATUS.STATE_GOT_HEAD1: if (inData == 0x55) { recvStatus = RECV_STATUS.STATE_GOT_HEAD2; // 获得了 HEAD2 RecvDataIndex = 0; } else { recvStatus = RECV_STATUS.STATE_IDLE; // 错误,返回初始状态 } break; case RECV_STATUS.STATE_GOT_HEAD2: recvBuff[RecvDataIndex + 2] = inData; RecvDataIndex++; if (RecvDataIndex >= PayloadDataNum) { recvStatus = RECV_STATUS.STATE_GOT_DATA; // 获得了 数据 RecvDataIndex = 0; } break; case RECV_STATUS.STATE_GOT_DATA: if (inData == 0xA5) { recvStatus = RECV_STATUS.STATE_GOT_END1; // 获得了 END1 } else { recvStatus = RECV_STATUS.STATE_IDLE; // 错误,返回初始状态 } break; case RECV_STATUS.STATE_GOT_END1: if (inData == 0x5A) { recvStatus = RECV_STATUS.STATE_IDLE; // 重新恢复到IDLE状态 // 成功获得了所有数据 //recvBuff[0] commState = COMM_STATE.IDLE; // 成功收到数据,切换为通信空闲状态 // // X00 - X15 stoveLidState[0] = (STOVE_LID_STATE)(recvBuff[2] & 0x3); // 1#炉盖 X0 - X01 stoveLidState[1] = (STOVE_LID_STATE)((recvBuff[2] >> 2) & 0x3); // 2#炉盖 stoveLidState[2] = (STOVE_LID_STATE)((recvBuff[2] >> 4) & 0x3); // 3#炉盖 stoveLidState[3] = (STOVE_LID_STATE)((recvBuff[2] >> 6) & 0x3); // 4#炉盖 stoveLidState[4] = (STOVE_LID_STATE)(recvBuff[3] & 0x3); // 5#炉盖 stoveLidState[5] = (STOVE_LID_STATE)((recvBuff[3] >> 2) & 0x3); // 6#炉盖 stoveLidState[6] = (STOVE_LID_STATE)((recvBuff[3] >> 4) & 0x3); // 7#炉盖 stoveLidState[7] = (STOVE_LID_STATE)(recvBuff[4] & 0x3); //后门 stoveLidState[8] = (STOVE_LID_STATE)((recvBuff[4] >> 2) & 0x3); //前门 // X30 自动 X31手动 //if ((recvBuff[5] & 0x01) == 0) //{ //automode_change_cntr_manual = 0; /* * automode_change_cntr_auto++; * if (automode_change_cntr_auto < 10) * { * GenericOp.AutoMode = true;// 自动模式 * } * else * { * automode_change_cntr_auto = 10; * }*/ // } // else // { //automode_change_cntr_auto = 0; // automode_change_cntr_manual++; // if (automode_change_cntr_manual < 10) // { // GenericOp.AutoMode = false;// 手动模式 // } // else // { // automode_change_cntr_manual = 10; // } // } // 手动控制柜用于控制龙门的前进、后退、上下、抓放,对应PLC的X41 - X46 GenericOp.manual_gtry_action = GenericOp.GTRY_ACTION_TYPE.NONE; // 初始为不做任何动作 //if ((recvBuff[6] & 0x02) !=0) GenericOp.manual_gtry_action = GenericOp.GTRY_ACTION_TYPE.FORWARD; // X41 //else if ((recvBuff[6] & 0x04) !=0) GenericOp.manual_gtry_action = GenericOp.GTRY_ACTION_TYPE.BAKWARD; // X42 //else if ((recvBuff[6] & 0x08) != 0) GenericOp.manual_gtry_action = GenericOp.GTRY_ACTION_TYPE.UP; // X43 //else if ((recvBuff[6] & 0x10) != 0) GenericOp.manual_gtry_action = GenericOp.GTRY_ACTION_TYPE.DOWN;// X44 //else if ((recvBuff[6] & 0x20) != 0) GenericOp.manual_gtry_action = GenericOp.GTRY_ACTION_TYPE.CLAMP;// X45 //else if ((recvBuff[6] & 0x40) != 0) GenericOp.manual_gtry_action = GenericOp.GTRY_ACTION_TYPE.CLAMP_RELAX;// X46 //GenericOp.EStop_Manual = ((recvBuff[6] >> 7) == 0);// X47 急停信号 } else { recvStatus = RECV_STATUS.STATE_IDLE; // 错误,返回初始状态 } break; } }