1

我正在开发一个 C# Winforms 应用程序,我需要确定卡车是否采用指定的路线,并以正确的顺序通过这些点。有效路线的示例如下:

ROUTE 1
入口门 1
秤门入口侧
秤门出口侧
出口门 1

ROUTE 2
入口 2
栅门入口侧
栅门出口侧
出口 2

两条路线的比例门相同,但入口和出口是我需要担心的。如果一辆卡车从 1 号门进入并从 1 号门离开,那么所走的路线是正确的。但是,如果卡车进入 2 号门并通过 1 号门离开,那么我需要发送通知。

每个门都有配置为读取点的硬件。当卡车经过读取点时,会在数据库中创建带有时间戳的记录。我设置了一个计时器,以便在指定的时间间隔内检索有效卡车 ID 的列表。然后,它检索每辆卡车在指定时间段内经过的读取点,并将这些读取点也存储在列表中。我不确定如何将“正确路线”列表与卡车通过的读取点列表进行比较。现在我的出发点是每辆卡车每天只开一次旅行,并且在我得到这个覆盖后会调整额外的旅行。

这是我的计时器代码

private void tmr_Tick(object sender, EventArgs e)
    {
        int maxTime = int.Parse(AppSettings.GetAppSetting("MaxTime"));
        List<string> _assets = new List<string>();
        List<ReadPoint> _assetReads = new List<ReadPoint>();

        //Get the list of assets to process
        DataSet ds = du.ExecuteTextCommand("SELECT DISTINCT AssetId FROM " + 
             "(SELECT a.TagId, a.AssetId, a.Description, rp.Comments, DateScanned " + 
             "FROM AssetsReads ar JOIN Assets a on ar.AssetTagID = a.AssetTagID " + 
             "JOIN ReadPointLocations rp on " + 
             "ar.ReadPointLocationsID = rp.ReadPointLocationsID) AS AssetResult " + 
             "ORDER BY AssetId");
        if (ds != null && ds.Tables[0].Rows.Count > 0)
        {
            foreach (DataRow dr in ds.Tables[0].Rows)
            {
                _assets.Add(dr["AssetId"].ToString());
            }
        }

        //Loop through and process the assets
        foreach (string asset in _assets)
        {
            ds = du.ExecuteTextCommand("SELECT a.TagId, a.AssetId, a.Description, " + 
                 "rp.ReadPointLocationId, rp.Comments, DateScanned " + 
                 "FROM AssetsReads ar JOIN Assets a on ar.AssetTagID = a.AssetTagID " + 
                 "JOIN ReadPointLocations rp on " + 
                 "ar.ReadPointLocationsID = rp.ReadPointLocationsID " + 
                 "WHERE a.AssetID = '" + asset + "' ORDER BY DateScanned");
            if (ds != null && ds.Tables[0].Rows.Count > 0)
            {
                _assetReads.Clear();

                foreach (DataRow dr in ds.Tables[0].Rows)
                {
                    ReadPoint ar = new ReadPoint();
                    ar.ReadPointLocationId = int.Parse(dr["ReadPointLocationId"].ToString());
                    ar.ReadpointName = dr["Comments"].ToString();
                    ar.DateScanned = DateTime.Parse(dr["DateScanned"].ToString());
                    _assetReads.Add(ar);
                }

                //Check to see if the asset has been seen in the last (MaxTime) minutes
                if (DateTime.Parse(_assetReads[0].DateScanned.ToString()) < DateTime.Now)
                {
                    ///////////////////////
                    //Send notification
                    ///////////////////////
                    continue;
                }

                //Determine the correct route to follow
                Route currentRoute = null;
                foreach (Route rt in _routes)
                {
                    foreach (ReadPoint rp in rt.ReadPoints)
                    {
                        if (_assetReads[0].ReadPointLocationId == rp.ReadPointLocationId)
                        {
                            currentRoute = rt;
                            break;
                        }
                    }

                    if (currentRoute != null)
                        break;
                }

                //Check if the route was correctly followed
                if (currentRoute != null)
                {
                    //////////////////////////////
                    //This is where I'm stuck
                    //////////////////////////////
                }
            }
        }
    }
4

1 回答 1

1

嗯,我想你在这里真的很近。您有一个资产(卡车)已经通过的 ReadPointLocations(门)列表,按照卡车通过大门的顺序排列。您还拥有通过这些大门的“正确”路径的列表,并且可以根据卡车首先通过的大门确定应该遵循的路径。剩下要做的就是将卡车的大门读数与预期读数对齐,并验证卡车是否通过了它应该有的所有大门,按顺序:

//Check if the route was correctly followed
if (currentRoute != null)
{
    var gatesInOrder = 0;
    for(var i=0; i<_assetReads.Length; i++)
    {
       if(_assetReads[i].ReadPointLocationId == currentRoute[gatesInOrder])
          //gate crossed in order; increment to next gate
          gatesInOrder++;           
    }
    //if we didn't get to the end of the route, send a notification
    if(gatesInOrder != currentRoute.Length)
    {
       ///////////////////////
       //Send notification
       ///////////////////////
    }
}

现在,这假设了两件事。首先,所有读取都没有错误地执行。我可以根据经验告诉您,即使在自动化系统中,位置扫描的遗漏率也非常高。这意味着如果您的入口门扫描被错过,您将无法确定卡车应该从哪个门离开;您将根据您拥有的第一个读数选择一条路线(可能是 1 号闸门),即标尺入口闸门,但由于该节点对闸门 1 和闸门 2 路径都是通用的,因此您会错误地通知卡车如果卡车从 2 号登机口离开,即使它从 2 号登机口进入,也会从错误的登机口退出。为了避免这种情况,您必须能够识别每条路线中对该路线唯一的登机口(在这种情况下, 入口和出口大门)并根据对其中一个位置的第一次门扫描确定要使用的正确路线,而不仅仅是任何位置。您现在已经选择了正确的路线,但您不会找到入口扫描;您可以检测到这一点并发送不同的“门扫描错过”通知。

其次,我们假设一旦卡车进入一条路线,它必须继续通过该路径并且不能在任何点偏离。任何事情都不能乱七八糟。因此,在一个更复杂的示例中,假设卡车还进行了简单的检查(尾灯工作、没有可见的泄漏、轮胎胎面正常、怠速时没有滚滚的烟雾等)。如果检查和称重可以按任一顺序进行,如果称重和检查的顺序与预期相反,您将错误地使用上述算法发送通知。您可以通过简单地检查是否在某个点扫描了所有正确路径的位置来天真地避免这种情况,但这不会捕捉到,例如,一辆卡车在整个过程中走错路。如果这是可能的,那么你将需要更复杂的东西,

于 2012-08-20T21:31:30.903 回答