DESKTOP-Kang 5 vuotta sitten
vanhempi
commit
c70593b8ed

+ 1 - 1
Dev/OHV/OHV.Module.Monitoring/Interactivity/InOutIOViewModel.cs

@@ -256,7 +256,7 @@ namespace OHV.Module.Monitoring.Interactivity
                     break;
             }
 
-            this.IO.TestEqueue();
+            //this.IO.TestEqueue();
 
         }
 

+ 1 - 1
Dev/OHV/VehicleControlSystem/ControlLayer/Clamp.cs

@@ -549,7 +549,7 @@ namespace VehicleControlSystem.ControlLayer
 
         public int JogMove( string axisName, E_JogMoveDir dir, int velocity )
         {
-            logger.D( $"JogMove - Axis[{axisName}] / Dir[{dir}] / vel[{velocity}]" );
+            //logger.D( $"JogMove - Axis[{axisName}] / Dir[{dir}] / vel[{velocity}]" );
 
             var axis = this.axes.Where( x => x.Config.AxisName.Equals( axisName ) ).Single();
             return axis.JogMove( dir, velocity );

+ 7 - 1
Dev/OHV/VehicleControlSystem/ControlLayer/IO/IIO.cs

@@ -8,7 +8,13 @@ namespace VehicleControlSystem.ControlLayer.IO
 {
     public interface IIO
     {
-
+        event Dlg OnContd;
+        event Dlg OnDiscontd;
+        event Dlg OnFirstColtd;
+        event DlgChangedIO OnChangedIO;
+        event DlgWriteIO OnWriteIO;
+        event DlgLog OnLog;
+ 
         //int GetIOTable( SIOTABLE* Input, SIOTABLE* Output )=0;
 
         int LoadIOMap(string strFileName);

+ 2 - 1
Dev/OHV/VehicleControlSystem/ControlLayer/MQ/ZmqManager.cs

@@ -1166,7 +1166,8 @@ namespace VehicleControlSystem.ControlLayer.MQ
                 v = "1";
             else
                 v = "-1";
-            logger.E($"Jog Dir : <True +, False -> {isForward}");
+
+            //logger.E($"Jog Dir : <True +, False -> {isForward}");
 
             var rll = this.RequestDrive("setm", $"4091/{v}");
             if (rll.Count == 0)

+ 88 - 0
Dev/OHV/VehicleControlSystem/ControlLayer/ObstacleDetecter.cs

@@ -0,0 +1,88 @@
+using GSG.NET.Logging;
+using GSG.NET.Utils;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace VehicleControlSystem.ControlLayer
+{
+    public class ObstacleDetecter
+    {
+        Logger logger = Logger.GetLogger(typeof(ObstacleDetecter));
+
+        List<string> obstacleBitList = new List<string>();
+        IO.IIO io = null;
+
+        public int CurrentPattern { get; set; }
+
+        public ObstacleDetecter(IO.IIO iO)
+        {
+            this.io = iO;
+            this.io.OnContd += Io_OnContd;
+        }
+
+        private void Io_OnContd(string ID)
+        {
+            this.CurrentPattern = GetObstacleDetectPattern();
+        }
+
+        public void Init()
+        {
+            this.obstacleBitList.AddRange(new string[]
+            {
+                "OUT_OBSTRUCTION_PATTERN_00",
+                "OUT_OBSTRUCTION_PATTERN_01",
+                "OUT_OBSTRUCTION_PATTERN_02",
+                "OUT_OBSTRUCTION_PATTERN_03",
+                "OUT_OBSTRUCTION_PATTERN_04",
+            });
+        }
+
+        int GetObstacleDetectPattern()
+        {
+            int bitIndex = 0;
+
+            BitArray bitArray = new BitArray(this.obstacleBitList.Count);
+
+            this.obstacleBitList.ForEach(b =>
+            {
+                if (this.io.IsOn(b, false))
+                    bitArray.Set(bitIndex, false);
+                else
+                    bitArray.Set(bitIndex, true);
+                bitIndex++;
+            });
+
+            return BitUtils.ChgInt32(bitArray);
+        }
+
+        /// <summary>
+        /// if no is zero, Laser Off
+        /// bit Off, On, On, On,On Area1
+        /// </summary>
+        /// <param name="no"> 0 == Off Laser</param>
+        /// <returns></returns>
+        public bool SetObstacleDetectPattern(int no)
+        {
+            var bitArray = BitUtils.ChgBitArray(no);
+
+            int bitIndex = 0;
+            this.obstacleBitList.ForEach(b =>
+            {
+                if (bitArray[bitIndex])
+                    this.io.OutputOff(b);
+                else
+                    this.io.OutputOn(b);
+                bitIndex++;
+            });
+
+            this.CurrentPattern = no;
+
+            return true;
+        }
+
+    }
+}

+ 23 - 2
Dev/OHV/VehicleControlSystem/ControlLayer/Serial/BatteryTabos/Peak/Peak.cs

@@ -113,6 +113,7 @@ namespace VehicleControlSystem.ControlLayer.Serial.BatteryTabos
                 this.IsConnected = this.GetStatus();
         }
 
+        DateTime occurDisconnectTime;
         bool isConnected = false;
         public bool IsConnected
         {
@@ -124,12 +125,14 @@ namespace VehicleControlSystem.ControlLayer.Serial.BatteryTabos
 
                 if (value)
                     this.manager._OnConnected();
-                else
-                    this.manager._OnDisconnected();
+                else { }
+                //! Pooling Thread 내부로 이동 1분이후 알람 발생을 위해.
+                    //this.manager._OnDisconnected();
             }
         }
 
 
+        bool isOccurDisconnect = false;
         public void _ThreadPoolingReceiveData()
         {
             while (!this.manager.cancel.Canceled)
@@ -140,9 +143,27 @@ namespace VehicleControlSystem.ControlLayer.Serial.BatteryTabos
                     {
                         Thread.Sleep(3000);
                         this.TryToConnect();
+
+                        //! 정해진 시간동안 Disconnect 상태가 유지 되면 상태 보고.
+                        if (!this.isOccurDisconnect)
+                        {
+                            this.occurDisconnectTime = DateTime.Now;
+                            this.isOccurDisconnect = true;
+                        }
+
+                        if (DateTime.Now.Subtract(this.occurDisconnectTime).TotalMinutes > 1)
+                        {
+                            if (this.isOccurDisconnect)
+                            {
+                                this.manager._OnDisconnected();
+                                this.occurDisconnectTime = DateTime.Now;
+                            }
+                        }
                         continue;
                     }
 
+                    this.isOccurDisconnect = false;
+
                     object o = this.qqW.Dequeue();
 
                     if (o is PollingObject) //Scan 을 주기적 으로 진행.

+ 19 - 134
Dev/OHV/VehicleControlSystem/ControlLayer/Vehicle.cs

@@ -42,6 +42,7 @@ namespace VehicleControlSystem.ControlLayer
         public HostManager HostManager { get; set; }
         public SqliteManager Sqlite { get; set; }
         public AutoManager AutoManager { get; set; }
+        public ObstacleDetecter ObstacleDetecter { get; set; }
     }
 
     /// <summary>
@@ -639,7 +640,7 @@ namespace VehicleControlSystem.ControlLayer
                                 ControlKind = ObstacleControlEventArgs.eControlKind.INFO,
                                 Drive = this.ObstacleDrive,
                                 Curve = this.ObstacleCurve,
-                                Current = this.GetObstacleDetectPattern(),
+                                Current = this.refObjects.ObstacleDetecter.CurrentPattern,
                                 ObstacleState = this.ObstacleStateProperty.ToString()
                             };
                             this.ObstacleControlEventPublish(msg);
@@ -1059,7 +1060,7 @@ namespace VehicleControlSystem.ControlLayer
         {
             //2020.08.18.Kang. 상위 연결이 안되어 있으면 SubCmd 실행을 안하고 대기함.
             //if (!this.refObjects.HostManager.IsConnected)
-                //return;
+            //return;
 
             var subCmd = this.refObjects.Sqlite.SubCmdDAL.GetAll().FirstOrDefault();
             if (subCmd == null) return;
@@ -1266,17 +1267,10 @@ namespace VehicleControlSystem.ControlLayer
                 Thread.Sleep(moveReadyBuzzerTime);
 
                 this.VehicleStateProperty = eVehicleState.Move;
-
-                //this.ObstaclePatternChange(this.refObjects.ZmqManager.SegmentID);
             }
 
             this.OnMoving?.Invoke();
 
-            //이전에 있던 작업들 종료 및 삭제
-            //this.taskMoveCancel.Cancel();
-            //this.taskMoveCancel.WaitAll();
-            //this.taskMoveCancel.Add(CheckCrossPoint());
-
             this.VehicleStateProperty = eVehicleState.Move;
 
             int result = this.refObjects.Drive.MoveToPoint(sub, 100);
@@ -1299,7 +1293,7 @@ namespace VehicleControlSystem.ControlLayer
 
                 //2020.08.13. Kang. 주행이 끝나면 장애물감지센서의 패턴을 특정 패턴으로 변경(나성권B 요청)
                 var pattern = Convert.ToInt32(this.refObjects.Sqlite.ConfigDal.GetById(ConstString.StandbyPattern).Value);
-                this.ChgObstacleDetectPattern(pattern);
+                this.refObjects.ObstacleDetecter.SetObstacleDetectPattern(pattern);
             }
 
             return result;
@@ -1313,17 +1307,19 @@ namespace VehicleControlSystem.ControlLayer
 
             while (true)
             {
-                LockUtils.Wait(50); //2020.07.29. Kang 빠르게 확인 할 필요가 없으므로 5ms -> 50ms 로 변경
+                LockUtils.Wait(40); //2020.07.29. Kang 빠르게 확인 할 필요가 없으므로 5ms -> 50ms 로 변경
 
                 if (SwUtils.Gt(st, waitTime))
                 {
                     logger.D("Wait4MoveDone Time Over");
+                    this.refObjects.Drive.Stop();
                     return 39;
                 }
 
                 //이동중 메인 명력이 없어진다면 정지 후 
                 if (null == this.refObjects.Sqlite.CommandDAL.GetById(this.CurrentSubCommand.CmdID))
                 {
+                    LockUtils.Wait(10);
                     logger.D("[Wait Move Done] - 메인 명령 사라짐");
                     var cmd = this.refObjects.Sqlite.CommandDAL.GetAll();
                     if (cmd == null)
@@ -1392,17 +1388,8 @@ namespace VehicleControlSystem.ControlLayer
                 return false; //Alarm
             }
 
-            //var route = sql.RouteDal.GetRoute( sub.TargetID );
-            //if ( !CorrectPosition( route, this.CurrentPosition ) )
-            //{
-            //    this.OccurVehicleAlarm( 20 );
-            //    return false; //Alarm
-            //}
-
             int result = 0;
-
-            //result = this.PIOAndLoad(sub.TargetID);
-            result = this.TestLoad();
+            result = this.PIOAndLoad(sub.TargetID);
             if (result != 0)
             {
                 this.OccurVehicleAlarm(result);
@@ -1420,8 +1407,6 @@ namespace VehicleControlSystem.ControlLayer
                 this.refObjects.Sqlite.CommandDAL.Update(cmd);
             }
 
-            //LockUtils.Wait( 1000 );
-            //this.OnLoadComplete?.Invoke(); //일찍 주면 다음 명령을 500ms 안에 주는 현상 있음. 그러니까 천천히 주자 
             this.VehicleStateProperty = eVehicleState.Idle;
 
             return true;
@@ -1438,26 +1423,10 @@ namespace VehicleControlSystem.ControlLayer
                 return false; //Alarm
             }
 
-            //var route = sql.RouteDal.GetRoute( sub.TargetID );
-
-            //if ( !CorrectPosition( route, this.CurrentPosition ) )
-            //{
-            //    this.OccurVehicleAlarm( 21 );
-            //    return false; //Alarm
-            //}
-
-            //PIO 내부로 이동.
-            //int result = this.clamp.Unlock_Sync();
-            //if ( result != 0 )
-            //{
-            //    this.OccurVehicleAlarm( result );
-            //    return false;
-            //}
             this.VehicleStateProperty = eVehicleState.Unload;
 
             int result = 0;
-            //result = this.PIOAndUnload(sub.TargetID);
-            result = this.TestUnload();
+            result = this.PIOAndUnload(sub.TargetID);
             if (result != 0)
             {
                 this.refObjects.IO.OutputOn("OUT_PIO_SENSOR_ONOFF");
@@ -1476,8 +1445,6 @@ namespace VehicleControlSystem.ControlLayer
                 this.refObjects.Sqlite.CommandDAL.Update(cmd);
             }
 
-            //LockUtils.Wait( 1000 );
-            //this.OnUnloadComplete?.Invoke(); //일찍 주면 다음 명령을 500ms 안에 주는 현상 있음. 그러니까 천천히 주자 
             this.VehicleStateProperty = eVehicleState.Idle;
 
             return true;
@@ -2392,7 +2359,7 @@ namespace VehicleControlSystem.ControlLayer
             this.OnPIOStart?.Invoke(false);
 
             Thread.Sleep(1000);
-            
+
             int result = this.refObjects.Clamp.Unlock_Sync();
             if (result != 0)
                 return result;
@@ -2520,7 +2487,7 @@ namespace VehicleControlSystem.ControlLayer
 
             var obstacle = RouteManager.Instance.Obstacles.Where(o => o.segmentID == v).Single();
 
-            this.ChgObstacleDetectPattern(obstacle.fieldset);
+            this.refObjects.ObstacleDetecter.SetObstacleDetectPattern(obstacle.fieldset);
             logger.D($"[Obstacle Pattern Chg] - {obstacle.fieldset}");
         }
 
@@ -2542,56 +2509,13 @@ namespace VehicleControlSystem.ControlLayer
             return true;
         }
 
-        /// <summary>
-        /// if no is zero, Laser Off
-        /// bit Off, On, On, On,On Area1
-        /// </summary>
-        /// <param name="no"> 0 == Off Laser</param>
-        /// <returns></returns>
-        public bool ChgObstacleDetectPattern(int no)
-        {
-            var bitArray = BitUtils.ChgBitArray(no);
-
-            int bitIndex = 0;
-            this.obstacleBitList.ForEach(b =>
-            {
-                if (bitArray[bitIndex])
-                    this.refObjects.IO.OutputOff(b);
-                else
-                    this.refObjects.IO.OutputOn(b);
-                bitIndex++;
-            });
-
-            ObstaclePattern = no;
-
-            return true;
-        }
-
-        public int GetObstacleDetectPattern()
-        {
-            int bitIndex = 0;
-
-            BitArray bitArray = new BitArray(this.obstacleBitList.Count);
-
-            this.obstacleBitList.ForEach(b =>
-            {
-                if (this.refObjects.IO.IsOn(b, false))
-                    bitArray.Set(bitIndex, false);
-                else
-                    bitArray.Set(bitIndex, true);
-                bitIndex++;
-            });
-
-            return BitUtils.ChgInt32(bitArray);
-        }
-
         /// <summary>
         /// Vehicle 이동 및 동작 중 Alarm 발생 시 처리
         /// </summary>
         /// <param name="alarmID"></param>
         public void OccurVehicleAlarm(int alarmID)
         {
-            logger.D($"[{this.GetType().Name}] - Occur Alarm Method- {alarmID}");
+            //logger.D($"[{this.GetType().Name}] - Occur Alarm Method- {alarmID}");
 
             var alarm = refObjects.Alarms.FirstOrDefault(x => x.AlarmId == alarmID);
             if (alarm != null)
@@ -2600,6 +2524,7 @@ namespace VehicleControlSystem.ControlLayer
                 {
                     this.MachineMode = eMachineMode.LocalMode;
                     this.VehicleStateProperty = eVehicleState.Abnormal;
+                    this.refObjects.Drive.Stop();
                     this.ConveyorOff();
                 }
             }
@@ -2612,12 +2537,12 @@ namespace VehicleControlSystem.ControlLayer
             if (state == ObstacleControlEventArgs.eControlKind.DRIVE)
             {
                 this.ObstacleDrive = value;
-                ChgObstacleDetectPattern(this.ObstacleDrive);
+                this.refObjects.ObstacleDetecter.SetObstacleDetectPattern(this.ObstacleDrive);
             }
             else if (state == ObstacleControlEventArgs.eControlKind.CURVE)
             {
                 this.ObstacleCurve = value;
-                ChgObstacleDetectPattern(this.ObstacleCurve);
+                this.refObjects.ObstacleDetecter.SetObstacleDetectPattern(this.ObstacleDrive);
             }
             else
                 return;
@@ -2626,7 +2551,7 @@ namespace VehicleControlSystem.ControlLayer
         public eSteeringState GetESteeringState() => this.refObjects.Steering.GetSteeringState();
         #endregion
 
-        #region Event Subscribe 
+        #region Event Subscribe
         private void BMUManager_OnDisconnect(string obj)
         {
             this.BatteryIsConnect = false;
@@ -2636,7 +2561,6 @@ namespace VehicleControlSystem.ControlLayer
         private void BMUManager_OnConnect(string obj)
         {
             this.BatteryIsConnect = true;
-            //ReqCurrentPos();
         }
 
         private void BMUManager_OnFirstColtd(List<ReceivedData> obj)
@@ -2702,7 +2626,7 @@ namespace VehicleControlSystem.ControlLayer
             //! 자동 모드 외의 모든 경우에 패턴을 30번으로 고정.
             if (obj == eOperatationMode.AutoMode) return;
 
-            this.ChgObstacleDetectPattern(30);
+            this.refObjects.ObstacleDetecter.SetObstacleDetectPattern(30);
             logger.D($"[Obstacle Pattern Chg] - Reason Auto Mode Changed {30}");
         }
 
@@ -2720,7 +2644,7 @@ namespace VehicleControlSystem.ControlLayer
                             return;
 
                         var v = CastTo<int>.From<object>(newValue);
-                        this.ChgObstacleDetectPattern(v);
+                        this.refObjects.ObstacleDetecter.SetObstacleDetectPattern(v);
                         logger.D($"[Obstacle Pattern Chg] - {v}");
                     }
                     break;
@@ -2811,45 +2735,6 @@ namespace VehicleControlSystem.ControlLayer
                     }
                     break;
 
-
-                //case "LinearSpeed":
-                //    {
-                //        this.LinearSpeed = CastTo<double>.From<object>(newValue);
-                //    }
-                //    break;
-                //case "CurveSpeed":
-                //    {
-                //        this.CurveSpeed = CastTo<double>.From<object>(newValue);
-                //    }
-                //    break;
-                //case "JogSPeed":
-                //    {
-                //        this.JogSPeed = CastTo<double>.From<object>(newValue);
-                //    }
-                //    break;
-                //case "AccelSpeed":
-                //    {
-                //        this.AccelSpeed = CastTo<double>.From<object>(newValue);
-                //    }
-                //    break;
-                //case "DecelSpeed":
-                //    {
-                //        this.DecelSpeed = CastTo<double>.From<object>(newValue);
-                //    }
-                //    break;
-                //case "CreepSpeed":
-                //    {
-                //        this.CreepSpeed = CastTo<double>.From<object>(newValue);
-                //    }
-                //    break;
-                //case "CreepDistance":
-                //    {
-                //        this.CreepDistance = CastTo<double>.From<object>(newValue);
-                //    }
-                //    break;
-                //case "IsCanStanbyLocation":
-                //    this.IsCanStanbyLocation = CastTo<bool>.From<object>(newValue);
-                //    break;
                 default:
                     break;
             }
@@ -2969,7 +2854,7 @@ namespace VehicleControlSystem.ControlLayer
             {
                 if (!isFirstConnected)
                 {
-                    this.ChgObstacleDetectPattern(30);
+                    this.refObjects.ObstacleDetecter.SetObstacleDetectPattern(30);
                     isFirstConnected = true;
                 }
             }

+ 7 - 0
Dev/OHV/VehicleControlSystem/Managers/AutoManager.cs

@@ -299,7 +299,14 @@ namespace VehicleControlSystem.Managers
 
                         case eAutoModeState.Stop:
                             if ( IsAllProcessStop() )
+                            {
+                                //TODO: 여기서 메인명령을 정리하자.
+                                this.sql.SubCmdDAL.Clean();
+                                this.sql.CommandDAL.Clean();
+
                                 this.OperationModeProperty = eOperatationMode.ManualMode;
+                            }
+
                             break;
 
                         case eAutoModeState.StartRun:

+ 15 - 14
Dev/OHV/VehicleControlSystem/VCSystem.cs

@@ -45,6 +45,7 @@ namespace VehicleControlSystem
         Steering steering = null;
         GSIDrive drive = null;
         Clamp clamp = null;
+        ObstacleDetecter obstacleDetecter = null;
         public Vehicle vehicle = null;
 
         public RouteManager RouteManager { get; set; }
@@ -86,6 +87,9 @@ namespace VehicleControlSystem
             ezIO.OnChangedIO += EzIO_OnChangedIO;
             ezIO.OnFirstColtd += EzIO_OnFirstColtd;
 
+            this.obstacleDetecter = new ObstacleDetecter(this.IO);
+            this.obstacleDetecter.Init();
+
             //Battery
             this.bMUManager = new BMUManager();
             this.bMUManager.BMUConfig = new ControlLayer.Serial.BatteryTabos.Config() { ID = "0" };
@@ -133,6 +137,7 @@ namespace VehicleControlSystem
             refObject.Sqlite = this.sql;
             refObject.AutoManager = this.autoManager;
             refObject.HostManager = this.hostManager;
+            refObject.ObstacleDetecter = obstacleDetecter;
 
             this.vehicle.DependencyInjection(refObject);
             this.vehicle.PropertyChanged += Vehicle_PropertyChanged;
@@ -157,7 +162,7 @@ namespace VehicleControlSystem
             catch (Exception ex)
             {
                 logger.E(ex);
-            }        
+            }
         }
 
         void UIRenderingComplete()
@@ -465,7 +470,7 @@ namespace VehicleControlSystem
         {
             var reply = new GUIMessageEventArgs();
             reply.Kind = GUIMessageEventArgs.eGUIMessageKind.RspObstaclePatternNo;
-            reply.MessageText = this.vehicle.GetObstacleDetectPattern().ToString();
+            reply.MessageText = this.obstacleDetecter.CurrentPattern.ToString();
 
             GUIMessageEventPublish(reply);
         }
@@ -473,7 +478,7 @@ namespace VehicleControlSystem
         private void ReqObsticlePatternChange(VCSMessageEventArgs msg)
         {
             var patternNo = Convert.ToInt32(msg.MessageText);
-            this.vehicle.ChgObstacleDetectPattern(patternNo);
+            this.obstacleDetecter.SetObstacleDetectPattern(patternNo);
 
             var reply = new GUIMessageEventArgs();
             reply.Kind = GUIMessageEventArgs.eGUIMessageKind.RspObstaclePatternChg;
@@ -496,9 +501,7 @@ namespace VehicleControlSystem
             };
 
             if (result != 0)
-            {
                 reply.Result = FluentResults.Results.Fail("Conveyor Load FAIL");
-            }
 
             GUIMessageEventPublish(reply);
         }
@@ -516,9 +519,7 @@ namespace VehicleControlSystem
             };
 
             if (result != 0)
-            {
                 reply.Result = FluentResults.Results.Fail("Conveyor Load FAIL");
-            }
 
             GUIMessageEventPublish(reply);
         }
@@ -707,10 +708,10 @@ namespace VehicleControlSystem
             GUIMessageEventArgs reply;
             if (msg.MessageKey.Equals(MessageKey.AutoMode))
             {
-//#if TEST
-//                if (!QuartzUtils.StopSchedule("SteerTest"))
-//                    return;
-//#endif
+                //#if TEST
+                //                if (!QuartzUtils.StopSchedule("SteerTest"))
+                //                    return;
+                //#endif
 
                 if (!this.ZmqManager.IsReqConnected)
                 {
@@ -780,9 +781,9 @@ namespace VehicleControlSystem
                 //    return;
                 //}
 
-                //2020.08.04. Kang. 가지고 있던 명령을 전체 삭제.
-                this.sql.SubCmdDAL.Clean();
-                this.sql.CommandDAL.Clean();
+                //명령 삭제 위치 변경 AutoManager OperationState 변경시로 이동
+                //this.sql.SubCmdDAL.Clean();
+                //this.sql.CommandDAL.Clean();
 
                 this.autoManager.AutoModeStateProperty = OHV.Common.Shareds.eAutoModeState.WaitStop;
                 reply = new GUIMessageEventArgs { Kind = GUIMessageEventArgs.eGUIMessageKind.RspVehicleModeChange, Result = FluentResults.Results.Ok(), MessageKey = MessageKey.ManualMode };

+ 1 - 0
Dev/OHV/VehicleControlSystem/VehicleControlSystem.csproj

@@ -181,6 +181,7 @@
     <Compile Include="ControlLayer\IO\QueueObjects.cs" />
     <Compile Include="ControlLayer\Motion\GSIDrive.cs" />
     <Compile Include="ControlLayer\MQ\ZmqManager.cs" />
+    <Compile Include="ControlLayer\ObstacleDetecter.cs" />
     <Compile Include="ControlLayer\Serial\BatteryTabos\Advantech\Advantech.cs" />
     <Compile Include="ControlLayer\Serial\BatteryTabos\Advantech\AdvCan.cs" />
     <Compile Include="ControlLayer\Serial\BatteryTabos\Advantech\AdvCANIO.cs" />

BIN
Documents/OHV.SETUP/OHV/Tools/Moxa_PG/moxa-wireless-search-utility-v2.6.zip


BIN
Documents/OHV.SETUP/OHV/Tools/Moxa_PG/turbo-roaming-analyzer.7z