Skip to content

Commit

Permalink
update:
Browse files Browse the repository at this point in the history
1. improve symbol loading performance
2. imrpove fuzzy search performance
  • Loading branch information
randolfly committed Jan 22, 2025
1 parent 1776c25 commit d05e21c
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 7 deletions.
23 changes: 23 additions & 0 deletions doc/roadmap/Feature Update.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
## Custom Ignore Variables Pattern

when load twincat project variables, sometimes it's nice to ignore some variables, such as:

![](assets/Pasted%20image%2020250122154205.png)

- `axis.PlcToNc.xxx`

When multiple axis are used, these unnecessary variables will significantly slower the program, hence it's good to provide a filter to remove such variables. Moreover, it's better to provide a custom filter (of cource some default rules are provides)?



## Remove Multiple Variables

when a variable is passed into a function block, whether it's by `VAR_INPUT` or `VAR_IN_OUT`, the twincat ads api will return handles for the variable out and in the function block, although they are basically the identical one.

![](assets/Pasted%20image%2020250122154749.png)

To identify the duplicated variables, notice that they have same last name:
- `axis.NcToPlc.ActPos` => `NcToPlc.ActPos`
- `power_motor.Axis.NcToPlc.ActPos`=>`Axis.NcToPlc.ActPos`

the idea is to retain the variable with shortest name in the group of variables.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions src/TwincatToolbox/Extensions/ISymbolExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using TwinCAT.TypeSystem;

namespace TwincatToolbox.Extensions;
public static class ISymbolExtension
{
// note: this method can cause problems if the symbol name is not unique
public static string GetSymbolName(this ISymbol symbol) {
return symbol.InstanceName.ToLower();
}
}
3 changes: 2 additions & 1 deletion src/TwincatToolbox/Models/SymbolInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@

namespace TwincatToolbox.Models;

public partial class SymbolInfo(ISymbol symbol)
// todo: ¼ì²éÕâÀïµÄ partial classÊÇ·ñÓбØÒª
public class SymbolInfo(ISymbol symbol)
{
public ISymbol Symbol { get; set; } = symbol;
public string Name => string.Join(".",
Expand Down
71 changes: 69 additions & 2 deletions src/TwincatToolbox/Services/AdsComService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using TwinCAT.TypeSystem;
using TwinCAT.ValueAccess;

using TwincatToolbox.Extensions;
using TwincatToolbox.Models;
using TwincatToolbox.Services.IService;

Expand Down Expand Up @@ -56,11 +57,77 @@ public void DisconnectAdsServer() {

/// <summary>
/// 获取所有可行的Symbols
/// 1. 通过SymbolLoader加载所有Symbols
/// 2. 递归遍历所有Symbols(仅获取MAIN和GVL下的Symbols)
/// 3. 将Symbol转化为SymbolTree,同时执行重复项剔除
/// 4. 将SymbolTree转化为List<SymbolInfo>,返回
/// </summary>
/// <returns>符号列表</returns>
/// <returns></returns>
public List<SymbolInfo> GetAvailableSymbols() {
var settings = new SymbolLoaderSettings(SymbolsLoadMode.VirtualTree,
ValueAccessMode.IndexGroupOffset);
ValueAccessMode.SymbolicByHandle);
var symbolLoader = SymbolLoaderFactory.Create(adsClient, settings);
var symbols = symbolLoader.Symbols;

// contains name of parent symbols, used to avoid duplicate symbols(symbolTree)
var symbolNameSet = new HashSet<string>();
var symbolList = new List<SymbolInfo>();

foreach (var symbol in symbols)
{
if (symbol.InstanceName is ("MAIN" or "GVL"))
{
LoadSymbolTreeBFS(symbol, ref symbolList);
}
}

return symbolList;

void LoadSymbolTreeBFS(ISymbol root, ref List<SymbolInfo> symbolList) {
var transverseOrder = new Queue<ISymbol>();

var symbolLoadQueue = new Queue<ISymbol>();
symbolLoadQueue.Enqueue(root);
symbolNameSet.Add(root.GetSymbolName());

while (symbolLoadQueue.Count > 0)
{
var currentSymbol = symbolLoadQueue.Dequeue();
transverseOrder.Enqueue(currentSymbol);
foreach (var subSymbol in currentSymbol.SubSymbols)
{
if (!symbolNameSet.Contains(subSymbol.GetSymbolName(),
StringComparer.CurrentCultureIgnoreCase))
{
symbolLoadQueue.Enqueue(subSymbol);
symbolNameSet.Add(subSymbol.GetSymbolName());
}
}
}

while (transverseOrder.Count > 0)
{
var symbol = transverseOrder.Dequeue();
if(symbol.SubSymbols.Count == 0)
{
symbolList.Add(new SymbolInfo(symbol));
}
}

// remove first element, which is the root symbol(virtual symbol)
symbolList.RemoveAt(0);
}

}


/// <summary>
/// 获取所有可行的Symbols
/// </summary>
/// <returns>符号列表</returns>
public List<SymbolInfo> GetAvailableSymbols_bak() {
var settings = new SymbolLoaderSettings(SymbolsLoadMode.VirtualTree,
ValueAccessMode.SymbolicByHandle);
var symbolLoader = SymbolLoaderFactory.Create(adsClient, settings);
var symbols = symbolLoader.Symbols;

Expand Down
12 changes: 8 additions & 4 deletions src/TwincatToolbox/ViewModels/DataLogViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ private void OnGetAvailableSymbols()
Debug.WriteLine("Ads server is not connected.");
return;
}

AvailableSymbols = _adsComService.GetAvailableSymbols();
AvailableSymbols.Sort((a, b) => a.Name.CompareTo(b.Name));
Debug.WriteLine("Available symbols: {0}", AvailableSymbols.Count());
Expand Down Expand Up @@ -132,13 +132,17 @@ public List<SymbolInfo> SearchSymbols(IList<SymbolInfo> sourceList)
{
if (string.IsNullOrEmpty((SearchText))) return sourceList.ToList();
var searchResults = sourceList
.Where(s=>Fuzz.PartialRatio(SearchText.ToLower(), s.Name.ToLower()) > 85)
.ToList();
Debug.WriteLine("Search results: {0}", searchResults.Count());
.OrderByDescending(s=>GetSimilarityScore(SearchText, s))
.Take(20).ToList();
// Debug.WriteLine("Search results: {0}", searchResults.Count());

return searchResults;
}

public int GetSimilarityScore(string searchText, SymbolInfo symbolInfo) {
return Fuzz.PartialTokenSetRatio(searchText, symbolInfo.Name.ToLower());
}

private void UpdateLogSymbol()
{
var logSearchSymbols = SearchSymbols(LogSymbols);
Expand Down

0 comments on commit d05e21c

Please sign in to comment.