Kaynağa Gözat

Merge branch 'master' of http://unque781.synology.me:3000/GSI/OHV

# Conflicts:
#	Dev/OHV/OHV.Module.Interactivity/PopUp/DriveServoViewModel.cs
#	Dev/OHV/VehicleControlSystem/ControlLayer/Vehicle.cs
ys-hwang 6 yıl önce
ebeveyn
işleme
9175cc0428

+ 3 - 0
Dev/OHV/OHV.Common/Events/MessageEventArgs.cs

@@ -25,8 +25,11 @@ namespace OHV.Common.Events
             RspAlarmReset,
             RspVehicleModeChange,
             RspEStop,
+            RspVihicleState,
         }
 
+        //Property 이름임.
+        public string ModelPropertyName { get; set; }
         public eGUIMessageKind Kind { get; set; }
         public string MessageKey { get; set; }
         public string MessageText { get; set; }

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

@@ -79,6 +79,7 @@
     <Compile Include="Model\SelectionItem.cs" />
     <Compile Include="Model\SelectionList.cs" />
     <Compile Include="Model\SubCmd.cs" />
+    <Compile Include="Model\VehicleState.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Shareds\ConstString.cs" />
     <Compile Include="Shareds\SharedEnumType.cs" />

+ 1 - 0
Dev/OHV/OHV.Common/Shareds/ConstString.cs

@@ -31,5 +31,6 @@ namespace OHV.Common.Shareds
         public const string Alarm = "Alarm";
         public const string AutoMode = "AutoMode";
         public const string ManualMode = "ManualMode";
+        public const string Vehicle = "Vehicle";
     }
 }

+ 7 - 0
Dev/OHV/OHV.Common/Shareds/SharedEnumType.cs

@@ -54,6 +54,13 @@
         Blocked,
         Decelerate,
     }
+
+	public enum eSteeringState
+	{
+		None = -1,
+		Left,
+		Right,
+	}
     #endregion
 
     #region Opertation

+ 29 - 28
Dev/OHV/OHV.Module.Interactivity/PopUp/DriveServoView.xaml

@@ -77,7 +77,8 @@
                     <StackPanel>
                         <TextBlock Foreground="White">Drive Point List</TextBlock>
                         <DataGrid ItemsSource="{Binding RouteList}" CanUserSortColumns="True" CanUserAddRows="False" AutoGenerateColumns="False" materialDesign:DataGridAssist.CellPadding="13 8 8 8" 
-                                  materialDesign:DataGridAssist.ColumnHeaderPadding="8" Background="{x:Null}" Foreground="White">
+                                  materialDesign:DataGridAssist.ColumnHeaderPadding="8" Background="{x:Null}" Foreground="White" IsSynchronizedWithCurrentItem="True" SelectedItem="{Binding SelectedRoute, Mode=TwoWay}"
+                                  >
 
                             <DataGrid.Resources>
                                 <Style TargetType="{x:Type DataGridRow}">
@@ -136,8 +137,6 @@
                 </Grid.ColumnDefinitions>
 
                 <Border Margin="0,5,163,5" BorderBrush="#FF00FFD3" BorderThickness="2" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.RowSpan="4" Grid.Column="2"/>
-                <Border Margin="161,5,2,3" BorderBrush="#FF00FFD3" BorderThickness="2" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.RowSpan="2" Grid.Column="2" Grid.Row="2"/>
-                <Border Margin="161,0,10,78" BorderBrush="#FF00FFD3" BorderThickness="2" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.Column="2" Grid.ColumnSpan="3" Grid.Row="2" RenderTransformOrigin="0.495,5.333"/>
                 <Border Margin="33,-2,34,82" BorderBrush="#FF00FFD3" BorderThickness="2" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.Column="2" Grid.ColumnSpan="3" Grid.RowSpan="2"/>
 
                 <Button Grid.Column="0" Grid.Row="1" HorizontalAlignment="Stretch" Margin="5" Height="auto"
@@ -196,34 +195,35 @@
                             materialDesign:ButtonAssist.CornerRadius="10">
                     <TextBlock><Run Text="{Binding DifferenceDrive, StringFormat=0.000, FallbackValue=0.000}"/></TextBlock>
                 </Button>
-
-                <Button Grid.Column="3" Margin="10,26,6,22"
-                        Grid.Row="2"
+                    
+                <StackPanel Grid.Column="2" Grid.Row="1" Grid.ColumnSpan="3" Grid.RowSpan="3"  Orientation="Horizontal" HorizontalAlignment="Center" Margin="102,52,102,31" >
+                    <Button Margin="0,30" Width="150"
                         HorizontalAlignment="Stretch" 
                         Height="Auto" 
                         BorderBrush="{Binding SteeringLeftBrushProperty}" 
                         BorderThickness="5" 
                         Command="{Binding SteeringCWCommand}"
-                        CommandParameter="CW" Grid.RowSpan="2">
-                    <StackPanel>
-                        <materialDesign:PackIcon Kind="ArrowLeft" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Height="42" Width="auto"/>
-                        <TextBlock Text="Steering Left" VerticalAlignment="Stretch" HorizontalAlignment="Center"/>
-                    </StackPanel>
-                </Button>
-
-                <Button Grid.Column="4" Margin="6,26,10,22"
-                        Grid.Row="2"
+                        CommandParameter="CW" >
+                        <StackPanel>
+                            <materialDesign:PackIcon Kind="ArrowLeft" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Height="42" Width="auto"/>
+                            <TextBlock Text="Steering Left" VerticalAlignment="Stretch" HorizontalAlignment="Center"/>
+                        </StackPanel>
+                    </Button>
+
+                    <Button Margin="0,30" Width="150"
                         HorizontalAlignment="Stretch" 
                         Height="Auto" 
                         BorderBrush="{Binding SteeringRightBrushProperty}" 
                         BorderThickness="5" 
                         Command="{Binding SteeringCCWCommand}"
-                        CommandParameter="CCW" Grid.RowSpan="2">
-                    <StackPanel>
-                        <materialDesign:PackIcon Kind="ArrowRight" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Height="42" Width="auto"/>
-                        <TextBlock Text="Steering Right" VerticalAlignment="Stretch" HorizontalAlignment="Center"/>
-                    </StackPanel>
-                </Button>
+                        CommandParameter="CCW">
+                        <StackPanel>
+                            <materialDesign:PackIcon Kind="ArrowRight" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Height="42" Width="auto"/>
+                            <TextBlock Text="Steering Right" VerticalAlignment="Stretch" HorizontalAlignment="Center"/>
+                        </StackPanel>
+                    </Button>
+                </StackPanel>
+
 
                 <!--Jog Button-->
                 <RepeatButton
@@ -293,13 +293,6 @@
                     </StackPanel>
                 </Button>
 
-                <Button Margin="7, 10" HorizontalAlignment="Stretch" Height="60" BorderBrush="Gray" BorderThickness="2" 
-                        Command="{Binding PositionSaveCommand}">
-                    <StackPanel>
-                        <!--<materialDesign:PackIcon Kind="PowerSettings" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Height="42" Width="auto"/>-->
-                        <TextBlock Text="Save" VerticalAlignment="Stretch" HorizontalAlignment="Center"/>
-                    </StackPanel>
-                </Button>
             </StackPanel>
 
             <StackPanel Grid.Column="1" VerticalAlignment="Center" Orientation="Vertical"
@@ -357,6 +350,14 @@
             </StackPanel>
 
             <StackPanel VerticalAlignment="Bottom">
+                <Button Margin="7, 10" HorizontalAlignment="Stretch" Height="70" BorderBrush="Gray" BorderThickness="2" 
+                        Command="{Binding PositionSaveCommand}">
+                    <StackPanel>
+                        <materialDesign:PackIcon Kind="ContentSave" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Height="42" Width="auto"/>
+                        <TextBlock Text="Save" VerticalAlignment="Stretch" HorizontalAlignment="Center"/>
+                    </StackPanel>
+                </Button>
+
                 <Button Margin="5" HorizontalAlignment="Stretch" Height="Auto" BorderBrush="Gray" BorderThickness="2" Command="{Binding CloseDialogCommand}" CommandParameter="true">
                     <StackPanel>
                         <materialDesign:PackIcon Kind="ExitToApp" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Height="42" Width="auto"/>

+ 147 - 70
Dev/OHV/OHV.Module.Interactivity/PopUp/DriveServoViewModel.cs

@@ -1,5 +1,7 @@
-using OHV.Common.Events;
+using GSG.NET.Extensions;
+using OHV.Common.Events;
 using OHV.Common.Model;
+using OHV.Common.Shareds;
 using OHV.SqliteDAL;
 using Prism.Commands;
 using Prism.Events;
@@ -15,6 +17,7 @@ using System.Windows.Media;
 
 namespace OHV.Module.Interactivity.PopUp
 {
+    //Todo: DataGrid Scroll 동작 수정 필요.
     public class DriveServoViewModel : BindableBase, IDialogAware
     {
         private DelegateCommand<string> _closeDialogCommand;
@@ -53,7 +56,7 @@ namespace OHV.Module.Interactivity.PopUp
         public double DriveTargetPos
         {
             get { return this._driveTargetPos; }
-            set { this.SetProperty(ref this._driveTargetPos , value); }
+            set { this.SetProperty(ref this._driveTargetPos, value); }
         }
 
         private double _currentDrive;
@@ -123,6 +126,13 @@ namespace OHV.Module.Interactivity.PopUp
             set { SetProperty(ref this._routeList, value); }
         }
 
+        private Route selectedRoute;
+        public Route SelectedRoute
+        {
+            get { return selectedRoute; }
+            set { SetProperty(ref this.selectedRoute, value); }
+        }
+
         public SqliteDAL.DAL.AxisPositionDataDAL axisPositionDataDal;
         SqliteManager sql;
         MessageController messageController;
@@ -130,8 +140,11 @@ namespace OHV.Module.Interactivity.PopUp
         public DriveServoViewModel(IEventAggregator _ea, SqliteManager _sql, MessageController _messageController)
         {
             this.eventAggregator = _ea;
-            this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Unsubscribe(UICallbackCommunication);
-            this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Subscribe(UICallbackCommunication, ThreadOption.UIThread);
+            this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Unsubscribe(DriveControlCallBack);
+            this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Subscribe(DriveControlCallBack, ThreadOption.UIThread);
+
+            this.eventAggregator.GetEvent<GUIMessagePubSubEvent>().Unsubscribe(UICallBackCommunication);
+            this.eventAggregator.GetEvent<GUIMessagePubSubEvent>().Subscribe(UICallBackCommunication, ThreadOption.UIThread);
 
             this.sql = _sql;
             this.RouteList = new ObservableCollection<Route>(sql.RouteDal.All);
@@ -160,13 +173,34 @@ namespace OHV.Module.Interactivity.PopUp
             this.JogCommand = new DelegateCommand<object>(ExecuteJogCommand);
         }
 
-        private void UICallbackCommunication(DriveControlEventArgs args)
+        private void UICallBackCommunication(GUIMessageEventArgs obj)
+        {
+            if ( obj.Kind == GUIMessageEventArgs.eGUIMessageKind.ModelPropertyChange)
+            {
+                if (obj.MessageKey.Equals(MessageKey.Vehicle))
+                {
+                    switch (obj.ModelPropertyName )
+                    {
+                        case "SteeringState":
+                            {
+                                var dir = CastTo<eSteeringState>.From<object>(obj.Args);
+                                this.ChangeSteeringDirection(dir);
+                            }
+                            break;
+                        default:
+                            break;
+                    }
+                }
+            }
+        }
+
+        private void DriveControlCallBack(DriveControlEventArgs args)
         {
             //TODO:[20/03/19 ys-hwang] Drive UI return msg popup
 
             if (args.EventDir == DriveControlEventArgs.eEventDir.ToFront)
             {
-                switch ( args.ControlKind )
+                switch (args.ControlKind)
                 {
                     case DriveControlEventArgs.eControlKind.MOVE:
                         ResponseMove(args);
@@ -174,19 +208,19 @@ namespace OHV.Module.Interactivity.PopUp
                     case DriveControlEventArgs.eControlKind.STOP:
                         break;
                     case DriveControlEventArgs.eControlKind.Steering:
-                        if ( args.Result.IsSuccess )
-                        {
-                            var dir = args.Result.ToResult<DriveControlEventArgs.eMoveDir>().Value;
-                            this.ChangeSteeringDirection( dir == DriveControlEventArgs.eMoveDir.LEFT ? true : false );
-                        }
-                        break;
+                        //if (args.Result.IsSuccess)
+                        //{
+                        //    var dir = args.Result.ToResult<DriveControlEventArgs.eMoveDir>().Value;
+                        //    this.ChangeSteeringDirection(dir == DriveControlEventArgs.eMoveDir.LEFT ? true : false);
+                        //}
+                        //break;
                     case DriveControlEventArgs.eControlKind.SteeringState:
-                        if ( args.Result.IsSuccess )
-                        {
-                            var dir = args.Result.ToResult<DriveControlEventArgs.eMoveDir>().Value;
-                            this.ChangeSteeringDirection( dir == DriveControlEventArgs.eMoveDir.LEFT ? true : false );
-                        }
-                        break;
+                        //if (args.Result.IsSuccess)
+                        //{
+                        //    var dir = args.Result.ToResult<DriveControlEventArgs.eMoveDir>().Value;
+                        //    this.ChangeSteeringDirection(dir == DriveControlEventArgs.eMoveDir.LEFT ? true : false);
+                        //}
+                        //break;
                     case DriveControlEventArgs.eControlKind.ReqCurrentPos:
                         this.CurrentDrive = args.CurrentPosition;
                         break;
@@ -228,18 +262,23 @@ namespace OHV.Module.Interactivity.PopUp
             this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Publish(args);
         }
 
-        void ChangeSteeringDirection(bool isLeft)
+        void ChangeSteeringDirection(eSteeringState state)
         {
-            if (isLeft)
+            if (state == eSteeringState.Left)
             {
                 this.SteeringLeftBrushProperty = (System.Windows.Media.Brush)new System.Windows.Media.BrushConverter().ConvertFromString("#FF00FFD3");
                 this.SteeringRightBrushProperty = Brushes.Gray;
             }
-            else
+            else if (state == eSteeringState.Right)
             {
                 this.SteeringLeftBrushProperty = Brushes.Gray;
                 this.SteeringRightBrushProperty = (System.Windows.Media.Brush)new System.Windows.Media.BrushConverter().ConvertFromString("#FF00FFD3");
             }
+            else
+            {
+                this.SteeringLeftBrushProperty = Brushes.Gray;
+                this.SteeringRightBrushProperty = Brushes.Gray;
+            }
         }
 
         #region Execute Method
@@ -251,12 +290,12 @@ namespace OHV.Module.Interactivity.PopUp
                 ControlKind = DriveControlEventArgs.eControlKind.JOG,
             };
 
-            if ( obj.ToString().Equals( "+" ) )
+            if (obj.ToString().Equals("+"))
                 msg.JogDir = DriveControlEventArgs.eJogMoveDir.Positive;
             else
                 msg.JogDir = DriveControlEventArgs.eJogMoveDir.Negative;
 
-            this.PublishEvent( msg );
+            this.PublishEvent(msg);
         }
 
         private void ExecuteJogVelPopupCommand()
@@ -308,33 +347,44 @@ namespace OHV.Module.Interactivity.PopUp
         {
             this.messageController.ShowConfirmationPopupView("Save To Data ?", r =>
             {
-              if (r.Result == ButtonResult.OK)
-              {
-                    //TODO:[20/03/18 ys-hwang] DB Table Update
-              }
+                if (r.Result == ButtonResult.OK)
+                {
+                    var ll = this.RouteList.ToList();
+                    ll.ForEach(x =>
+                    {
+                        var route = sql.RouteDal.GetK(x.Id);
+                        if (route == null) //DB 에 없다고 판단 추가
+                            sql.RouteDal.Add(x);
+                        else //Update
+                            sql.RouteDal.Update(x);
+                    });
+                    this.RefreshRouteList();
+                }
             });
         }
 
         private void ExecutePositionDeleteCommand()
         {
-            this.messageController.ShowConfirmationPopupView( "Select To Delete ?" , r =>
-            {
-                if ( r.Result == ButtonResult.OK )
-                {
-                    var deleteList = new List<Route>();
-
-                    foreach ( var item in this.RouteList )
-                    {
-                        if ( item.IsSelected )
-                            deleteList.Add( item );
-                    }
-                    deleteList.ForEach( x => { this.RouteList.Remove( x ); } );
-                }
-            } );
+            this.messageController.ShowConfirmationPopupView("Select To Delete ?", r =>
+          {
+              if (r.Result == ButtonResult.OK)
+              {
+                  var deleteList = new List<Route>();
+
+                  foreach (var item in this.RouteList)
+                  {
+                      if (item.IsSelected)
+                          deleteList.Add(item);
+                  }
+                  deleteList.ForEach(x => { this.RouteList.Remove(x); });
+              }
+              this.RefreshRouteList();
+          });
         }
 
         private void ExecutePositionAddCommand()
         {
+<<<<<<< HEAD
             this.messageController.ShowConfirmationPopupView( "Position Add ?" , r =>
             {
                 if ( r.Result == ButtonResult.OK )
@@ -344,72 +394,82 @@ namespace OHV.Module.Interactivity.PopUp
                     this.messageController.ShowNotificationView( "Create Success" );
                 }
             } );
+=======
+            this.messageController.ShowConfirmationPopupView("Position Add ?", r =>
+          {
+              if (r.Result == ButtonResult.OK)
+              {
+                  this.RouteList.Add(new Route());
+              }
+          });
+>>>>>>> f2b1b12e8c9f7450e1cbe9e6d15261074bce9945
         }
 
         private void ExecuteKeyInCommadn(object obj)
         {
             var numPad = new CalcuratorView();
-            var result = numPad.ShowDialog(this.DriveTargetPos );
+            var result = numPad.ShowDialog(this.DriveTargetPos);
             this.DriveTargetPos = result;
         }
 
         private void ExecuteOriginCommand()
         {
-            this.messageController.ShowConfirmationPopupView( "Origin ?" , r =>
-            {
-                if ( r.Result == ButtonResult.OK )
-                {
+            this.messageController.ShowConfirmationPopupView("Origin ?", r =>
+          {
+              if (r.Result == ButtonResult.OK)
+              {
                     //TODO: How to use
                 }
-            } );
+          });
         }
 
         private void ExecuteFaultResetCommand()
         {
             var msg = new DriveControlEventArgs
             {
-                EventDir = DriveControlEventArgs.eEventDir.ToBack ,
-                ControlKind = DriveControlEventArgs.eControlKind.FaultReset ,
+                EventDir = DriveControlEventArgs.eEventDir.ToBack,
+                ControlKind = DriveControlEventArgs.eControlKind.FaultReset,
             };
 
-            this.PublishEvent( msg );
+            this.PublishEvent(msg);
         }
 
         private void ExecuteServoOffCommand()
         {
             var msg = new DriveControlEventArgs
             {
-                EventDir = DriveControlEventArgs.eEventDir.ToBack ,
-                ControlKind = DriveControlEventArgs.eControlKind.DriveOFF ,
+                EventDir = DriveControlEventArgs.eEventDir.ToBack,
+                ControlKind = DriveControlEventArgs.eControlKind.DriveOFF,
             };
 
-            this.PublishEvent( msg );
+            this.PublishEvent(msg);
         }
 
         private void ExecuteServoOnCommand()
         {
             var msg = new DriveControlEventArgs
             {
-                EventDir = DriveControlEventArgs.eEventDir.ToBack ,
-                ControlKind = DriveControlEventArgs.eControlKind.DriveON ,
+                EventDir = DriveControlEventArgs.eEventDir.ToBack,
+                ControlKind = DriveControlEventArgs.eControlKind.DriveON,
             };
 
-            this.PublishEvent( msg );
+            this.PublishEvent(msg);
         }
 
         private void ExecuteCurrentToTargetCommand()
         {
-            this.messageController.ShowConfirmationPopupView( "Current To Target ?" , r =>
-            {
-                if ( r.Result == ButtonResult.OK )
-                {
-                    this.DriveTargetPos = this.CurrentDrive;
-                }
-            } );
+            this.messageController.ShowConfirmationPopupView("Current To Target ?", r =>
+          {
+              if (r.Result == ButtonResult.OK)
+              {
+                  this.DriveTargetPos = this.CurrentDrive;
+              }
+          });
         }
 
         private void ExecuteMoveToCommand()
         {
+<<<<<<< HEAD
             this.messageController.ShowConfirmationPopupView( "Move To Pos ?" , r =>
             {
                 if ( r.Result == ButtonResult.OK )
@@ -420,10 +480,21 @@ namespace OHV.Module.Interactivity.PopUp
                         ControlKind = DriveControlEventArgs.eControlKind.MOVE ,
                         //PositionTag = 
                     };
-
-                    this.PublishEvent( msg );
-                }
-            } );
+=======
+            this.messageController.ShowConfirmationPopupView("Move To Pos ?", r =>
+          {
+              if (r.Result == ButtonResult.OK)
+              {
+                  var msg = new DriveControlEventArgs
+                  {
+                      EventDir = DriveControlEventArgs.eEventDir.ToBack,
+                      ControlKind = DriveControlEventArgs.eControlKind.MOVE,
+                  };
+>>>>>>> f2b1b12e8c9f7450e1cbe9e6d15261074bce9945
+
+                  this.PublishEvent(msg);
+              }
+          });
         }
 
         private void ExecuteSelectPosCommand(object obj)
@@ -433,6 +504,12 @@ namespace OHV.Module.Interactivity.PopUp
 
         #endregion
 
+        void RefreshRouteList()
+        {
+            this.RouteList.Clear();
+            this.RouteList.AddRange(sql.RouteDal.All);
+        }
+
         #region Dialog Function
         public bool CanCloseDialog()
         {
@@ -441,8 +518,8 @@ namespace OHV.Module.Interactivity.PopUp
 
         public void OnDialogClosed()
         {
-            this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Publish( new DriveControlEventArgs { EventDir = DriveControlEventArgs.eEventDir.ToBack , ControlKind = DriveControlEventArgs.eControlKind.ReqStopCurrentPos } );
-            this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Unsubscribe( UICallbackCommunication );
+            this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Publish(new DriveControlEventArgs { EventDir = DriveControlEventArgs.eEventDir.ToBack, ControlKind = DriveControlEventArgs.eControlKind.ReqStopCurrentPos });
+            this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Unsubscribe(DriveControlCallBack);
         }
 
         public void OnDialogOpened(IDialogParameters parameters)
@@ -454,7 +531,7 @@ namespace OHV.Module.Interactivity.PopUp
             };
             this.PublishEvent(msg);
 
-            this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Publish( new DriveControlEventArgs { EventDir = DriveControlEventArgs.eEventDir.ToBack , ControlKind = DriveControlEventArgs.eControlKind.ReqCurrentPos } );
+            this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Publish(new DriveControlEventArgs { EventDir = DriveControlEventArgs.eEventDir.ToBack, ControlKind = DriveControlEventArgs.eControlKind.ReqCurrentPos });
         }
 
         private void CloseDialog(string parameter)

+ 1 - 1
Dev/OHV/OHV.Module.Interactivity/PopUp/LockServoView.xaml

@@ -465,7 +465,7 @@
                         materialDesign:ShadowAssist.ShadowDepth="Depth5"
                         Command="{Binding SelectedPosDataSave}">
                     <StackPanel>
-                        <materialDesign:PackIcon Kind="CalendarExport" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Height="42" Width="auto"/>
+                        <materialDesign:PackIcon Kind="ContentSave" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Height="42" Width="auto"/>
                         <TextBlock Text="SAVE" VerticalAlignment="Stretch" HorizontalAlignment="Center"/>
                     </StackPanel>
                 </Button>

+ 62 - 2
Dev/OHV/VehicleControlSystem/ControlLayer/Steering.cs

@@ -2,6 +2,7 @@
 using System.Threading.Tasks;
 using GSG.NET.Logging;
 using GSG.NET.Utils;
+using OHV.Common.Shareds;
 using OHV.SqliteDAL;
 using Prism.Events;
 using VehicleControlSystem.ControlLayer.IO;
@@ -12,17 +13,76 @@ namespace VehicleControlSystem.ControlLayer
     {
         static Logger logger = Logger.GetLogger();
 
-        IIO iO = null;
+        EzIO iO = null;
         SqliteManager sql = null;
         IEventAggregator eventAggregator = null;
 
         public event EventHandler<int> OnSteeringError;
 
+        private eSteeringState steeringState;
+
+        public eSteeringState SteeringState
+        {
+            get { return steeringState; }
+            set { SetField(ref this.steeringState, value); }
+        }
+
         public Steering(IIO io, SqliteManager sql, IEventAggregator ea)
         {
-            this.iO = io;
+            this.iO = io as EzIO;
             this.sql = sql;
             this.eventAggregator = ea;
+            this.iO.OnChangedIO += IO_OnChangedIO;
+        }
+
+        private void IO_OnChangedIO(BitBlock bit)
+        {
+            if (bit.Tag.Equals("IN_F_STEERING_DETECT_LEFT") || bit.Tag.Equals("IN_F_STEERING_DETECT_RIGHT"))
+                this.GetSteeringState();
+            if (bit.Tag.Equals("IN_R_STEERING_DETECT_LEFT") || bit.Tag.Equals("IN_R_STEERING_DETECT_RIGHT"))
+                this.GetSteeringState();
+        }
+
+        void GetSteeringState()
+        {
+            eSteeringState frontState = eSteeringState.None;
+            if (this.IsFrontLeft() && this.IsFrontRight())
+            {
+                //None
+            }
+            if (!this.IsFrontLeft() && !this.IsFrontRight())
+            {
+                //None
+            }
+            if (this.IsFrontLeft() && !this.IsFrontRight())
+                frontState = eSteeringState.Left;
+            if (!this.IsFrontLeft() && this.IsFrontRight())
+                frontState = eSteeringState.Right;
+
+            eSteeringState rearState = eSteeringState.None;
+            if (this.IsRearLeft() && this.IsRearRight())
+            {
+                //None
+            }
+            if (!this.IsRearLeft() && !this.IsRearRight())
+            {
+                //None
+            }
+            if (this.IsRearLeft() && !this.IsRearRight())
+            {
+                rearState = eSteeringState.Left;
+            }
+            if (!this.IsRearLeft() && this.IsRearRight())
+            {
+                rearState = eSteeringState.Right;
+            }
+
+            if (frontState == eSteeringState.Left && rearState == eSteeringState.Left)
+                this.SteeringState = eSteeringState.Left;
+            else if (frontState == eSteeringState.Right && rearState == eSteeringState.Right)
+                this.SteeringState = eSteeringState.Right;
+            else
+                this.SteeringState = eSteeringState.None;
         }
 
         object lockObj = new object();

+ 240 - 179
Dev/OHV/VehicleControlSystem/ControlLayer/Vehicle.cs

@@ -6,6 +6,7 @@ using System.Threading;
 using System.Threading.Tasks;
 using FluentResults;
 using GSG.NET.Concurrent;
+using GSG.NET.Extensions;
 using GSG.NET.LINQ;
 using GSG.NET.Logging;
 using GSG.NET.Quartz;
@@ -42,7 +43,7 @@ namespace VehicleControlSystem.ControlLayer
         }
 
         static Logger logger = Logger.GetLogger();
-        static Logger loggerPIO = Logger.GetLogger( "PIO" );
+        static Logger loggerPIO = Logger.GetLogger("PIO");
 
         #region Properties
         private double currentPosition;
@@ -50,18 +51,39 @@ namespace VehicleControlSystem.ControlLayer
         /// <summary>
         /// Tag 위치
         /// </summary>
+        private int currentTag;
+
+        public int CurrentTag
+        {
+            get { return currentTag; }
+            set { SetField(ref this.currentTag, value); }
+        }
+
+        /// <summary>
+        /// Scale Value
+        /// </summary>
         public double CurrentPosition
         {
             get { return currentPosition; }
             set
             {
-                if ( this.currentPosition == value ) return;
-
-                this.currentPosition = value;
-                this.OnCurrentPotisionChanged?.Invoke( (int)value );
+                if (SetField(ref this.currentPosition, value))
+                {
+                    this.currentPosition = value;
+                    this.OnCurrentPotisionChanged?.Invoke((int)value);
+                }
             }
         }
 
+        private eSteeringState steeringState;
+
+        public eSteeringState SteeringState
+        {
+            get { return steeringState; }
+            set { SetField(ref this.steeringState, value); }
+        }
+
+
         //이동
         public bool Busy
         {
@@ -69,9 +91,9 @@ namespace VehicleControlSystem.ControlLayer
             {
                 return this.CurrentSubCommand == null ? false : true;
             }
-
-            private set { }
+            set { }
         }
+
         public bool IsMoving { get; set; }
         public double BatteryVolt { get; set; }
         public bool IsError { get; set; }
@@ -127,36 +149,37 @@ namespace VehicleControlSystem.ControlLayer
         public eObstacleState ObstacleStateProperty
         {
             get { return obstacleState; }
-            set { SetField( ref this.obstacleState, value ); }
+            set { SetField(ref this.obstacleState, value); }
         }
 
         private eVehicleState vehicleState;
         public eVehicleState VehicleStateProperty
         {
             get { return vehicleState; }
-            set { SetField( ref this.vehicleState, value ); }
+            set { SetField(ref this.vehicleState, value); }
         }
 
         IEventAggregator eventAggregator;
 
-        public Vehicle( IIO io, SqliteManager sqliteManager, IEventAggregator ea, AutoManager auto )
+        public Vehicle(IIO io, SqliteManager sqliteManager, IEventAggregator ea, AutoManager auto)
         {
             this.iO = io;
             this.motion = new GSIMotion();
             this.sql = sqliteManager;
             this.autoManager = auto;
 
-            this.obstacleBitList.AddRange( new string[]
+            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",
-            } );
+            });
 
             this.eventAggregator = ea;
 
+<<<<<<< HEAD
             /*Drive*/
             this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Unsubscribe( ReceiveDriveControlEvent );
             this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Subscribe( ReceiveDriveControlEvent );
@@ -186,17 +209,21 @@ namespace VehicleControlSystem.ControlLayer
                         break;
                 }
             }
+=======
+            this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Unsubscribe(ReceiveDriveControlEvent);
+            this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Subscribe(ReceiveDriveControlEvent);
+>>>>>>> f2b1b12e8c9f7450e1cbe9e6d15261074bce9945
         }
 
-        private void ReceiveDriveControlEvent( DriveControlEventArgs _args )
+        private void ReceiveDriveControlEvent(DriveControlEventArgs _args)
         {
-            if ( this.autoManager.OperationModeProperty != eOperatationMode.ManualMode )
+            if (this.autoManager.OperationModeProperty != eOperatationMode.ManualMode)
                 return;
 
             var msg = _args;
-            if ( msg.EventDir == DriveControlEventArgs.eEventDir.ToBack )
+            if (msg.EventDir == DriveControlEventArgs.eEventDir.ToBack)
             {
-                switch ( msg.ControlKind )
+                switch (msg.ControlKind)
                 {
                     case DriveControlEventArgs.eControlKind.MOVE:
                         this.ReqMoveToPos(_args);
@@ -204,8 +231,8 @@ namespace VehicleControlSystem.ControlLayer
                     case DriveControlEventArgs.eControlKind.STOP:
                         break;
                     case DriveControlEventArgs.eControlKind.Steering:
-                        if ( msg.MoveDir == DriveControlEventArgs.eMoveDir.LEFT )
-                            this.steering.ControlSteering( true );
+                        if (msg.MoveDir == DriveControlEventArgs.eMoveDir.LEFT)
+                            this.steering.ControlSteering(true);
                         else
                             this.steering.ControlSteering();
                         break;
@@ -213,11 +240,11 @@ namespace VehicleControlSystem.ControlLayer
                         {
                             DriveControlEventArgs reply = new DriveControlEventArgs();
                             reply.ControlKind = DriveControlEventArgs.eControlKind.SteeringState;
-                            if ( this.steering.IsLeft() )
-                                reply.Result = FluentResults.Results.Ok<DriveControlEventArgs.eMoveDir>( DriveControlEventArgs.eMoveDir.LEFT );
+                            if (this.steering.IsLeft())
+                                reply.Result = FluentResults.Results.Ok<DriveControlEventArgs.eMoveDir>(DriveControlEventArgs.eMoveDir.LEFT);
                             else
-                                reply.Result = FluentResults.Results.Ok<DriveControlEventArgs.eMoveDir>( DriveControlEventArgs.eMoveDir.RIGHT );
-                            this.DriveControlEventPublish( reply );
+                                reply.Result = FluentResults.Results.Ok<DriveControlEventArgs.eMoveDir>(DriveControlEventArgs.eMoveDir.RIGHT);
+                            this.DriveControlEventPublish(reply);
                         }
                         break;
                     case DriveControlEventArgs.eControlKind.ReqCurrentPos:
@@ -228,16 +255,16 @@ namespace VehicleControlSystem.ControlLayer
                         this.taskCancel.WaitAll();
                         break;
                     case DriveControlEventArgs.eControlKind.FaultReset:
-                        this.ReqFaultReset( _args );
+                        this.ReqFaultReset(_args);
                         break;
                     case DriveControlEventArgs.eControlKind.DriveON:
-                        this.ReqDriveOn( _args );
+                        this.ReqDriveOn(_args);
                         break;
                     case DriveControlEventArgs.eControlKind.DriveOFF:
-                        this.ReqDriveOff( _args );
+                        this.ReqDriveOff(_args);
                         break;
                     case DriveControlEventArgs.eControlKind.JOG:
-                        this.ReqJog( _args );
+                        this.ReqJog(_args);
                         break;
                     default:
                         break;
@@ -245,11 +272,15 @@ namespace VehicleControlSystem.ControlLayer
             }
         }
 
+<<<<<<< HEAD
 
         private void DriveControlEventPublish( DriveControlEventArgs args )
+=======
+        private void DriveControlEventPublish(DriveControlEventArgs args)
+>>>>>>> f2b1b12e8c9f7450e1cbe9e6d15261074bce9945
         {
             args.EventDir = DriveControlEventArgs.eEventDir.ToFront;
-            this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Publish( args );
+            this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Publish(args);
         }
 
         public void Init()
@@ -258,17 +289,19 @@ namespace VehicleControlSystem.ControlLayer
             this.CreateSteering();
 
             ThreadStart();
+
+            //TimerUtils.Once(5000, () => { this.CurrentPosition = 1000; });
         }
 
         public int InitializationVehicle()
         {
             int result = 0;
-            if ( this.IsDetectedCenter() ) //자제가 있으면 Lock
+            if (this.IsDetectedCenter()) //자제가 있으면 Lock
                 result = this.clamp.Lock_Sync();
             else
                 result = this.clamp.Unlock_Sync();
 
-            if ( this.motion.IsErrorOn )
+            if (this.motion.IsErrorOn)
                 return 22;
 
             return result;
@@ -308,16 +341,16 @@ namespace VehicleControlSystem.ControlLayer
                 ControlKind = DriveControlEventArgs.eControlKind.FaultReset
             };
 
-            msg.Result = Results.Ok( "Drive On" );
-            this.DriveControlEventPublish( msg );
+            msg.Result = Results.Ok("Drive On");
+            this.DriveControlEventPublish(msg);
         }
 
         void ReqJog(DriveControlEventArgs _args)
         {
             //TODO:[20/03/18 ys-hwang] Drive Jog Request
             var drive = string.Empty;
-            
-            if ( _args.JogDir == DriveControlEventArgs.eJogMoveDir.Positive )
+
+            if (_args.JogDir == DriveControlEventArgs.eJogMoveDir.Positive)
                 drive = "POSITIVE";
             else
                 drive = "NEGATIVE";
@@ -327,12 +360,13 @@ namespace VehicleControlSystem.ControlLayer
         {
             //TODO:[20/03/18 ys-hwang] Drive Current Position Publish
 
-            var task = Task.Factory.StartNew( ( ) =>
-             {
-                 while(!this.taskCancel.Canceled)
-                 {
-                     LockUtils.Wait( 500 );
+            var task = Task.Factory.StartNew(() =>
+            {
+                while (!this.taskCancel.Canceled)
+                {
+                    LockUtils.Wait(500);
 
+<<<<<<< HEAD
                      var msg = new DriveControlEventArgs
                      {
                          EventDir = DriveControlEventArgs.eEventDir.ToFront ,
@@ -341,13 +375,23 @@ namespace VehicleControlSystem.ControlLayer
                      };
                      
                      this.DriveControlEventPublish( msg );
+=======
+                    var msg = new DriveControlEventArgs
+                    {
+                        EventDir = DriveControlEventArgs.eEventDir.ToFront,
+                        ControlKind = DriveControlEventArgs.eControlKind.ReqCurrentPos,
+                         //CurrentPosition = drive.CurrentPosition,
+                     };
+
+                     //this.DriveControlEventPublish( msg );
+>>>>>>> f2b1b12e8c9f7450e1cbe9e6d15261074bce9945
                  }
-             } );
+            });
 
-            this.taskCancel.Add( task );
+            this.taskCancel.Add(task);
         }
 
-        void ReqDriveOn( DriveControlEventArgs _args)
+        void ReqDriveOn(DriveControlEventArgs _args)
         {
             var drive = "Drive Name";
             //drive.On();
@@ -356,57 +400,61 @@ namespace VehicleControlSystem.ControlLayer
             {
                 ControlKind = DriveControlEventArgs.eControlKind.DriveON
             };
-            msg.Result = Results.Ok( "Drive On" );
+            msg.Result = Results.Ok("Drive On");
 
-            this.DriveControlEventPublish( msg );
+            this.DriveControlEventPublish(msg);
         }
 
-        void ReqDriveOff( DriveControlEventArgs _args)
+        void ReqDriveOff(DriveControlEventArgs _args)
         {
             var drive = "Drive Name";
             //drive.Off();
 
             var msg = new DriveControlEventArgs
             {
+<<<<<<< HEAD
                 ControlKind = DriveControlEventArgs.eControlKind.DriveOFF
+=======
+
+>>>>>>> f2b1b12e8c9f7450e1cbe9e6d15261074bce9945
             };
-            msg.Result = Results.Ok( "Drive On" );
+            msg.Result = Results.Ok("Drive On");
 
-            this.DriveControlEventPublish( msg );
+            this.DriveControlEventPublish(msg);
         }
         #endregion
 
         #region Thread
         void ThreadStart()
         {
-            this.cancel.AddGo( new Action( this._ThSubCmdWorker ) );
-            this.cancel.AddGo( new Action( this._ThObstacleChecker ) );
+            this.cancel.AddGo(new Action(this._ThSubCmdWorker));
+            this.cancel.AddGo(new Action(this._ThObstacleChecker));
         }
 
         //장애물 감지 Thread
         //장애물 감지 패턴 변경도 여기 하자.
         private void _ThObstacleChecker()
         {
-            while ( !this.cancel.Canceled )
+            while (!this.cancel.Canceled)
             {
                 try
                 {
-                    if ( this.autoManager.OperationModeProperty == eOperatationMode.AutoMode )
+                    if (this.autoManager.OperationModeProperty == eOperatationMode.AutoMode)
                         this.CheckObstacle();
                 }
-                catch ( ThreadInterruptedException threadInterruptedException )
+                catch (ThreadInterruptedException threadInterruptedException)
                 {
                 }
-                catch ( Exception exception )
+                catch (Exception exception)
                 {
-                    logger.E( exception );
+                    logger.E(exception);
                 }
                 finally
                 {
-                    LockUtils.Wait( 5 );
+                    LockUtils.Wait(5);
                 }
             }
-            logger.D( "Vehicle - _ThObstacleChecker Dispose" );
+            logger.D("Vehicle - _ThObstacleChecker Dispose");
         }
 
         /// <summary>
@@ -414,66 +462,66 @@ namespace VehicleControlSystem.ControlLayer
         /// </summary>
         public void _ThSubCmdWorker()
         {
-            while ( !this.cancel.Canceled )
+            while (!this.cancel.Canceled)
             {
                 try
                 {
-                    if ( this.ObstacleStateProperty != eObstacleState.Normal ) //장애물 감지 상태 시 조그 동작만 가능하게.
+                    if (this.ObstacleStateProperty != eObstacleState.Normal) //장애물 감지 상태 시 조그 동작만 가능하게.
                         continue;
 
-                    if ( this.autoManager.AutoModeStateProperty != eAutoModeState.Run ) // 
+                    if (this.autoManager.AutoModeStateProperty != eAutoModeState.Run) // 
                         continue;
 
                     var subCmd = sql.SubCmdDAL.GetSubCmd();
-                    if ( subCmd == null ) continue;
+                    if (subCmd == null) continue;
 
-                    if ( !sql.CommandDAL.All.Any( x => x.CommandID.Equals( subCmd.CmdID ) ) )
+                    if (!sql.CommandDAL.All.Any(x => x.CommandID.Equals(subCmd.CmdID)))
                     {
-                        if ( subCmd.CmdType == SubCmd.eCmdType.Auto ) //자동 명령중 Main Command 가 없으면 삭제.
+                        if (subCmd.CmdType == SubCmd.eCmdType.Auto) //자동 명령중 Main Command 가 없으면 삭제.
                         {
-                            sql.SubCmdDAL.Delete( subCmd );
-                            logger.I( $"SubCmd Deleted - ID={subCmd.ID}, CommandID={subCmd.CmdID}" );
+                            sql.SubCmdDAL.Delete(subCmd);
+                            logger.I($"SubCmd Deleted - ID={subCmd.ID}, CommandID={subCmd.CmdID}");
                         }
                     }
 
-                    switch ( subCmd.Type )
+                    switch (subCmd.Type)
                     {
                         case SubCmd.eType.Move:
                             this.CurrentSubCommand = subCmd;
-                            this.Move( subCmd );
+                            this.Move(subCmd);
                             break;
 
                         case SubCmd.eType.Load:
                             this.CurrentSubCommand = subCmd;
-                            this.LoadCarrier( subCmd );
+                            this.LoadCarrier(subCmd);
                             break;
 
                         case SubCmd.eType.Unload:
                             this.CurrentSubCommand = subCmd;
-                            this.UnloadCarrier( subCmd );
+                            this.UnloadCarrier(subCmd);
                             break;
 
                         case SubCmd.eType.Charge:
                             this.CurrentSubCommand = subCmd;
-                            this.BatteryCharge( subCmd );
+                            this.BatteryCharge(subCmd);
                             break;
                         default:
                             break;
                     }
                 }
-                catch ( ThreadInterruptedException threadInterruptedException )
+                catch (ThreadInterruptedException threadInterruptedException)
                 {
                 }
-                catch ( Exception exception )
+                catch (Exception exception)
                 {
-                    logger.E( exception );
+                    logger.E(exception);
                 }
                 finally
                 {
-                    LockUtils.Wait( 500 );
+                    LockUtils.Wait(500);
                 }
             }
-            logger.D( "Vehicle - _ThSubCmdWorker Dispose" );
+            logger.D("Vehicle - _ThSubCmdWorker Dispose");
         }
         #endregion
 
@@ -487,21 +535,21 @@ namespace VehicleControlSystem.ControlLayer
             this.autoManager.ProcessAlarm(23);
         }
 
-        void Move( SubCmd sub )
+        void Move(SubCmd sub)
         {
-            if ( this.MoveTo( sub.TargetID ) )
+            if (this.MoveTo(sub.TargetID))
             {
-                sql.SubCmdDAL.Delete( sub );
+                sql.SubCmdDAL.Delete(sub);
             }
             else
             {
-                if ( this.ObstacleStateProperty == eObstacleState.Blocked )
+                if (this.ObstacleStateProperty == eObstacleState.Blocked)
                 {
                 }
             }
         }
 
-        bool MoveTo( string pointID )
+        bool MoveTo(string pointID)
         {
             //this.BuzzerOnOff(true, eBuzzerKind.StartWarn);
             ////TimerUtils.Once(3000, BuzzerOnOff, false, eBuzzerKind.StartWarn );
@@ -510,14 +558,14 @@ namespace VehicleControlSystem.ControlLayer
 
             this.OnMoveReady?.Invoke();
 
-            var moveReadyBuzzerTime = sql.ConfigDal.GetValueToInt( ConstString.BuzzerStartReadyTime );
-            Thread.Sleep( moveReadyBuzzerTime );
+            var moveReadyBuzzerTime = sql.ConfigDal.GetValueToInt(ConstString.BuzzerStartReadyTime);
+            Thread.Sleep(moveReadyBuzzerTime);
 
             this.OnMoving?.Invoke();
             this.IsMoving = true;
 
             //this.BuzzerOnOff(true, eBuzzerKind.Moving);
-            this.motion.MoveToPoint( pointID, 100 );
+            this.motion.MoveToPoint(pointID, 100);
 
             bool result = Wait4MoveDone();
             this.IsMoving = false;
@@ -533,17 +581,17 @@ namespace VehicleControlSystem.ControlLayer
             long st = SwUtils.CurrentTimeMillis;
 
             //Todo: 이동시 확인 사항들.
-            while ( true )
+            while (true)
             {
-                Thread.Sleep( 5 );
+                Thread.Sleep(5);
 
-                if ( SwUtils.Gt( st, waitTime ) )
+                if (SwUtils.Gt(st, waitTime))
                 {
                     //Todo: 이동시간 초과 시 동작들.
                     break;
                 }
 
-                if ( this.ObstacleStateProperty == eObstacleState.Blocked )
+                if (this.ObstacleStateProperty == eObstacleState.Blocked)
                     return false;
 
                 //Todo: 이동중 명령이 삭제 되면 처리 할일들.
@@ -555,70 +603,70 @@ namespace VehicleControlSystem.ControlLayer
             return true;
         }
 
-        public bool LoadCarrier( SubCmd sub )
+        public bool LoadCarrier(SubCmd sub)
         {
-            var route = sql.RouteDal.GetRoute( sub.TargetID );
+            var route = sql.RouteDal.GetRoute(sub.TargetID);
 
-            if ( !CorrectPosition( route, this.CurrentPosition ) )
+            if (!CorrectPosition(route, this.CurrentPosition))
             {
-                this.autoManager.ProcessAlarm( 20 );
+                this.autoManager.ProcessAlarm(20);
                 return false; //Alarm
             }
 
             int result = this.clamp.Unlock_Sync();
-            if ( result != 0 )
+            if (result != 0)
             {
-                this.autoManager.ProcessAlarm( result );
+                this.autoManager.ProcessAlarm(result);
                 return false;
             }
 
-            result = this.PIOAndLoad( sub.TargetID );
-            if ( result != 0 )
+            result = this.PIOAndLoad(sub.TargetID);
+            if (result != 0)
             {
-                this.autoManager.ProcessAlarm( result );
+                this.autoManager.ProcessAlarm(result);
                 return false;
             }
 
             result = this.clamp.Lock_Sync();
-            if ( result != 0 )
+            if (result != 0)
             {
-                this.autoManager.ProcessAlarm( result );
+                this.autoManager.ProcessAlarm(result);
                 return false;
             }
 
             //Load, Unload 가 끝나면 메인 Command 를 완료 했다고 판다.
-            sql.CommandDAL.UpdateState( sub.CmdID, eCommandState.Complete );
-            sql.SubCmdDAL.Delete( sub );
+            sql.CommandDAL.UpdateState(sub.CmdID, eCommandState.Complete);
+            sql.SubCmdDAL.Delete(sub);
 
             return true;
         }
 
-        public bool UnloadCarrier( SubCmd sub )
+        public bool UnloadCarrier(SubCmd sub)
         {
-            var route = sql.RouteDal.GetRoute( sub.TargetID );
+            var route = sql.RouteDal.GetRoute(sub.TargetID);
 
-            if ( !CorrectPosition( route, this.CurrentPosition ) )
+            if (!CorrectPosition(route, this.CurrentPosition))
             {
-                this.autoManager.ProcessAlarm( 21 );
+                this.autoManager.ProcessAlarm(21);
                 return false; //Alarm
             }
 
             int result = this.clamp.Unlock_Sync();
-            if ( result != 0 )
+            if (result != 0)
             {
-                this.autoManager.ProcessAlarm( result );
+                this.autoManager.ProcessAlarm(result);
                 return false;
             }
 
-            result = this.PIOAndUnload( sub.TargetID );
-            if ( result != 0 )
+            result = this.PIOAndUnload(sub.TargetID);
+            if (result != 0)
             {
-                this.autoManager.ProcessAlarm( result );
+                this.autoManager.ProcessAlarm(result);
                 return false;
             }
 
-            sql.CommandDAL.UpdateState( sub.CmdID, eCommandState.Complete );
-            sql.SubCmdDAL.Delete( sub );
+            sql.CommandDAL.UpdateState(sub.CmdID, eCommandState.Complete);
+            sql.SubCmdDAL.Delete(sub);
 
             return true;
         }
@@ -629,7 +677,7 @@ namespace VehicleControlSystem.ControlLayer
         /// </summary>
         /// <param name="sub"></param>
         /// <returns></returns>
-        public bool BatteryCharge( SubCmd sub )
+        public bool BatteryCharge(SubCmd sub)
         {
             var route = sql.RouteDal.GetRoute(sub.TargetID);
 
@@ -711,21 +759,21 @@ namespace VehicleControlSystem.ControlLayer
         #region Check Method
         bool CheckObstacle()
         {
-            if ( this.iO.IsOn( "IN_OBSTRUCTION_DETECT_SAFETY" ) || this.iO.IsOn( "IN_OBSTRUCTION_DETECT_ERROR" ) )
+            if (this.iO.IsOn("IN_OBSTRUCTION_DETECT_SAFETY") || this.iO.IsOn("IN_OBSTRUCTION_DETECT_ERROR"))
             {
                 this.motion.Stop();
                 this.ObstacleStateProperty = eObstacleState.Abnormal;
                 return true;
             }
 
-            if ( this.iO.IsOn( "IN_OBSTRUCTION_DETECT_STOP" ) )
+            if (this.iO.IsOn("IN_OBSTRUCTION_DETECT_STOP"))
             {
                 this.motion.Stop();
                 this.ObstacleStateProperty = eObstacleState.Blocked;
                 return true;
             }
 
-            if ( this.iO.IsOn( "IN_OBSTRUCTION_DETECT_SLOW" ) )
+            if (this.iO.IsOn("IN_OBSTRUCTION_DETECT_SLOW"))
             {
                 this.motion.SlowStop();
                 this.ObstacleStateProperty = eObstacleState.Decelerate;
@@ -742,67 +790,67 @@ namespace VehicleControlSystem.ControlLayer
         #region Machanical Method
 
         #region Conveyor
-        int OnOffConveyor( bool isOn, bool isCW = false )
+        int OnOffConveyor(bool isOn, bool isCW = false)
         {
-            if ( IsInverterError() )
+            if (IsInverterError())
                 return 16;
 
-            if ( isCW )
-                this.iO.OutputOn( "OUT_CV_CWCCW" );
+            if (isCW)
+                this.iO.OutputOn("OUT_CV_CWCCW");
             else
-                this.iO.OutputOff( "OUT_CV_CWCCW" );
+                this.iO.OutputOff("OUT_CV_CWCCW");
 
-            if ( isOn )
-                this.iO.OutputOn( "OUT_CV_RUN" );
+            if (isOn)
+                this.iO.OutputOn("OUT_CV_RUN");
             else
-                this.iO.OutputOff( "OUT_CV_RUN" );
+                this.iO.OutputOff("OUT_CV_RUN");
 
             return 0;
         }
 
-        void SetConveyorSpeed( bool IsHight )
+        void SetConveyorSpeed(bool IsHight)
         {
-            if ( IsHight )
-                this.iO.WriteOutputIO( "OUT_CV_DA", true );
+            if (IsHight)
+                this.iO.WriteOutputIO("OUT_CV_DA", true);
             else
-                this.iO.WriteOutputIO( "OUT_CV_DA", false );
+                this.iO.WriteOutputIO("OUT_CV_DA", false);
         }
 
         /// <summary>
         /// 입구 감지 로딩시 감속 사용
         /// </summary>
         /// <returns></returns>
-        bool IsDetectedLoadStart() => this.iO.IsOn( "IN_CV_DETECT_00" );
+        bool IsDetectedLoadStart() => this.iO.IsOn("IN_CV_DETECT_00");
 
         /// <summary>
         /// 실물 감지
         /// </summary>
         /// <returns></returns>
-        public bool IsDetectedCenter() => this.iO.IsOn( "IN_CV_DETECT_01" );
+        public bool IsDetectedCenter() => this.iO.IsOn("IN_CV_DETECT_01");
 
-        bool IsDetectedLoadStop() => this.iO.IsOn( "IN_CV_DETECT_02" );
-        bool IsInverterError() => this.iO.IsOn( "IN_CV_ERROR" );
-        bool IsLifterPositinCheck() => this.iO.IsOn( "IN_LIFTER_POSITION_DETECT" );
-        bool IsLifterDuplication() => this.iO.IsOn( "IN_LIFTER_DUPLICATION_DETECT" );
-        bool IsPIOInterLockOn() => this.iO.IsOn( "OUT_PIO_INTERLOCK" );
+        bool IsDetectedLoadStop() => this.iO.IsOn("IN_CV_DETECT_02");
+        bool IsInverterError() => this.iO.IsOn("IN_CV_ERROR");
+        bool IsLifterPositinCheck() => this.iO.IsOn("IN_LIFTER_POSITION_DETECT");
+        bool IsLifterDuplication() => this.iO.IsOn("IN_LIFTER_DUPLICATION_DETECT");
+        bool IsPIOInterLockOn() => this.iO.IsOn("OUT_PIO_INTERLOCK");
 
         int Load_Carrier()
         {
-            if ( IsDetectedCenter() )
+            if (IsDetectedCenter())
                 return 9;
 
-            OnOffConveyor( true, true );
+            OnOffConveyor(true, true);
 
             long sTime = SwUtils.CurrentTimeMillis;
-            while ( true )
+            while (true)
             {
-                if ( SwUtils.Gt( sTime, 20 * ConstUtils.ONE_SECOND ) ) //Wait 20Sec
+                if (SwUtils.Gt(sTime, 20 * ConstUtils.ONE_SECOND)) //Wait 20Sec
                 {
-                    OnOffConveyor( false, true );
+                    OnOffConveyor(false, true);
                     return 10;
                 }
 
-                if ( IsDetectedLoadStart() )
+                if (IsDetectedLoadStart())
                     break;
             }
 
@@ -811,34 +859,34 @@ namespace VehicleControlSystem.ControlLayer
 
         int UnloadCarrier()
         {
-            if ( !IsDetectedLoadStart() )
+            if (!IsDetectedLoadStart())
                 return 11;
 
-            OnOffConveyor( true, true );
+            OnOffConveyor(true, true);
 
             long sTime = SwUtils.CurrentTimeMillis;
-            while ( true )
+            while (true)
             {
-                if ( SwUtils.Gt( sTime, 20 * ConstUtils.ONE_SECOND ) ) //Wait 20Sec
+                if (SwUtils.Gt(sTime, 20 * ConstUtils.ONE_SECOND)) //Wait 20Sec
                 {
-                    OnOffConveyor( false, true );
+                    OnOffConveyor(false, true);
                     return 12;
                 }
 
-                if ( !IsDetectedLoadStart() )
+                if (!IsDetectedLoadStart())
                     break;
             }
 
             return 0;
         }
 
-        public int PIOAndLoad( string targetName )
+        public int PIOAndLoad(string targetName)
         {
 #if SIMULATION
             PIOClear();
             loggerPIO.I($"Start Load PIO - [{targetName}]");
             this.OnPIOStart?.Invoke(true);
-            
+
             this.iO.WriteOutputIO("OUT_PIO_RECEIVE_RUN", true);
             loggerPIO.I("[Vehicle] - 4 Receive Run On");
 
@@ -957,7 +1005,7 @@ namespace VehicleControlSystem.ControlLayer
             return 0;
         }
 
-        public int PIOAndUnload( string targetName )
+        public int PIOAndUnload(string targetName)
         {
 #if SIMULATION
             PIOClear();
@@ -1067,7 +1115,7 @@ namespace VehicleControlSystem.ControlLayer
         void PIOClear()
         {
             string[] pio = { "OUT_PIO_READY", "OUT_PIO_SENDING_RUN", "OUT_PIO_SEND_COMPLITE", "OUT_PIO_RECEIVABLE", "OUT_PIO_RECEIVE_RUN", "OUT_PIO_RECIVE_COMPLITE", "OUT_PIO_INTERLOCK" };
-            pio.FwEach( x => { this.iO.OutputOff( x ); } );
+            pio.FwEach(x => { this.iO.OutputOff(x); });
         }
 
         #endregion
@@ -1077,13 +1125,26 @@ namespace VehicleControlSystem.ControlLayer
         #region Hardware Create Method
         void CreateSteering()
         {
-            this.steering = new Steering( this.iO, this.sql, this.eventAggregator );
+            this.steering = new Steering(this.iO, this.sql, this.eventAggregator);
             this.steering.OnSteeringError += Steering_OnSteeringError;
+            this.steering.PropertyChanged += Steering_PropertyChanged;
+        }
+
+        private void Steering_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
+        {
+            var property = sender.GetType().GetProperty(e.PropertyName);
+            var newValue = property.GetValue(sender, null);
+
+            if (e.PropertyName.Equals("SteeringState"))
+            {
+                var v = CastTo<eSteeringState>.From<object>(newValue);
+                this.SteeringState = v;
+            }
         }
 
         void CreateClamp()
         {
-            this.clamp = new Clamp( this.sql, this.eventAggregator );
+            this.clamp = new Clamp(this.sql, this.eventAggregator);
             this.clamp.Init();
         }
 
@@ -1097,12 +1158,12 @@ namespace VehicleControlSystem.ControlLayer
         /// <param name="route"></param>
         /// <param name="currentPosition"></param>
         /// <returns></returns>
-        bool CorrectPosition( Route route, double currentPosition )
+        bool CorrectPosition(Route route, double currentPosition)
         {
             var rScale = route.ScaleValue;
             var rTolerance = route.ScaleTolerance;
             var result = currentPosition - rScale;
-            if ( rTolerance < Math.Abs( result ) )
+            if (rTolerance < Math.Abs(result))
                 return false;
 
             return true;
@@ -1114,19 +1175,19 @@ namespace VehicleControlSystem.ControlLayer
         /// </summary>
         /// <param name="no"> 0 == Off Laser</param>
         /// <returns></returns>
-        bool ChgObstacleDetectPattern( int no )
+        bool ChgObstacleDetectPattern(int no)
         {
-            var bitArray = BitUtils.ChgBitArray( 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.obstacleBitList.ForEach(b =>
+            {
+                if (bitArray[bitIndex])
+                    this.iO.OutputOff(b);
+                else
+                    this.iO.OutputOn(b);
+                bitIndex++;
+            });
 
             return true;
         }
@@ -1135,29 +1196,29 @@ namespace VehicleControlSystem.ControlLayer
         {
             int bitIndex = 0;
 
-            BitArray bitArray = new BitArray( this.obstacleBitList.Count );
-
-            this.obstacleBitList.ForEach( b =>
-             {
-                 if ( this.iO.IsOn( b ) )
-                     bitArray.Set( bitIndex, false );
-                 else
-                     bitArray.Set( bitIndex, true );
-                 bitIndex++;
-             } );
+            BitArray bitArray = new BitArray(this.obstacleBitList.Count);
 
-            return BitUtils.ChgInt32( bitArray );
+            this.obstacleBitList.ForEach(b =>
+            {
+                if (this.iO.IsOn(b))
+                    bitArray.Set(bitIndex, false);
+                else
+                    bitArray.Set(bitIndex, true);
+                bitIndex++;
+            });
+
+            return BitUtils.ChgInt32(bitArray);
         }
 
         #endregion
 
         #region Event Subscribe 
-        private void Steering_OnSteeringError( object sender, int e )
+        private void Steering_OnSteeringError(object sender, int e)
         {
-            if ( e != 0 )
+            if (e != 0)
             {
-                logger.E( $"[Steering] - Control Error {e}" );
-                this.autoManager.ProcessAlarm( e );
+                logger.E($"[Steering] - Control Error {e}");
+                this.autoManager.ProcessAlarm(e);
             }
             else
             {
@@ -1165,10 +1226,10 @@ namespace VehicleControlSystem.ControlLayer
                 {
                     EventDir = DriveControlEventArgs.eEventDir.ToFront,
                     ControlKind = DriveControlEventArgs.eControlKind.Steering,
-                    Result = FluentResults.Results.Ok<DriveControlEventArgs.eMoveDir>( DriveControlEventArgs.eMoveDir.LEFT ),
+                    Result = FluentResults.Results.Ok<DriveControlEventArgs.eMoveDir>(DriveControlEventArgs.eMoveDir.LEFT),
                 };
 
-                this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Publish( msg );
+                this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Publish(msg);
             }
 
         }

+ 18 - 0
Dev/OHV/VehicleControlSystem/VCSystem.cs

@@ -61,6 +61,8 @@ namespace VehicleControlSystem
             this.autoManager = new AutoManager(this.IO, this.eventAggregator, this.sql);
             this.scheduler = new Scheduler(eventAggregator, this.autoManager, this.sql);
             this.vehicle = new Vehicle(this.IO, this.sql, this.eventAggregator, this.autoManager);
+            this.vehicle.PropertyChanged += Vehicle_PropertyChanged;
+
             this.hostManager = new HostManager(this.eventAggregator, this.vehicle, this.sql);
 
             this.hostManager.Init();
@@ -69,6 +71,22 @@ namespace VehicleControlSystem
             this.autoManager.Init(this.vehicle);
         }
 
+        private void Vehicle_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
+        {
+            var arg = new GUIMessageEventArgs();
+            arg.Kind = GUIMessageEventArgs.eGUIMessageKind.ModelPropertyChange;
+            arg.MessageKey = MessageKey.Vehicle;
+            arg.ModelPropertyName = e.PropertyName;
+
+            var property = sender.GetType().GetProperty(e.PropertyName);
+            var newValue = property.GetValue(sender, null);
+
+            arg.ModelPropertyName = e.PropertyName;
+            arg.Args = newValue;
+
+            GUIMessageEventPublish(arg);
+        }
+
         public void CleanHisAlarm()
         {
             sql.HisAlarmDAL.Delete(20);