ScopeLimit.cs
4.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace DeviceLibrary
{
public class ScopeLimit
{
List<string> agvIPs;
//不规则图像坐标
List<Agv_Info.AgvPosition> positions;
Thread threadPoll;//监控线程
/// <summary>
/// 区域是否可用
/// </summary>
public bool Available { get; private set; } = true;
public delegate void ScopeLimitStateChangedEventHandler(string ip, bool state);
public event ScopeLimitStateChangedEventHandler ScopeLimitStateChangedEvent;
public ScopeLimit(List<Agv_Info.AgvPosition> positions)
{
agvIPs = new List<string>();
agvIPs.AddRange(new string[]
{
"10.85.199.68",
"10.85.199.69",
"10.85.199.70",
"10.85.199.71",
"10.85.199.72",
"10.85.199.73",
"10.85.199.74",
"10.85.199.80",
"10.85.199.81",
"10.85.199.114"
});
this.positions = positions;
//threadPoll = new Thread(ScopeDetecting);
//threadPoll.IsBackground = true;
//threadPoll.Start();
}
private void ScopeDetecting()
{
bool rtn;
while (true)
{
Thread.Sleep(5000);
List<string> agvs = new List<string>();
foreach (string ip in agvIPs)
{
Thread.Sleep(1000);
rtn = MiR_API.Get_Position(ip, CommonVar.agvInfo[0].Authorization, out Agv_Info.AgvPosition position);
if (rtn)
{
if (IsInPolygon(position, positions))
{
agvs.Add(ip);
}
}
}
if (agvs.Count > 0)
{
Available = false;
ScopeLimitStateChangedEvent?.Invoke(string.Join(";", agvs), Available);
}
else //不在限制区域
{
if (!Available)
{
Available = true;
ScopeLimitStateChangedEvent?.Invoke("", Available);
}
}
}
}
/// <summary>
/// 判断点是否在多边形内.
/// ----------原理----------
/// 注意到如果从P作水平向左的射线的话,如果P在多边形内部,那么这条射线与多边形的交点必为奇数,
/// 如果P在多边形外部,则交点个数必为偶数(0也在内)。
/// </summary>
/// <param name="checkPoint">要判断的点</param>
/// <param name="polygonPoints">多边形的顶点</param>
/// <returns></returns>
bool IsInPolygon(Agv_Info.AgvPosition checkPoint, List<Agv_Info.AgvPosition> polygonPoints)
{
bool inside = false;
int pointCount = polygonPoints.Count;
Agv_Info.AgvPosition p1, p2;
for (int i = 0, j = pointCount - 1; i < pointCount; j = i, i++)//第一个点和最后一个点作为第一条线,之后是第一个点和第二个点作为第二条线,之后是第二个点与第三个点,第三个点与第四个点...
{
p1 = polygonPoints[i];
p2 = polygonPoints[j];
if (checkPoint.y < p2.y)
{//p2在射线之上
if (p1.y <= checkPoint.y)
{//p1正好在射线中或者射线下方
if ((checkPoint.y - p1.y) * (p2.x - p1.x) > (checkPoint.x - p1.x) * (p2.y - p1.y))//斜率判断,在P1和P2之间且在P1P2右侧
{
//射线与多边形交点为奇数时则在多边形之内,若为偶数个交点时则在多边形之外。
//由于inside初始值为false,即交点数为零。所以当有第一个交点时,则必为奇数,则在内部,此时为inside=(!inside)
//所以当有第二个交点时,则必为偶数,则在外部,此时为inside=(!inside)
inside = (!inside);
}
}
}
else if (checkPoint.y < p1.y)
{
//p2正好在射线中或者在射线下方,p1在射线上
if ((checkPoint.y - p1.y) * (p2.x - p1.x) < (checkPoint.x - p1.x) * (p2.y - p1.y))//斜率判断,在P1和P2之间且在P1P2右侧
{
inside = (!inside);
}
}
}
return inside;
}
}
}