1

トラックが指定されたルートをたどり、正しい順序でポイントを通過したかどうかを判断する必要がある C# Winforms アプリを開発しています。有効なルートの例は次のとおりです。

ROUTE 1
入口ゲート1
スケールゲート入口側
スケールゲート出口側
出口ゲート1

ROUTE 2
入口ゲート2
スケールゲート入口側
スケールゲート出口側
出口ゲート2

スケールゲートは両方のルートで同じですが、私が心配する必要があるのは入口と出口のゲートです。トラックがゲート 1 から入り、ゲート 1 から出る場合、たどったルートは正しいものでした。ただし、トラックがゲート 2 に入り、ゲート 1 から出る場合は、通知を送信する必要があります。

各ゲートには、読み取りポイントとして構成されたハードウェアがあります。トラックが読み取りポイントを通過すると、データベースにタイムスタンプ付きのレコードが作成されます。指定された間隔で有効なトラック ID のリストを取得するようにタイマーを設定しました。次に、指定された時間内に各トラックが通過した読み取りポイントを取得し、それらもリストに格納します。よくわからないのは、「正しいルート」リストと、トラックが通過した読み取りポイントのリストを比較する方法です。現在、各トラックは 1 日に 1 回だけ移動するという前提で作業を進めています。

タイマーのコードは次のとおりです

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
       ///////////////////////
    }
}

さて、これは2つのことを前提としています。まず、すべての読み取りがエラーなしで実行されること。自動化されたシステムであっても、位置スキャンが非常に高い頻度で見落とされることは、経験からわかります。これは、入口ゲートスキャンを見逃した場合、トラックがどのゲートを通過する必要があるかを判断できないことを意味します。スケールエントリゲートである最初の読み取りに基づいてルート(おそらくゲート1)を選択しますが、そのノードはゲート1とゲート2の両方のパスに共通であるため、トラックに誤って通知しますトラックがゲート2から出た場合でも、ゲート2から出た場合は、間違ったゲートから出ました。これを回避するには、各ルートでそのルートに固有のゲート(この場合)を識別できる必要があります。 、入口ゲートと出口ゲート)、場所だけでなく、それらの場所の1つに対する最初のゲートスキャンに基づいて、使用する適切なルートを特定します。これで適切なルートを選択できましたが、入口ゲートスキャンは見つかりません。これを検出して、別の「ゲートスキャン失敗」通知を送信できます。

次に、トラックがルートに入ると、そのパスを継続する必要があり、どの時点でも逸脱することはできないと想定します。順不同で何もできません。したがって、より複雑な例では、トラックも簡単な検査を受けたとしましょう(テールライトが機能している、目に見える漏れがない、タイヤのトレッドが正常である、アイドル時にうねる煙がないなど)。検査と計量がどちらかの順序で行われる可能性がある場合、計量と検査が予想とは逆の順序で行われたとすると、上記のアルゴリズムを使用して誤って通知を送信することになります。ある時点ですべての適切なパスの場所がスキャンされたことを確認するだけで、これを素朴に回避できますが、たとえば、トラックが全体を間違って通過することはありません。それが可能であれば、もっと複雑なものが必要になります。

于 2012-08-20T21:31:30.903 に答える