瀏覽代碼

cleanup; README

master
Robin Thoni 7 年之前
父節點
當前提交
f87a9b3f2c

+ 57
- 17
README.md 查看文件

@@ -1,14 +1,16 @@
1 1
 Aspirobot
2 2
 =========
3
-Aspirobot is a simple(r) AI agent that vaccums dust in your rooms but leaves your jewels.
3
+Aspirobot is a simple(r) AI agent that vaccums dust in your rooms but pick up your jewels.
4 4
 
5 5
 Build
6 6
 -----
7 7
 - Command line  
8
-`cd uqac-ia-aspirobot
8
+```shell
9
+cd uqac-ia-aspirobot
9 10
 dotnet restore
10 11
 dotnet build
11
-dotnet run`
12
+dotnet run
13
+```
12 14
 
13 15
 - Visual Studio  
14 16
 Run VS, open solution, wait for package restore, click run (F5)
@@ -19,21 +21,59 @@ Run Rider, open solution, wait for package restore, click run (Shift + F10)
19 21
 Configuration
20 22
 -------------
21 23
 Some behaviors can be configured in Program.cs file:  
22
-- EnvConfig (Environment configuration)
23
-  - Height: Map height
24
-  - Width: Map width
25
-  - ActionPropability: Probability that an action occurs in the enviromnent, once per SleepTime (>=0, <=100)
26
-  - AddDustProbability: Probability that a dust is added on the map, only when an action is to be taken (>=0, <=100)
27
-  - AddJewelProbability: Probability that a jewel is added on the map, only when an action is to be taken, and AddDustProbability does not occur (>=0, <=100)
28
-  - RemoveJewelProbability: Probability that a jewel is removed from the map, only when an action is to be taken, and neither AddDustProbability nor AddJewelProbability occur (>=0, <=100)
29
-  - SleepTime: Time between each iteration in ms (>=0)
24
+- `EnvConfig` (Environment configuration)
25
+  - `Height`: Map height
26
+  - `Width`: Map width
27
+  - `ActionPropability`: Probability that an action occurs in the enviromnent, once per `EnvConfig.SleepTime` (>=0, <=100)
28
+  - `AddDustProbability`: Probability that a dust is added on the map, only when an action is to be taken (>=0, <=100)
29
+  - `AddJewelProbability`: Probability that a jewel is added on the map, only when an action is to be taken,
30
+  and `AddDustProbability` does not occur (>=0, <=100)
31
+  - `RemoveJewelProbability`: Probability that a jewel is removed from the map, only when an action is to be taken,
32
+  and neither `EnvConfig.AddDustProbability` nor `EnvConfig.AddJewelProbability` occur (>=0, <=100)
33
+  - `SleepTime`: Time between each iteration in ms (>=0)
30 34
   
31
-- AgConfig (Agent configuration)
32
-  - SleepTime: Time between each iteration in ms (>=0)
33
-  - StartX: Agent start X position (>=0, <EnvConfig.Width)
34
-  - StartY: Agent start Y position (>=0, <EnvConfig.Height)
35
-  - AutoAdjustThinkTimeInterval: Indicate if agent should try to auto adjust think time interval 
36
-  - ThinkTimeInterval: Default think time interval in ms (>=0). This variable controls how often the agent will re-evaluate the situation
35
+- `AgConfig` (Agent configuration)
36
+  - `SleepTime`: Time between each iteration in ms (>=0)
37
+  - `StartX`: Agent start X position (>=0, <`EnvConfig.Width`)
38
+  - `StartY`: Agent start Y position (>=0, <`EnvConfig.Height`)
39
+  - `AutoAdjustThinkTimeInterval`: Indicate if agent should try to auto adjust think time interval (`AgConfig.ThinkTimeInterval`)
40
+  - `ThinkTimeInterval`: Default think time interval in ms (>=0). This variable controls how often the agent will re-evaluate the situation
37 41
   
38 42
 How it works
39 43
 ------------
44
+Agent will loop forever (until killed) peforming the following operations:
45
+- Environment update: this action will force all sensors to update their data, so that the environment can be updated.
46
+  - In the FakeEnv implementation, the environment update itself from remote virtual environment, so the sensors updates do nothing.
47
+  - In a real robot implementation, the update methods of sensors would gather data and push them to the environment.
48
+- UI update: this will update the user interface.
49
+  - In the FakeEnv implementation, it draw in the standard output.
50
+  - In a real robot implementation, it would either do nothing, or update a web interface (for example)
51
+- Internal state update: Prepare internal state to be able to choose an action to do.
52
+- Choose an action: Choose the most appropriate action to do by analysing the gathered data and current internal state.
53
+- Act: Execute choosen action (go to room, vaccum, pick)
54
+- Sleep: Sleep for `AgConfig.SleepTime`ms
55
+
56
+FakeEnv implementation will loop forever (until killed) peforming the following operations:
57
+- Sleep: Sleep for `EnvConfig.SleepTime`ms
58
+- May do something: Randomly choose to do something or not using `EnvConfig.ActionPropability`
59
+    - May add dust on a random location: Randomly choose to do it or not using `EnvConfig.AddDustProbability`
60
+    - May add a jewel on a random location: Randomly choose to do it or not using `EnvConfig.AddJewelProbability`.
61
+    Can only happen if no previous action has been done.
62
+    - May remove a jewel from the first room that contains a jewel: Randomly choose to do it or not using `EnvConfig.RemoveJewelProbability`.
63
+    Can only happen if no previous action has been done.
64
+
65
+Code
66
+----
67
+This agent is coded in .NET Core (C#) using DI (Dependency Injection) and interfaces to abstract implementation
68
+and allow to run a virtual environment or a real one without changing anything in the agent implementation
69
+
70
+FakeEnv implementation starts one thread for the environment and another one for the agent.
71
+
72
+Agent logic is in `Agent/*.cs`  
73
+Agent sensors and effectors interfaces are in `Agent/Interfaces/*`  
74
+Agent FakeEnv client implementation is in `Agent/FakeEnv/*`  
75
+FakeEnv client, server, protocol and configuration are defined in `Common/*.cs`  
76
+FakeEnv server implementation is in `Environment/*.cs`  
77
+Some helper methods are defined in `Extensions/Extensions.cs`  
78
+Shared interfaces are in `Interfaces/*.cs`  
79
+Console user interface is in `UI/UiConsole.cs`

+ 7
- 24
uqac-ia-aspirobot/Agent/AgAgent.cs 查看文件

@@ -1,4 +1,5 @@
1 1
 using System;
2
+using System.Collections.Generic;
2 3
 using System.Linq;
3 4
 using System.Threading;
4 5
 using Microsoft.Extensions.DependencyInjection;
@@ -17,10 +18,6 @@ namespace uqac_ia_aspirobot.Agent
17 18
 {
18 19
     public class AgAgent
19 20
     {
20
-        private readonly IAgDustSensor _agDustSensor;
21
-        private readonly IAgBatterySensor _agBatterySensor;
22
-        private readonly IAgPickedSensor _agPickedSensor;
23
-        private readonly IAgVaccumSensor _agVaccumSensor;
24 21
 
25 22
         private readonly IAgEngineEffector _engineEffector;
26 23
 
@@ -72,14 +69,8 @@ namespace uqac_ia_aspirobot.Agent
72 69
 
73 70
         public AgAgent(IOptions<AgConfig> options,
74 71
             IEnvironment environment, AgState state, IUi ui,
75
-            IAgDustSensor agDustSensor, IAgBatterySensor agBatterySensor, IAgPickedSensor agPickedSensor, IAgVaccumSensor agVaccumSensor,
76 72
             IAgEngineEffector engineEffector, IAgVaccumEffector vaccumEffector)
77 73
         {
78
-            _agDustSensor = agDustSensor;
79
-            _agBatterySensor = agBatterySensor;
80
-            _agPickedSensor = agPickedSensor;
81
-            _agVaccumSensor = agVaccumSensor;
82
-
83 74
             _engineEffector = engineEffector;
84 75
             _vaccumEffector = vaccumEffector;
85 76
 
@@ -97,30 +88,22 @@ namespace uqac_ia_aspirobot.Agent
97 88
             var running = true;
98 89
 
99 90
             _environment.Setup();
100
-            _state.DustyRooms = _environment.FindDustyRoomsWithoutJewel();
91
+            _state.DustyRooms = new List<IRoom>();
101 92
 
102 93
             while (running)
103 94
             {
104
-                if (_options.SleepTime > 0)
105
-                {
106
-                    Thread.Sleep(_options.SleepTime);
107
-                }
108
-                UpdateSensors();
95
+                _environment.Update();
109 96
                 _ui.Update();
110 97
                 UpdateState();
111 98
                 Think();
112 99
                 Work();
100
+                if (_options.SleepTime > 0)
101
+                {
102
+                    Thread.Sleep(_options.SleepTime);
103
+                }
113 104
             }
114 105
         }
115 106
 
116
-        public void UpdateSensors()
117
-        {
118
-            _agDustSensor.Update();
119
-            _agBatterySensor.Update();
120
-            _agPickedSensor.Update();
121
-            _agVaccumSensor.Update();
122
-        }
123
-
124 107
         public void UpdateState()
125 108
         {
126 109
             if (_options.AutoAdjustThinkTimeInterval)

+ 20
- 4
uqac-ia-aspirobot/Agent/FakeEnv/AgEnvironment.cs 查看文件

@@ -1,6 +1,7 @@
1 1
 using System;
2 2
 using System.Collections.Generic;
3 3
 using Microsoft.Extensions.DependencyInjection;
4
+using uqac_ia_aspirobot.Agent.Interfaces.Sensors;
4 5
 using uqac_ia_aspirobot.Common;
5 6
 using uqac_ia_aspirobot.Extensions;
6 7
 using uqac_ia_aspirobot.Interfaces;
@@ -9,20 +10,30 @@ namespace uqac_ia_aspirobot.Agent.FakeEnv
9 10
 {
10 11
     public class AgEnvironment : IEnvironment
11 12
     {
13
+        private readonly IAgDustSensor _agDustSensor;
14
+        private readonly IAgBatterySensor _agBatterySensor;
15
+        private readonly IAgPickedSensor _agPickedSensor;
16
+        private readonly IAgVaccumSensor _agVaccumSensor;
17
+
12 18
         private readonly IServiceProvider _serviceProvider;
13 19
 
14 20
         private readonly ArClient _arClient;
15 21
 
16
-        protected int _width;
22
+        private int _width;
17 23
 
18
-        protected int _height;
24
+        private int _height;
19 25
 
20
-        protected readonly IDictionary<string, IRoom> _rooms = new Dictionary<string, IRoom>();
26
+        private readonly IDictionary<string, IRoom> _rooms = new Dictionary<string, IRoom>();
21 27
 
22
-        public AgEnvironment(IServiceProvider serviceProvider, ArClient arClient)
28
+        public AgEnvironment(IServiceProvider serviceProvider, ArClient arClient,
29
+            IAgDustSensor agDustSensor, IAgBatterySensor agBatterySensor, IAgPickedSensor agPickedSensor, IAgVaccumSensor agVaccumSensor)
23 30
         {
24 31
             _serviceProvider = serviceProvider;
25 32
             _arClient = arClient;
33
+            _agDustSensor = agDustSensor;
34
+            _agBatterySensor = agBatterySensor;
35
+            _agPickedSensor = agPickedSensor;
36
+            _agVaccumSensor = agVaccumSensor;
26 37
         }
27 38
 
28 39
         public void Setup()
@@ -49,6 +60,11 @@ namespace uqac_ia_aspirobot.Agent.FakeEnv
49 60
                 room.Update();
50 61
                 return true;
51 62
             });
63
+
64
+            _agDustSensor.Update();
65
+            _agBatterySensor.Update();
66
+            _agPickedSensor.Update();
67
+            _agVaccumSensor.Update();
52 68
         }
53 69
 
54 70
         protected string GetKey(int x, int y)

+ 2
- 5
uqac-ia-aspirobot/Agent/FakeEnv/Effectors/AgEngineEffector.cs 查看文件

@@ -9,8 +9,6 @@ namespace uqac_ia_aspirobot.Agent.FakeEnv.Effectors
9 9
     {
10 10
         private readonly IAgBatterySensor _agBatterySensor;
11 11
 
12
-        private readonly AgConfig _options;
13
-
14 12
         public int X { get; protected set; }
15 13
 
16 14
         public int Y { get; protected set; }
@@ -18,9 +16,8 @@ namespace uqac_ia_aspirobot.Agent.FakeEnv.Effectors
18 16
         public AgEngineEffector(IOptions<AgConfig> options, IAgBatterySensor agBatterySensor)
19 17
         {
20 18
             _agBatterySensor = agBatterySensor;
21
-            _options = options.Value;
22
-            X = _options.StartX;
23
-            Y = _options.StartY;
19
+            X = options.Value.StartX;
20
+            Y = options.Value.StartY;
24 21
         }
25 22
 
26 23
         public void MoveTo(int x, int y)

+ 0
- 1
uqac-ia-aspirobot/Agent/FakeEnv/Sensors/AgDustSensor.cs 查看文件

@@ -14,7 +14,6 @@ namespace uqac_ia_aspirobot.Agent.FakeEnv.Sensors
14 14
 
15 15
         public void Update()
16 16
         {
17
-            _environment.Update();
18 17
         }
19 18
     }
20 19
 }

+ 1
- 1
uqac-ia-aspirobot/Agent/Interfaces/Effectors/IAgEngineEffector.cs 查看文件

@@ -1,6 +1,6 @@
1 1
 namespace uqac_ia_aspirobot.Agent.Interfaces.Effectors
2 2
 {
3
-    public interface IAgEngineEffector
3
+    public interface IAgEngineEffector : IEffector
4 4
     {
5 5
 
6 6
         int X { get; }

+ 1
- 1
uqac-ia-aspirobot/Agent/Interfaces/Effectors/IAgVaccumEffector.cs 查看文件

@@ -1,6 +1,6 @@
1 1
 namespace uqac_ia_aspirobot.Agent.Interfaces.Effectors
2 2
 {
3
-    public interface IAgVaccumEffector
3
+    public interface IAgVaccumEffector : IEffector
4 4
     {
5 5
         void Vaccum();
6 6
         void Pick();

+ 7
- 0
uqac-ia-aspirobot/Agent/Interfaces/Effectors/IEffector.cs 查看文件

@@ -0,0 +1,7 @@
1
+namespace uqac_ia_aspirobot.Agent.Interfaces.Effectors
2
+{
3
+    public interface IEffector
4
+    {
5
+
6
+    }
7
+}

+ 1
- 2
uqac-ia-aspirobot/Common/ArServer.cs 查看文件

@@ -1,5 +1,4 @@
1
-using System;
2
-using Microsoft.Extensions.Options;
1
+using Microsoft.Extensions.Options;
3 2
 using System.IO.Pipes;
4 3
 using System.Threading;
5 4
 using uqac_ia_aspirobot.Extensions;

+ 6
- 2
uqac-ia-aspirobot/Environment/EnvEnvironment.cs 查看文件

@@ -11,9 +11,9 @@ namespace uqac_ia_aspirobot.Environment
11 11
         private readonly IServiceProvider _serviceProvider;
12 12
         private readonly EnvConfig _options;
13 13
 
14
-        protected readonly IDictionary<string, IRoom> _rooms = new Dictionary<string, IRoom>();
14
+        private readonly IDictionary<string, IRoom> _rooms = new Dictionary<string, IRoom>();
15 15
 
16
-        protected string GetKey(int x, int y)
16
+        private string GetKey(int x, int y)
17 17
         {
18 18
             return $"{x},{y}";
19 19
         }
@@ -52,5 +52,9 @@ namespace uqac_ia_aspirobot.Environment
52 52
         {
53 53
             return _rooms[GetKey(x, y)];
54 54
         }
55
+
56
+        public void Update()
57
+        {
58
+        }
55 59
     }
56 60
 }

+ 4
- 1
uqac-ia-aspirobot/Environment/EnvThread.cs 查看文件

@@ -94,7 +94,10 @@ namespace uqac_ia_aspirobot.Environment
94 94
 
95 95
             while (running)
96 96
             {
97
-                Thread.Sleep(_config.SleepTime);
97
+                if (_config.SleepTime > 0)
98
+                {
99
+                    Thread.Sleep(_config.SleepTime);
100
+                }
98 101
                 var action = GenerateAction();
99 102
                 if (action == Actions.AddDust || action == Actions.AddJewel)
100 103
                 {

+ 2
- 0
uqac-ia-aspirobot/Interfaces/IEnvironment.cs 查看文件

@@ -20,5 +20,7 @@ namespace uqac_ia_aspirobot.Interfaces
20 20
         int GetHeight();
21 21
 
22 22
         IRoom GetRoom(int x, int y);
23
+
24
+        void Update();
23 25
     }
24 26
 }

+ 1
- 5
uqac-ia-aspirobot/UI/UiConsole.cs 查看文件

@@ -149,11 +149,7 @@ namespace uqac_ia_aspirobot.UI
149 149
                 {
150 150
                     var state = _environment.GetRoomState(x, y);
151 151
                     ConsoleColor? color = null;
152
-                    if (state == RoomState.Clean)
153
-                    {
154
-                        color = null;
155
-                    }
156
-                    else if (state == RoomState.Dust)
152
+                    if (state == RoomState.Dust)
157 153
                     {
158 154
                         color = ConsoleColor.Gray;
159 155
                     }

Loading…
取消
儲存