Compare commits

...

2 Commits

18 changed files with 1003 additions and 113 deletions

View File

@ -381,5 +381,13 @@
PID = 1 PID = 1
} }
public enum CabecasModelo
{
Target = 0,
Vegetation = 1,
Cana = 2,
Segmentation = 3,
}
} }
} }

View File

@ -527,7 +527,9 @@ namespace AgroBase.Models
AtuPercentualInicioPulverizacao = 85, AtuPercentualInicioPulverizacao = 85,
AtuPressaoLinha = 18, AtuPressaoLinha = 18,
AtuAgitadorModo = ModoAgitadorCalda.SemAgitacao, AtuAgitadorModo = ModoAgitadorCalda.SemAgitacao,
AtuModoControle = ModoControleBomba.PID AtuModoControle = ModoControleBomba.PID,
AtuModeloCabeca = CabecasModelo.Target,
AtuClasseAlvo = "erva"
}; };
op.Parametros.ModulosMandatorios.AddRange(new List<OperacaoModulosMandatoriosModel>() op.Parametros.ModulosMandatorios.AddRange(new List<OperacaoModulosMandatoriosModel>()
{ {
@ -640,6 +642,8 @@ namespace AgroBase.Models
AtuPressaoLinha = 18, AtuPressaoLinha = 18,
AtuAgitadorModo = ModoAgitadorCalda.Continuo, AtuAgitadorModo = ModoAgitadorCalda.Continuo,
AtuModoControle = ModoControleBomba.PID, AtuModoControle = ModoControleBomba.PID,
AtuModeloCabeca = CabecasModelo.Target,
AtuClasseAlvo = "erva"
}; };
op.Parametros.ModulosMandatorios.AddRange(new List<OperacaoModulosMandatoriosModel>() op.Parametros.ModulosMandatorios.AddRange(new List<OperacaoModulosMandatoriosModel>()
{ {
@ -782,6 +786,8 @@ namespace AgroBase.Models
AtuPressaoLinha = 18, AtuPressaoLinha = 18,
AtuAgitadorModo = ModoAgitadorCalda.SemAgitacao, AtuAgitadorModo = ModoAgitadorCalda.SemAgitacao,
AtuModoControle = ModoControleBomba.PID, AtuModoControle = ModoControleBomba.PID,
AtuModeloCabeca = CabecasModelo.Target,
AtuClasseAlvo = "erva"
}; };
op.Parametros.ModulosMandatorios.AddRange(new List<OperacaoModulosMandatoriosModel>() op.Parametros.ModulosMandatorios.AddRange(new List<OperacaoModulosMandatoriosModel>()
{ {
@ -922,6 +928,8 @@ namespace AgroBase.Models
AtuPressaoLinha = 18, AtuPressaoLinha = 18,
AtuAgitadorModo = ModoAgitadorCalda.SemAgitacao, AtuAgitadorModo = ModoAgitadorCalda.SemAgitacao,
AtuModoControle = ModoControleBomba.PID, AtuModoControle = ModoControleBomba.PID,
AtuModeloCabeca = CabecasModelo.Target,
AtuClasseAlvo = "erva"
}; };
op.Parametros.ModulosMandatorios.AddRange(new List<OperacaoModulosMandatoriosModel>() op.Parametros.ModulosMandatorios.AddRange(new List<OperacaoModulosMandatoriosModel>()
{ {
@ -1022,6 +1030,8 @@ namespace AgroBase.Models
AtuPressaoLinha = 18, AtuPressaoLinha = 18,
AtuAgitadorModo = ModoAgitadorCalda.SemAgitacao, AtuAgitadorModo = ModoAgitadorCalda.SemAgitacao,
AtuModoControle = ModoControleBomba.PID, AtuModoControle = ModoControleBomba.PID,
AtuModeloCabeca = CabecasModelo.Target,
AtuClasseAlvo = "erva"
}; };
op.Parametros.ModulosMandatorios.AddRange(new List<OperacaoModulosMandatoriosModel>() op.Parametros.ModulosMandatorios.AddRange(new List<OperacaoModulosMandatoriosModel>()
{ {

View File

@ -549,6 +549,34 @@ namespace AgroBase.Models.Operacoes
} }
} }
private CabecasModelo _atuModeloCabeca;
public CabecasModelo AtuModeloCabeca
{
get => _atuModeloCabeca;
set
{
if (_atuModeloCabeca != value)
{
_atuModeloCabeca = value;
OnPropertyChanged(nameof(AtuModeloCabeca));
}
}
}
private string _atuClasseAlvo;
public string AtuClasseAlvo
{
get => _atuClasseAlvo;
set
{
if (_atuClasseAlvo != value)
{
_atuClasseAlvo = value;
OnPropertyChanged(nameof(AtuClasseAlvo));
}
}
}
private bool _movAuxilioSonar; private bool _movAuxilioSonar;
public bool MovAuxilioSonar public bool MovAuxilioSonar
{ {

View File

@ -1014,8 +1014,6 @@ namespace AgroBase.Models
double distanciaUltimoPonto = GPSUtils.DistanciaEntrePontos(_posicaoAtual, ultimoPonto.Posicao); double distanciaUltimoPonto = GPSUtils.DistanciaEntrePontos(_posicaoAtual, ultimoPonto.Posicao);
//int idxCorredorDentro = VerificaEquipamentoDentroCorredor(_posicaoAtual);
if (!double.IsNaN(distanciaUltimoPonto) && !double.IsInfinity(distanciaUltimoPonto) && distanciaUltimoPonto < 5.0) if (!double.IsNaN(distanciaUltimoPonto) && !double.IsInfinity(distanciaUltimoPonto) && distanciaUltimoPonto < 5.0)
{ {
msg = $"Início no meio da rua ignorado: robô está a {distanciaUltimoPonto:0.00}m do fim. Nova operação começará do zero."; msg = $"Início no meio da rua ignorado: robô está a {distanciaUltimoPonto:0.00}m do fim. Nova operação começará do zero.";
@ -1028,6 +1026,7 @@ namespace AgroBase.Models
(bool noCoredor, var idxPontoMaisProximo) = VerificaEquipamentoDentroCorredorMontado(_posicaoAtual); (bool noCoredor, var idxPontoMaisProximo) = VerificaEquipamentoDentroCorredorMontado(_posicaoAtual);
if (noCoredor && idxPontoMaisProximo >= 0 && idxPontoMaisProximo < _TrajetoriaFixa.Count) if (noCoredor && idxPontoMaisProximo >= 0 && idxPontoMaisProximo < _TrajetoriaFixa.Count)
{ {
int idxCorredorDentro = VerificaEquipamentoDentroCorredor(_posicaoAtual);
for (int i = 0; i <= idxPontoMaisProximo; i++) for (int i = 0; i <= idxPontoMaisProximo; i++)
{ {
_TrajetoriaFixa[i].Visitado = true; _TrajetoriaFixa[i].Visitado = true;
@ -2289,6 +2288,22 @@ namespace AgroBase.Models
if (!PontoInicialAdicionado) if (!PontoInicialAdicionado)
{ {
_trajetoriaFixa.Add(PontoInicial); _trajetoriaFixa.Add(PontoInicial);
if (false)
{
GPSModel SegundoPonto = GPSUtils.ProjetarPontoDeslocado(CorredorAtual.FirstOrDefault(), (VariaveisEquipamento.DistanciaEntreBicosCm / 100.0 / 2.0), anguloProjetar1);
PontoTrajetoriaModel PontoSecundario = new PontoTrajetoriaModel(TipoPontoRua.LigacaoEntrada)
{
idxCorredor = idx,
idxPonto = _trajetoriaFixa.Count(),
idxPontoCorredor = _trajetoriaFixa.Count(x => x.idxCorredor == idx),
Posicao = SegundoPonto,
Direcao = direcaoAtual,
Orientacao = GPSUtils.CalcularOrientacao(ultimoPontoTrajetoria.Posicao, SegundoPonto),
Visitado = false,
LarguraCorredor = larguraCorredorMenor
};
_trajetoriaFixa.Add(PontoSecundario);
}
} }
foreach (GPSModel pontoAtual in CorredorAtual) foreach (GPSModel pontoAtual in CorredorAtual)
@ -2399,6 +2414,8 @@ namespace AgroBase.Models
AutonomiaCorredor.Iniciar(); AutonomiaCorredor.Iniciar();
VerificacaoInicialMeioRuaConcluida = false;
AtualizarDadosTrajetoria(); AtualizarDadosTrajetoria();
LoopAtualizaDados(); LoopAtualizaDados();

View File

@ -4,6 +4,7 @@ using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using static AgroBase.Models.Enums; using static AgroBase.Models.Enums;
using static AgroBase.Models.Operadores.OperadoresModels; using static AgroBase.Models.Operadores.OperadoresModels;
@ -303,6 +304,7 @@ namespace AgroBase.Services.Operadores
RedisService.AtualizarCampos( RedisService.AtualizarCampos(
CtxKey.DadosOperacao, CtxKey.DadosOperacao,
("id", op.ID ?? ""),
("configurado", true), ("configurado", true),
("modo", op.Parametros?.Modo ?? ModoOperacao.NaoDefinido), ("modo", op.Parametros?.Modo ?? ModoOperacao.NaoDefinido),
("tempo_aguardar_inicio_operacao", op.TempoIniciarOperacao), ("tempo_aguardar_inicio_operacao", op.TempoIniciarOperacao),
@ -355,7 +357,9 @@ namespace AgroBase.Services.Operadores
percent_vertical_deteccao = pControle.AtuPercentualInicioPulverizacao / 100.0, percent_vertical_deteccao = pControle.AtuPercentualInicioPulverizacao / 100.0,
height_area_deteccao = pControle.AtuAlturaAreaPulverizacao / 100.0, height_area_deteccao = pControle.AtuAlturaAreaPulverizacao / 100.0,
pct_erva_bico_on = pControle.AtuPercentualErvasBicoOn / 100.0, pct_erva_bico_on = pControle.AtuPercentualErvasBicoOn / 100.0,
pct_erva_bico_off = pControle.AtuPercentualErvasBicoOff / 100.0 pct_erva_bico_off = pControle.AtuPercentualErvasBicoOff / 100.0,
modelo_cabeca = pControle.AtuModeloCabeca.ToString().ToLower(),
modelo_classe_alvo = pControle.AtuClasseAlvo,
} }
), ),
("Snr", new ("Snr", new
@ -367,14 +371,13 @@ namespace AgroBase.Services.Operadores
) )
); );
if ((op.Parametros?.ControleAutomatico ?? false) && (op.Trajetoria?._TrajetoriaFixa?.Any() ?? false)) _ = SolicitarAtualizacaoMapaAsync(op).ContinueWith(
{ task =>
var comando = new
{ {
cmd = HealthWorkerCommandType.AtualizarPontosMapa Variaveis.MostrarLog($"[HealthWorkerService] Erro atualizando mapa: {task.Exception?.GetBaseException().Message}");
}; },
RedisService.Publish(CmdKey.HealthWorkerRx, JsonConvert.SerializeObject(comando)); TaskContinuationOptions.OnlyOnFaulted
} );
//Console.WriteLine("Dados de operacao atualizados com sucesso!"); //Console.WriteLine("Dados de operacao atualizados com sucesso!");
@ -386,6 +389,99 @@ namespace AgroBase.Services.Operadores
} }
} }
private static readonly SemaphoreSlim _mapaSync = new SemaphoreSlim(1, 1);
private static async Task<bool> SolicitarAtualizacaoMapaAsync(OperacaoModel op)
{
Variaveis.MostrarLog($"[HealthWorkerService] SolicitarAtualizacaoMapaAsync solicitado");
if (!await _mapaSync.WaitAsync(0))
return false;
try
{
for (int tentativa = 1; tentativa <= 3; tentativa++)
{
if (!ReferenceEquals(op, Variaveis.OperacaoEmAndamento))
return false;
bool atualizado = await AtualizarPontosMapa(op);
if (atualizado)
return true;
if (tentativa < 3)
await Task.Delay(200);
Variaveis.MostrarLog($"[HealthWorkerService] SolicitarAtualizacaoMapaAsync. Tentativa={tentativa}");
}
return false;
}
finally
{
_mapaSync.Release();
}
}
private static async Task<bool> AtualizarPontosMapa(OperacaoModel op)
{
if (!(op?.Parametros?.ControleAutomatico ?? false) || !(op?.Trajetoria?._TrajetoriaFixa?.Any() ?? false))
return false;
var commandId = Guid.NewGuid().ToString("N");
var operationId = op?.ID ?? "";
var mapRevision = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
RedisService.AtualizarCampos(
CtxKey.DadosOperacao,
("mapa_revisao_solicitada", mapRevision),
("mapa_operacao_id", operationId),
("mapa_command_id", commandId),
("mapa_status", "pendente")
);
var comando = new
{
cmd = HealthWorkerCommandType.AtualizarPontosMapa,
command_id = commandId,
operation_id = operationId,
map_revision = mapRevision
};
long assinantes = RedisService.Publish(
CmdKey.HealthWorkerRx,
JsonConvert.SerializeObject(comando)
);
bool sucesso = await AguardarMapaAplicadoAsync(commandId, mapRevision, TimeSpan.FromSeconds(3));
return assinantes > 0 && sucesso;
}
private static async Task<bool> AguardarMapaAplicadoAsync(string commandId, long revision, TimeSpan timeout)
{
var limite = DateTime.UtcNow + timeout;
while (DateTime.UtcNow < limite)
{
string ultimoCommandId = RedisService.GetField(CtxKey.DadosHealthWorker, "ultimo_comando_mapa", "");
long revisaoAplicada = RedisService.GetField(CtxKey.DadosHealthWorker, "mapa_revisao_aplicada", 0L);
string status = RedisService.GetField(CtxKey.DadosHealthWorker, "mapa_status", "");
if (ultimoCommandId == commandId && revisaoAplicada == revision && status == "aplicado")
{
return true;
}
if (ultimoCommandId == commandId && status == "erro")
{
return false;
}
await Task.Delay(100);
}
return false;
}
public static void AtualizarDadosControleOperacao() public static void AtualizarDadosControleOperacao()
{ {
try try

View File

@ -145,10 +145,23 @@ namespace AgroBase.Services
} }
} }
public static void Publish(string canal, string mensagem) public static long Publish(string canal, string mensagem)
{ {
var pub = _redis.GetSubscriber(); try
pub.Publish(canal, mensagem); {
if (_redis == null || !_redis.IsConnected)
return 0;
var pub = _redis.GetSubscriber();
return pub.Publish(canal, mensagem);
}
catch (Exception ex)
{
Console.WriteLine(
$"❌ Erro ao publicar em '{canal}': {ex.Message}"
);
return 0;
}
} }
public static void Subscribe(string canal, Action<string> callback) public static void Subscribe(string canal, Action<string> callback)

View File

@ -4,6 +4,8 @@
from __future__ import annotations from __future__ import annotations
import time import time
import threading
import unicodedata
from pathlib import Path from pathlib import Path
from typing import Dict, List, Tuple from typing import Dict, List, Tuple
@ -18,9 +20,9 @@ except Exception:
DEFAULT_CHANNEL_ORDER = ["R", "G", "B", "RE", "NIR"] DEFAULT_CHANNEL_ORDER = ["R", "G", "B", "RE", "NIR"]
TARGET_COLORS_RGB = { HEAD_COLORS_RGB = {
0: (30, 30, 30), # background 0: (30, 30, 30), # background
1: (255, 70, 30), # target / alvo pulverizável 1: (255, 70, 30), # classe positiva da cabeça binária selecionada
255: (0, 0, 0), # ignore/fallback 255: (0, 0, 0), # ignore/fallback
} }
@ -50,7 +52,7 @@ def get_input_channel_indices(config: dict) -> List[int]:
class MultiSpecSegformerService: class MultiSpecSegformerService:
""" """
Runtime oficial Weed Worker v1. Runtime oficial Weed Worker multi-head.
Contrato: Contrato:
input: input:
@ -66,20 +68,67 @@ class MultiSpecSegformerService:
- SegFormer multi-head - SegFormer multi-head
- resize fullres - resize fullres
- argmax - argmax
e expõe saída: e expõe as saídas multi-head. Este serviço executa somente uma das
cabeças operacionais por inferência:
- target_mask - target_mask
- vegetation_mask
- cana_mask
- semantic_mask (convertida para binário pela classe escolhida)
output: output:
np.ndarray uint8 HxW np.ndarray uint8 HxW
0 = fundo / não pulverizar máscara binária uint8 HxW da cabeça selecionada
1 = alvo pulverizável 0 = classe negativa
1 = classe positiva
semantic_mask nunca é entregue diretamente ao WeedDetector. Quando
selecionada, ela é convertida para 0/1 usando semantic_target_class.
""" """
TARGET_MODES = ("target_direct", "direct_target", "target_head", "target", "spray", "operational") MODE_ALIASES = {
"target": "target",
"target_direct": "target",
"direct_target": "target",
"target_head": "target",
"spray": "target",
"operational": "target",
"vegetation": "vegetation",
"vegetation_direct": "vegetation",
"direct_vegetation": "vegetation",
"vegetation_head": "vegetation",
"vegetacao": "vegetation",
"cana": "cana",
"cana_direct": "cana",
"direct_cana": "cana",
"cana_head": "cana",
"semantic": "semantic",
"semantic_direct": "semantic",
"direct_semantic": "semantic",
"semantic_head": "semantic",
"segmentacao": "semantic",
}
OUTPUT_BY_HEAD = {
"target": "target_mask",
"vegetation": "vegetation_mask",
"cana": "cana_mask",
"semantic": "semantic_mask",
}
SEMANTIC_CLASS_IDS = {
"chao": 0,
"cana": 1,
"erva": 2,
}
def __init__(self, model_config: dict, mostrar_log=print): def __init__(self, model_config: dict, mostrar_log=print):
self.config = model_config or {} self.config = model_config or {}
self.mostrar_log = mostrar_log self.mostrar_log = mostrar_log
self._runtime_lock = threading.RLock()
self._runtime_generation = 0
self.input_channel_names = get_input_channel_names(self.config) self.input_channel_names = get_input_channel_names(self.config)
self.input_channel_indices = get_input_channel_indices(self.config) self.input_channel_indices = get_input_channel_indices(self.config)
@ -87,8 +136,22 @@ class MultiSpecSegformerService:
self.runtime_backend = str(self.config.get("runtime_backend", "onnx")).lower() self.runtime_backend = str(self.config.get("runtime_backend", "onnx")).lower()
self.onnx_provider = str(self.config.get("onnx_provider", "tensorrt")).lower() self.onnx_provider = str(self.config.get("onnx_provider", "tensorrt")).lower()
self.runtime_mode = str(self.config.get("runtime_mode", "target_direct")).lower() # runtime_mode é a fonte única da verdade. onnx_output_mode permanece
self.onnx_output_mode = str(self.config.get("onnx_output_mode", self.runtime_mode)).lower() # apenas como fallback para configs antigas que não possuem runtime_mode.
configured_mode = self.config.get(
"runtime_mode",
self.config.get("onnx_output_mode", "target"),
)
self.runtime_mode = str(configured_mode).strip().lower()
self.selected_head = self._normalizar_head(self.runtime_mode)
self.selected_output_name = self.OUTPUT_BY_HEAD[self.selected_head]
self.semantic_target_class = self._normalizar_semantic_target_class(
self.config.get("semantic_target_class", "erva")
)
self.semantic_target_id = self.SEMANTIC_CLASS_IDS[self.semantic_target_class]
# Mantido para compatibilidade com logs/código externo antigo.
self.onnx_output_mode = self.runtime_mode
self.onnx_output_kind = str(self.config.get("onnx_output_kind", "mask")).lower() self.onnx_output_kind = str(self.config.get("onnx_output_kind", "mask")).lower()
# No contrato v1, a normalização está dentro do ONNX. # No contrato v1, a normalização está dentro do ONNX.
@ -121,6 +184,8 @@ class MultiSpecSegformerService:
f"[WEED_ONNX] backend=onnx " f"[WEED_ONNX] backend=onnx "
f"provider={self.onnx_provider} " f"provider={self.onnx_provider} "
f"runtime_mode={self.runtime_mode} " f"runtime_mode={self.runtime_mode} "
f"selected_head={self.selected_head} "
f"selected_output={self.selected_output_name} "
f"output_kind={self.onnx_output_kind} " f"output_kind={self.onnx_output_kind} "
f"preprocess_norm={self.onnx_preprocess_norm}" f"preprocess_norm={self.onnx_preprocess_norm}"
) )
@ -129,6 +194,40 @@ class MultiSpecSegformerService:
# Inicialização / contrato # Inicialização / contrato
# ============================================================ # ============================================================
@classmethod
def _normalizar_head(cls, mode: str) -> str:
normalized = str(mode).strip().lower()
head = cls.MODE_ALIASES.get(normalized)
if head is None:
raise RuntimeError(
f"runtime_mode inválido para Weed Worker: {mode!r}. "
"Use 'target', 'vegetation', 'cana' ou 'semantic'."
)
return head
@staticmethod
def _normalizar_texto(value) -> str:
text = unicodedata.normalize("NFKD", str(value).strip().lower())
return "".join(ch for ch in text if not unicodedata.combining(ch))
@classmethod
def _normalizar_semantic_target_class(cls, value) -> str:
normalized = cls._normalizar_texto(value)
aliases = {
"0": "chao", "chao": "chao", "solo": "chao", "background": "chao", "bg": "chao",
"1": "cana", "cana": "cana", "sugarcane": "cana",
"2": "erva", "erva": "erva", "weed": "erva",
}
result = aliases.get(normalized)
if result is None:
raise RuntimeError(
f"semantic_target_class inválida: {value!r}. "
"Use 'chao', 'cana' ou 'erva'."
)
return result
def _validar_contrato_runtime(self): def _validar_contrato_runtime(self):
if self.runtime_backend not in ("onnx", "tensorrt", "trt"): if self.runtime_backend not in ("onnx", "tensorrt", "trt"):
raise RuntimeError( raise RuntimeError(
@ -136,17 +235,9 @@ class MultiSpecSegformerService:
"Use runtime_backend='onnx'." "Use runtime_backend='onnx'."
) )
if self.runtime_mode not in self.TARGET_MODES: # A normalização no __init__ já valida o modo e define a cabeça.
raise RuntimeError( if self.selected_head not in self.OUTPUT_BY_HEAD:
f"runtime_mode inválido para Weed Worker v1: {self.runtime_mode}. " raise RuntimeError(f"Cabeça operacional inválida: {self.selected_head}")
"Use runtime_mode='target_direct'."
)
if self.onnx_output_mode not in self.TARGET_MODES:
raise RuntimeError(
f"onnx_output_mode inválido para Weed Worker v1: {self.onnx_output_mode}. "
"Use onnx_output_mode='target_direct'."
)
if self.onnx_output_kind != "mask": if self.onnx_output_kind != "mask":
raise RuntimeError( raise RuntimeError(
@ -249,23 +340,91 @@ class MultiSpecSegformerService:
self.mostrar_log(f"[WEED_ONNX] providers ativos={self.onnx_session.get_providers()}") self.mostrar_log(f"[WEED_ONNX] providers ativos={self.onnx_session.get_providers()}")
def _selecionar_outputs_runtime(self, output_names: List[str]) -> List[str]: def _selecionar_outputs_runtime(self, output_names: List[str]) -> List[str]:
target_outputs = [ output_lookup = {str(name).lower(): str(name) for name in output_names}
n for n in output_names expected = self.selected_output_name.lower()
if "target" in str(n).lower()
]
if target_outputs: if expected in output_lookup:
return target_outputs return [output_lookup[expected]]
# Fallback seguro: se o ONNX tiver só uma saída, usa ela.
if len(output_names) == 1:
return list(output_names)
raise RuntimeError( raise RuntimeError(
"Não encontrei saída target no ONNX. " f"A saída necessária {self.selected_output_name!r} não existe no ONNX. "
f"Outputs disponíveis: {output_names}" f"Cabeça selecionada={self.selected_head!r}; "
f"outputs disponíveis={output_names}."
) )
def atualizar_runtime_mode(self, runtime_mode, semantic_target_class=None) -> bool:
"""Troca a cabeça operacional sem recriar a sessão ONNX.
Retorna True quando a configuração efetivamente mudou. Uma inferência
que já estava em andamento é descartada e o novo modo vale no frame
seguinte.
"""
new_mode = str(runtime_mode).strip().lower()
new_head = self._normalizar_head(new_mode)
new_output = self.OUTPUT_BY_HEAD[new_head]
if semantic_target_class is None:
semantic_target_class = self.semantic_target_class
new_semantic_class = self._normalizar_semantic_target_class(semantic_target_class)
new_semantic_id = self.SEMANTIC_CLASS_IDS[new_semantic_class]
output_lookup = {str(n).lower(): str(n) for n in self.onnx_output_names}
actual_output = output_lookup.get(new_output.lower())
if actual_output is None:
raise RuntimeError(
f"A saída necessária {new_output!r} não existe no ONNX. "
f"Outputs disponíveis={self.onnx_output_names}."
)
with self._runtime_lock:
changed = (
new_head != self.selected_head
or (new_head == "semantic" and new_semantic_id != self.semantic_target_id)
)
if not changed:
return False
old_desc = self._runtime_description_unlocked()
self.runtime_mode = new_head
self.onnx_output_mode = new_head
self.selected_head = new_head
self.selected_output_name = actual_output
self.onnx_run_output_names = [actual_output]
self.semantic_target_class = new_semantic_class
self.semantic_target_id = new_semantic_id
self._runtime_generation += 1
self._limpar_cache_unlocked()
new_desc = self._runtime_description_unlocked()
self.mostrar_log(f"[WEED_ONNX][MODE] {old_desc} -> {new_desc}")
return True
def atualizar_config(self, config: dict) -> bool:
config = config or {}
mode = config.get("runtime_mode", config.get("onnx_output_mode", self.runtime_mode))
semantic_class = config.get("semantic_target_class", self.semantic_target_class)
changed = self.atualizar_runtime_mode(mode, semantic_class)
self.config.update(config)
return changed
def _runtime_description_unlocked(self) -> str:
if self.selected_head == "semantic":
return f"semantic[{self.semantic_target_class}={self.semantic_target_id}]"
return self.selected_head
def _limpar_cache_unlocked(self):
self._ultimo_predictions = None
self._ultimo_probs = None
self._ultimo_predictions_full = {}
def limpar_cache_runtime(self):
with self._runtime_lock:
self._limpar_cache_unlocked()
def get_runtime_generation(self) -> int:
with self._runtime_lock:
return int(self._runtime_generation)
# ============================================================ # ============================================================
# Inferência # Inferência
# ============================================================ # ============================================================
@ -295,8 +454,16 @@ class MultiSpecSegformerService:
t_forward0 = time.perf_counter() t_forward0 = time.perf_counter()
with self._runtime_lock:
run_output_names = list(self.onnx_run_output_names)
selected_head = self.selected_head
selected_output_name = self.selected_output_name
semantic_target_class = self.semantic_target_class
semantic_target_id = self.semantic_target_id
runtime_generation = self._runtime_generation
outputs = self.onnx_session.run( outputs = self.onnx_session.run(
self.onnx_run_output_names, run_output_names,
{self.onnx_input_name: x}, {self.onnx_input_name: x},
) )
@ -307,22 +474,39 @@ class MultiSpecSegformerService:
if len(outputs) < 1: if len(outputs) < 1:
raise RuntimeError("ONNX não retornou nenhuma saída.") raise RuntimeError("ONNX não retornou nenhuma saída.")
target_mask = self._onnx_output_to_mask(outputs[0], out_hw) raw_mask = self._onnx_output_to_mask(outputs[0], out_hw)
if selected_head == "semantic":
selected_mask = (raw_mask == semantic_target_id).astype(np.uint8)
else:
selected_mask = raw_mask
# Defesa do contrato do WeedDetector: a saída final deste serviço é
# sempre binária. As cabeças binárias já devem conter 0/1; semantic
# foi explicitamente convertida acima.
invalid_values = np.logical_and(selected_mask != 0, selected_mask != 1)
if np.any(invalid_values):
values = np.unique(selected_mask[invalid_values])[:10].tolist()
raise RuntimeError(
f"A saída {selected_output_name!r} não é binária. "
f"Valores inválidos encontrados: {values}"
)
post_ms = (time.perf_counter() - t_post0) * 1000.0 post_ms = (time.perf_counter() - t_post0) * 1000.0
total_ms = (time.perf_counter() - t_total0) * 1000.0 total_ms = (time.perf_counter() - t_total0) * 1000.0
self._ultimo_tensor = chw predictions_full = {
self._ultimo_predictions = target_mask "selected": selected_mask,
self._ultimo_probs = None "selected_head": selected_head,
"selected_output": selected_output_name,
self._ultimo_predictions_full = { "semantic_target_class": semantic_target_class if selected_head == "semantic" else None,
"target": target_mask, "semantic_target_id": semantic_target_id if selected_head == "semantic" else None,
"target_head": target_mask, "target": selected_mask if selected_head == "target" else None,
"target_op": target_mask, "target_head": selected_mask if selected_head == "target" else None,
"semantic": None, "target_op": selected_mask if selected_head == "target" else None,
"vegetation": None, "semantic": raw_mask if selected_head == "semantic" else None,
"cana": None, "vegetation": selected_mask if selected_head == "vegetation" else None,
"cana": selected_mask if selected_head == "cana" else None,
"probs": None, "probs": None,
"infer_ms": total_ms, "infer_ms": total_ms,
@ -330,17 +514,29 @@ class MultiSpecSegformerService:
"forward_ms": forward_ms, "forward_ms": forward_ms,
"post_ms": post_ms, "post_ms": post_ms,
"runtime_mode": self.runtime_mode, "runtime_mode": selected_head,
"runtime_generation": runtime_generation,
"backend": "onnx", "backend": "onnx",
"providers": self.onnx_session.get_providers(), "providers": self.onnx_session.get_providers(),
"outputs": self.onnx_output_names, "outputs": self.onnx_output_names,
"outputs_executados": self.onnx_run_output_names, "outputs_executados": run_output_names,
} }
if return_full: # A configuração pode mudar enquanto o provider executa. A verificação
return dict(self._ultimo_predictions_full) # e a publicação do cache ficam no mesmo lock para impedir que um frame
# antigo reapareça depois de atualizar_runtime_mode() limpar o estado.
with self._runtime_lock:
if runtime_generation != self._runtime_generation:
return None
self._ultimo_tensor = chw
self._ultimo_predictions = selected_mask
self._ultimo_probs = None
self._ultimo_predictions_full = predictions_full
return target_mask if return_full:
return dict(predictions_full)
return selected_mask
def _prepare_input_numpy_onnx(self, tensor5_chw: np.ndarray): def _prepare_input_numpy_onnx(self, tensor5_chw: np.ndarray):
if tensor5_chw is None: if tensor5_chw is None:
@ -435,7 +631,7 @@ class MultiSpecSegformerService:
Não roda inferência aqui. Não roda inferência aqui.
Usa: Usa:
- tensor multiespectral cacheado - tensor multiespectral cacheado
- target_mask cacheada - máscara binária cacheada da cabeça selecionada
""" """
tensor = tensor5_chw if tensor5_chw is not None else self._ultimo_tensor tensor = tensor5_chw if tensor5_chw is not None else self._ultimo_tensor
pred = predictions if predictions is not None else self._ultimo_predictions pred = predictions if predictions is not None else self._ultimo_predictions
@ -449,7 +645,7 @@ class MultiSpecSegformerService:
if pred is None: if pred is None:
return rgb_bgr, None, rgb_bgr, None, None return rgb_bgr, None, rgb_bgr, None, None
seg_rgb = self.ids_to_rgb(pred, TARGET_COLORS_RGB) seg_rgb = self.ids_to_rgb(pred, HEAD_COLORS_RGB)
overlay_rgb = cv2.addWeighted(rgb, 1.0 - alpha, seg_rgb, alpha, 0.0) overlay_rgb = cv2.addWeighted(rgb, 1.0 - alpha, seg_rgb, alpha, 0.0)
seg_bgr = cv2.cvtColor(seg_rgb, cv2.COLOR_RGB2BGR) seg_bgr = cv2.cvtColor(seg_rgb, cv2.COLOR_RGB2BGR)

View File

@ -80,14 +80,59 @@ def main():
time.sleep(0.1) time.sleep(0.1)
def redis_callback(dados): def redis_callback(dados):
acao = HealthWorkerCommandType(dados.get("cmd", 0)) try:
acao = HealthWorkerCommandType(int(dados.get("cmd", 0)))
except Exception as e:
mostrar_log(f"Comando inválido: {dados} | {e}")
return
if acao == HealthWorkerCommandType.AtualizarPontosMapa: if acao != HealthWorkerCommandType.AtualizarPontosMapa:
try: return
ContextoGlobalRedis._atualizar_pontos_mapa()
except Exception as e: command_id = str(dados.get("command_id", ""))
mostrar_log(f"Erro ao atualizar pontos do mapa: {e}") operation_id = str(dados.get("operation_id", ""))
mostrar_log("Dados de mapa da Operacao atualizados com sucesso!") map_revision = dados.get("map_revision")
try:
resultado = ContextoGlobalRedis._atualizar_pontos_mapa(
operation_id=operation_id,
map_revision=map_revision,
)
if not resultado.get("sucesso", False):
raise RuntimeError(resultado.get("erro", "Falha desconhecida"))
ContextoGlobalRedis.atualizar_ctx_dict(
CtxKey.DadosHealthWorker,
ultimo_comando_mapa=command_id,
mapa_operacao_id=operation_id,
mapa_revisao_aplicada=map_revision,
mapa_pontos_aplicados=resultado["quantidade"],
mapa_status="aplicado",
mapa_erro="",
mapa_aplicado_em=time.time(),
)
mostrar_log(
f"Mapa aplicado | command_id={command_id} | "
f"operacao={operation_id} | "
f"revisao={map_revision} | "
f"pontos={resultado['quantidade']}"
)
except Exception as e:
ContextoGlobalRedis.atualizar_ctx_dict(
CtxKey.DadosHealthWorker,
ultimo_comando_mapa=command_id,
mapa_operacao_id=operation_id,
mapa_revisao_aplicada=map_revision,
mapa_status="erro",
mapa_erro=str(e),
)
mostrar_log(
f"Erro ao aplicar mapa | command_id={command_id} | {e}"
)
def inicializar(): def inicializar():
mostrar_log("🚀 Iniciando Health Worker...") mostrar_log("🚀 Iniciando Health Worker...")

View File

@ -1330,11 +1330,60 @@ class ContextoGlobalRedis:
return False return False
@classmethod @classmethod
def _atualizar_pontos_mapa(cls): def _atualizar_pontos_mapa(cls, operation_id=None, map_revision=None):
try:
operacao = cls.get_operacao()
operacao_atual = str(operacao.get("mapa_operacao_id", ""))
if operation_id and operacao_atual != operation_id:
return {
"sucesso": False,
"erro": (
f"Operação divergente: esperado={operation_id}, "
f"atual={operacao_atual}"
),
}
# Conversão atual dos pontos...
pontos_info = cls._converter_pontos_mapa(operacao)
if not pontos_info:
return {
"sucesso": False,
"erro": "Nenhum ponto válido foi produzido",
}
atualizado = cls.atualizar_ctx_dict(
CtxKey.DadosOperacao,
pontos_mapa=pontos_info,
mapa_revisao_processada=map_revision,
)
cls._atualizar_mpc(do_manager=False, iniciar_operacao=False)
if not atualizado:
return {
"sucesso": False,
"erro": "Falha ao gravar pontos_mapa no Redis",
}
return {
"sucesso": True,
"quantidade": len(pontos_info),
}
except Exception as e:
return {
"sucesso": False,
"erro": str(e),
}
@classmethod
def _converter_pontos_mapa(cls, operacao):
pontos_info = [] pontos_info = []
try: try:
operacao = cls.get_operacao()
dados_dir = cls._dict(operacao.get("Dir", {})) dados_dir = cls._dict(operacao.get("Dir", {}))
tipo_controle = cls._int( tipo_controle = cls._int(
dados_dir.get("tipo_controle", TiposControladorDirecional.Manual.value), dados_dir.get("tipo_controle", TiposControladorDirecional.Manual.value),
@ -1343,7 +1392,7 @@ class ContextoGlobalRedis:
if tipo_controle != TiposControladorDirecional.MPC.value: if tipo_controle != TiposControladorDirecional.MPC.value:
cls.atualizar_ctx_dict(CtxKey.DadosOperacao, pontos_mapa=[]) cls.atualizar_ctx_dict(CtxKey.DadosOperacao, pontos_mapa=[])
return return pontos_info
dados_mpc = cls._dict(dados_dir.get("mpc", {})) dados_mpc = cls._dict(dados_dir.get("mpc", {}))
pontos = dados_mpc.get("pontos", []) or [] pontos = dados_mpc.get("pontos", []) or []
@ -1351,12 +1400,12 @@ class ContextoGlobalRedis:
if not pontos: if not pontos:
cls.atualizar_ctx_dict(CtxKey.DadosOperacao, pontos_mapa=[]) cls.atualizar_ctx_dict(CtxKey.DadosOperacao, pontos_mapa=[])
return return pontos_info
if not isinstance(p_ref, (list, tuple)) or len(p_ref) < 2: if not isinstance(p_ref, (list, tuple)) or len(p_ref) < 2:
mostrar_log("Ponto de referência do mapa ausente/inválido. Não foi possível converter pontos MPC.") mostrar_log("Ponto de referência do mapa ausente/inválido. Não foi possível converter pontos MPC.")
cls.atualizar_ctx_dict(CtxKey.DadosOperacao, pontos_mapa=[]) cls.atualizar_ctx_dict(CtxKey.DadosOperacao, pontos_mapa=[])
return return pontos_info
from shared.gps_handler import GPSHandler from shared.gps_handler import GPSHandler
@ -1378,18 +1427,12 @@ class ContextoGlobalRedis:
except Exception as e: except Exception as e:
mostrar_log(f"Erro ao converter ponto MPC: {p} | {e}") mostrar_log(f"Erro ao converter ponto MPC: {p} | {e}")
cls.atualizar_ctx_dict(
CtxKey.DadosOperacao,
pontos_mapa=pontos_info,
)
if pontos_info:
cls._atualizar_mpc(do_manager=False, iniciar_operacao=False)
except Exception as e: except Exception as e:
mostrar_log(f"Erro ao atualizar pontos do mapa: {e}") mostrar_log(f"Erro ao atualizar pontos do mapa: {e}")
cls.atualizar_ctx_dict(CtxKey.DadosOperacao, pontos_mapa=pontos_info) cls.atualizar_ctx_dict(CtxKey.DadosOperacao, pontos_mapa=pontos_info)
return pontos_info
# ============================================================ # ============================================================
# Mapeamento de parâmetros # Mapeamento de parâmetros
# ============================================================ # ============================================================

View File

@ -861,37 +861,35 @@ class CameraManager:
self._ultima_saude_ts = time.time() self._ultima_saude_ts = time.time()
try: try:
# O lock protege somente a identidade da sessão da câmera. # Mantém a referência estável durante leitura/publicação da saúde.
# fechar_camera_manager aguarda esta seção curta terminar.
with self._vida_lock: with self._vida_lock:
camera_atual = self.camera camera_atual = self.camera
generation = self._camera_generation
if camera_atual is not None: if camera_atual is not None:
if pipeline_ia is None: if pipeline_ia is None:
pipeline_ia = self._avaliar_saude_pipeline_ia() pipeline_ia = self._avaliar_saude_pipeline_ia()
camera_atual.atualizar_saude(pipeline_ia=pipeline_ia)
camera_atual.atualizar_saude(pipeline_ia=pipeline_ia) elif self.mx_id is not None:
from camera_worker.manager import definir_saude_camera
elif self.mx_id is not None: definir_saude_camera(
from camera_worker.manager import definir_saude_camera self.mx_id,
StatusModulo.DESCONECTADO,
definir_saude_camera( 0,
self.mx_id, ["desconectado"],
StatusModulo.DESCONECTADO, False,
0, {},
["desconectado"], disp=T_Code.Cam,
False, conectado=False,
{}, )
disp=T_Code.Cam,
conectado=False,
)
except Exception as e: except Exception as e:
self.mostrar_log(f"[saude] erro: {e}") self.mostrar_log(f"[saude] erro: {e}")
def _atualizar_config_dinamica_detector(self, intervalo_s=0.20): def _atualizar_config_dinamica_detector(self, intervalo_s=0.20):
""" """
Atualiza config do detector em baixa frequência. Atualiza config do detector e a cabeça ONNX em baixa frequência.
Isso permite refletir: Isso permite refletir:
- velocidade atual; - velocidade atual;
@ -917,6 +915,32 @@ class CameraManager:
if self.weed_detector is not None: if self.weed_detector is not None:
self.weed_detector.atualizar_config(cfg) self.weed_detector.atualizar_config(cfg)
mode_changed = False
if self.model_svc is not None:
mode_changed = self.model_svc.atualizar_config(cfg)
if mode_changed:
# Remove qualquer máscara/detecção gerada no modo anterior.
with self._pred_lock:
self._pred_cache = {}
self._pred_consumido_ts = 0.0
self._ultimo_predictions = None
self._ultimo_predictions_full = None
# O detector não deve manter na memória espacial regiões
# derivadas da máscara velha.
if self.weed_detector is not None:
method = getattr(self.weed_detector, "limpar_memoria_alvo", None)
if not callable(method):
method = getattr(self.weed_detector, "_inicializar_estado", None)
if callable(method):
method()
self.mostrar_log(
"[weed][MODEL] modo atualizado dinamicamente; "
"caches anteriores descartados"
)
self._ultimo_config_update_ts = agora self._ultimo_config_update_ts = agora
except Exception as e: except Exception as e:
@ -1537,6 +1561,16 @@ class CameraManager:
pred_ts = time.time() pred_ts = time.time()
with self._pred_lock: with self._pred_lock:
infer_mode_generation = int(
infer_full.get("runtime_generation", -1)
)
current_mode_generation = int(
self.model_svc.get_runtime_generation()
)
if infer_mode_generation != current_mode_generation:
self.perf.inc("infer_descartada_troca_modo")
continue
if ( if (
self._pred_cache.get("predictions") is not None self._pred_cache.get("predictions") is not None
and float(self._pred_cache.get("ts", 0.0) or 0.0) and float(self._pred_cache.get("ts", 0.0) or 0.0)

View File

@ -90,9 +90,13 @@ WEED_DEFAULT_CONFIG = {
"runtime_backend": "onnx", "runtime_backend": "onnx",
"onnx_provider": "tensorrt", "onnx_provider": "tensorrt",
# Modo operacional: usar diretamente a cabeça target. # Cabeça utilizada:
"runtime_mode": "target_direct", # target | vegetation | cana | semantic
"onnx_output_mode": "target_direct", "runtime_mode": "target",
# Usado somente quando runtime_mode = semantic:
# chao | cana | erva
"semantic_target_class": "erva",
# Contrato do ONNX novo: # Contrato do ONNX novo:
# entrada 0..1 crua -> normalização interna -> resize -> argmax -> target_mask. # entrada 0..1 crua -> normalização interna -> resize -> argmax -> target_mask.
@ -249,6 +253,9 @@ def aplicar_overrides_redis(cfg: dict) -> dict:
contexto = ContextoGlobalRedis.get_contexto() contexto = ContextoGlobalRedis.get_contexto()
equipamento = ContextoGlobalRedis.get_equipamento() equipamento = ContextoGlobalRedis.get_equipamento()
cfg["runtime_mode"] = str(dados_atu.get("modelo_cabeca") or "target").strip().lower()
cfg["semantic_target_class"] = str(dados_atu.get("modelo_classe_alvo") or "erva").strip().lower()
cfg["qtd_bicos"] = int(equipamento.get("qtd_bicos") or cfg.get("qtd_bicos", 7) or 7) cfg["qtd_bicos"] = int(equipamento.get("qtd_bicos") or cfg.get("qtd_bicos", 7) or 7)
# Modelo ONNX full-runtime validado para o Weed Worker. # Modelo ONNX full-runtime validado para o Weed Worker.

View File

@ -124,6 +124,10 @@ class WeedDetector:
self._last_update_ts: Optional[float] = None self._last_update_ts: Optional[float] = None
self._distancia_deslocada_total_cm = 0.0 self._distancia_deslocada_total_cm = 0.0
def limpar_memoria_alvo(self):
"""Descarta evidências e estados de bico do modo de máscara anterior."""
self._inicializar_estado()
def _atualizar_geometria_memoria(self): def _atualizar_geometria_memoria(self):
cfg = self.config cfg = self.config

View File

@ -112,6 +112,7 @@ namespace OperationControl.Controls
if (VariaveisControleOperacao.RoverEmFoco != null) if (VariaveisControleOperacao.RoverEmFoco != null)
{ {
VariaveisControleOperacao.RoverEmFoco!.Controle.ControleManualAcionado = manual_on;
VariaveisControleOperacao.RoverEmFoco!.Controle.MovimentoAutomatico = !manual_on; VariaveisControleOperacao.RoverEmFoco!.Controle.MovimentoAutomatico = !manual_on;
VariaveisControleOperacao.RoverEmFoco!.Controle.DirecionalAutomatico = !manual_on; VariaveisControleOperacao.RoverEmFoco!.Controle.DirecionalAutomatico = !manual_on;
VariaveisControleOperacao.EnviarParametrosOperacao(new AgroBase.Models.Operacoes.OperacaoParametrosModel() VariaveisControleOperacao.EnviarParametrosOperacao(new AgroBase.Models.Operacoes.OperacaoParametrosModel()

View File

@ -80,7 +80,7 @@ namespace OperationControl.Models
Show(); Show();
APIService.IniciarRotinas(); await APIService.IniciarRotinasAsync();
/* /*
* O MQTT novo precisa estar pronto antes dos timers. * O MQTT novo precisa estar pronto antes dos timers.
@ -507,7 +507,9 @@ namespace OperationControl.Models
new OperacaoParametrosDadosGNSSModel new OperacaoParametrosDadosGNSSModel
{ {
Latitude = -22.17254631649402, Latitude = -22.17254631649402,
LatitudeAnt = -22.17253728573052,
Longitude = -47.395203906184044, Longitude = -47.395203906184044,
LongitudeAnt = -47.395203906184044,
OrientacaoReal = 187 OrientacaoReal = 187
}, },

View File

@ -0,0 +1,374 @@
<Project>
<PropertyGroup>
<AssemblyName>OperationControl</AssemblyName>
<IntermediateOutputPath>obj\Debug\</IntermediateOutputPath>
<BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath>
<MSBuildProjectExtensionsPath>C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\</MSBuildProjectExtensionsPath>
<_TargetAssemblyProjectName>OperationControl</_TargetAssemblyProjectName>
</PropertyGroup>
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UseWPF>true</UseWPF>
<UseWindowsForms>True</UseWindowsForms>
</PropertyGroup>
<ItemGroup>
<None Remove="3d.jpg" />
<None Remove="barra.jpg" />
<None Remove="caminho.jpeg" />
<None Remove="logo.png" />
<None Remove="mapa.jpg" />
<None Remove="robo_superior.jpg" />
<None Remove="solo.jpeg" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="BruTile" Version="6.0.0" />
<PackageReference Include="BruTile.MbTiles" Version="6.0.0" />
<PackageReference Include="Extended.Wpf.Toolkit" Version="5.0.0" />
<PackageReference Include="FFME.Windows" Version="7.0.361-beta.1" />
<PackageReference Include="GirCore.Gst-1.0" Version="0.7.0-preview.3" />
<PackageReference Include="GirCore.GstVideo-1.0" Version="0.7.0-preview.3" />
<PackageReference Include="LibVLCSharp" Version="3.9.4" />
<PackageReference Include="LibVLCSharp.WPF" Version="3.9.4" />
<PackageReference Include="Mapsui" Version="5.0.0" />
<PackageReference Include="Mapsui.Extensions" Version="5.0.0" />
<PackageReference Include="Mapsui.Wpf" Version="5.0.0" />
<PackageReference Include="Mapsui3.Geometries" Version="3.0.0-alpha.3" />
<PackageReference Include="NetTopologySuite" Version="2.6.0" />
<PackageReference Include="NetTopologySuite.IO.GeoJSON" Version="4.0.0" />
<PackageReference Include="NetTopologySuite.IO.ShapeFile" Version="2.1.0" />
<PackageReference Include="OpenTK" Version="4.9.4" />
<PackageReference Include="ScottPlot.WPF" Version="5.1.57" />
<PackageReference Include="System.IO.Ports" Version="10.0.0" />
<PackageReference Include="VideoLAN.LibVLC.Windows" Version="3.0.21" />
</ItemGroup>
<ItemGroup>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AgroBase\AgroBase.csproj" />
</ItemGroup>
<ItemGroup>
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\Accessibility.dll" />
<ReferencePath Include="C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\bitmiracle.libtiff.net\2.4.660\lib\netstandard2.0\BitMiracle.LibTiff.NET.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\brutile\6.0.0\lib\net8.0\BruTile.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\brutile.mbtiles\6.0.0\lib\net8.0\BruTile.MbTiles.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\brutile\6.0.0\lib\net8.0\BruTile.XmlSerializers.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\dotspatial.projections\4.0.656\lib\net6.0\DotSpatial.Projections.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\excss\4.3.1\lib\net8.0\ExCSS.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\ffme.windows\7.0.361-beta.1\lib\net8.0-windows7.0\ffme.win.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\ffmpeg.autogen\7.0.0\lib\netstandard2.1\FFmpeg.AutoGen.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\gircore.glib-2.0\0.7.0-preview.3\lib\net8.0\GLib-2.0.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\opentk.glwpfcontrol\4.3.3\lib\netcoreapp3.1\GLWpfControl.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\gircore.gobject-2.0\0.7.0-preview.3\lib\net8.0\GObject-2.0.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\gircore.gst-1.0\0.7.0-preview.3\lib\net8.0\Gst-1.0.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\gircore.gstbase-1.0\0.7.0-preview.3\lib\net8.0\GstBase-1.0.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\gircore.gstvideo-1.0\0.7.0-preview.3\lib\net8.0\GstVideo-1.0.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\harfbuzzsharp\8.3.1.2\lib\net8.0\HarfBuzzSharp.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\libvlcsharp\3.9.4\lib\net8.0\LibVLCSharp.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\libvlcsharp.wpf\3.9.4\lib\net6.0-windows7.0\LibVLCSharp.WPF.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\mapsui\5.0.0\lib\net8.0\Mapsui.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\mapsui.extensions\5.0.0\lib\net8.0\Mapsui.Extensions.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\mapsui3.geometries\3.0.0-alpha.3\lib\netstandard2.0\Mapsui.Geometries.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\mapsui.nts\5.0.0\lib\net8.0\Mapsui.Nts.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\mapsui.rendering.skia\5.0.0\lib\net8.0\Mapsui.Rendering.Skia.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\mapsui.tiling\5.0.0\lib\net8.0\Mapsui.Tiling.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\mapsui.wpf\5.0.0\lib\net8.0-windows7.0\Mapsui.UI.Wpf.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\Microsoft.CSharp.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\Microsoft.VisualBasic.Core.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\Microsoft.VisualBasic.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\Microsoft.VisualBasic.Forms.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\Microsoft.Win32.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\Microsoft.Win32.Registry.AccessControl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\Microsoft.Win32.Registry.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\Microsoft.Win32.SystemEvents.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\mscorlib.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\netstandard.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\nettopologysuite\2.6.0\lib\netstandard2.1\NetTopologySuite.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\nettopologysuite.features\2.1.0\lib\netstandard2.0\NetTopologySuite.Features.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\nettopologysuite.io.geojson\4.0.0\lib\netstandard2.0\NetTopologySuite.IO.GeoJSON.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\nettopologysuite.io.geojson4stj\4.0.0\lib\netstandard2.0\NetTopologySuite.IO.GeoJSON4STJ.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\nettopologysuite.io.shapefile\2.1.0\lib\netstandard2.0\NetTopologySuite.IO.ShapeFile.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\newtonsoft.json\13.0.1\lib\netstandard2.0\Newtonsoft.Json.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\opentk.audio.openal\4.9.4\lib\netcoreapp3.1\OpenTK.Audio.OpenAL.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\opentk.compute\4.9.4\lib\netcoreapp3.1\OpenTK.Compute.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\opentk.core\4.9.4\lib\netstandard2.1\OpenTK.Core.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\opentk.graphics\4.9.4\lib\netcoreapp3.1\OpenTK.Graphics.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\opentk.input\4.9.4\lib\netstandard2.0\OpenTK.Input.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\opentk.mathematics\4.9.4\lib\netcoreapp3.1\OpenTK.Mathematics.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\opentk.windowing.common\4.9.4\lib\netcoreapp3.1\OpenTK.Windowing.Common.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\opentk.windowing.desktop\4.9.4\lib\netcoreapp3.1\OpenTK.Windowing.Desktop.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\opentk.windowing.graphicslibraryframework\4.9.4\lib\netcoreapp3.1\OpenTK.Windowing.GraphicsLibraryFramework.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\PresentationCore.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\PresentationFramework.Aero.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\PresentationFramework.Aero2.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\PresentationFramework.AeroLite.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\PresentationFramework.Classic.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\PresentationFramework.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\PresentationFramework.Luna.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\PresentationFramework.Royale.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\PresentationUI.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\ReachFramework.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\scottplot\5.1.57\lib\net8.0\ScottPlot.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\scottplot.wpf\5.1.57\lib\net8.0-windows7.0\ScottPlot.WPF.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\shimskiasharp\3.2.1\lib\net8.0\ShimSkiaSharp.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\skiasharp\3.119.1\ref\net8.0\SkiaSharp.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\skiasharp.harfbuzz\3.119.1\lib\net8.0\SkiaSharp.HarfBuzz.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\skiasharp.views.desktop.common\3.119.1\lib\net8.0\SkiaSharp.Views.Desktop.Common.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\skiasharp.views.wpf\3.119.1\lib\net462\SkiaSharp.Views.WPF.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\sqlite-net-base\1.10.196-beta\lib\net8.0\SQLite-net.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\sqlitepclraw.config.e_sqlite3\3.0.2\lib\net8.0\SQLitePCLRaw.batteries_v2.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\sqlitepclraw.core\3.0.2\lib\netstandard2.0\SQLitePCLRaw.core.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\sqlitepclraw.provider.e_sqlite3\3.0.2\lib\net8.0-windows7.0\SQLitePCLRaw.provider.e_sqlite3.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\svg.custom\3.2.1\lib\net8.0\Svg.Custom.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\svg.model\3.2.1\lib\net8.0\Svg.Model.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\svg.skia\3.2.1\lib\net8.0\Svg.Skia.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.AppContext.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Buffers.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\System.CodeDom.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Collections.Concurrent.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Collections.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Collections.Immutable.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Collections.NonGeneric.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Collections.Specialized.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.ComponentModel.Annotations.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.ComponentModel.DataAnnotations.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.ComponentModel.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.ComponentModel.EventBasedAsync.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.ComponentModel.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.ComponentModel.TypeConverter.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\System.Configuration.ConfigurationManager.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Configuration.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Console.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Core.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Data.Common.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Data.DataSetExtensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Data.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\System.Design.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Diagnostics.Contracts.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Diagnostics.Debug.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Diagnostics.DiagnosticSource.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\System.Diagnostics.EventLog.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Diagnostics.FileVersionInfo.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\System.Diagnostics.PerformanceCounter.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Diagnostics.Process.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Diagnostics.StackTrace.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Diagnostics.TextWriterTraceListener.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Diagnostics.Tools.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Diagnostics.TraceSource.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Diagnostics.Tracing.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\System.DirectoryServices.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\System.Drawing.Common.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\System.Drawing.Design.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\System.Drawing.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Drawing.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Dynamic.Runtime.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Formats.Asn1.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Formats.Tar.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Globalization.Calendars.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Globalization.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Globalization.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.IO.Compression.Brotli.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.IO.Compression.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.IO.Compression.FileSystem.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.IO.Compression.ZipFile.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.IO.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.IO.FileSystem.AccessControl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.IO.FileSystem.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.IO.FileSystem.DriveInfo.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.IO.FileSystem.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.IO.FileSystem.Watcher.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.IO.IsolatedStorage.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.IO.MemoryMappedFiles.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\System.IO.Packaging.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\system.io.pipelines\9.0.0\lib\net8.0\System.IO.Pipelines.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.IO.Pipes.AccessControl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.IO.Pipes.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\system.io.ports\10.0.0\lib\net8.0\System.IO.Ports.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.IO.UnmanagedMemoryStream.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Linq.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Linq.Expressions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Linq.Parallel.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Linq.Queryable.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Memory.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Net.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Net.Http.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Net.Http.Json.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Net.HttpListener.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Net.Mail.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Net.NameResolution.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Net.NetworkInformation.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Net.Ping.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Net.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Net.Quic.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Net.Requests.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Net.Security.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Net.ServicePoint.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Net.Sockets.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Net.WebClient.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Net.WebHeaderCollection.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Net.WebProxy.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Net.WebSockets.Client.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Net.WebSockets.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Numerics.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Numerics.Vectors.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.ObjectModel.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\System.Printing.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Reflection.DispatchProxy.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Reflection.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Reflection.Emit.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Reflection.Emit.ILGeneration.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Reflection.Emit.Lightweight.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Reflection.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Reflection.Metadata.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Reflection.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Reflection.TypeExtensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\System.Resources.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Resources.Reader.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Resources.ResourceManager.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Resources.Writer.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Runtime.CompilerServices.Unsafe.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Runtime.CompilerServices.VisualC.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Runtime.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Runtime.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Runtime.Handles.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Runtime.InteropServices.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Runtime.InteropServices.JavaScript.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Runtime.InteropServices.RuntimeInformation.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Runtime.Intrinsics.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Runtime.Loader.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Runtime.Numerics.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Runtime.Serialization.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Runtime.Serialization.Formatters.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Runtime.Serialization.Json.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Runtime.Serialization.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Runtime.Serialization.Xml.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Security.AccessControl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Security.Claims.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Security.Cryptography.Algorithms.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Security.Cryptography.Cng.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Security.Cryptography.Csp.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Security.Cryptography.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Security.Cryptography.Encoding.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Security.Cryptography.OpenSsl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\System.Security.Cryptography.Pkcs.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Security.Cryptography.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\System.Security.Cryptography.ProtectedData.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Security.Cryptography.X509Certificates.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\System.Security.Cryptography.Xml.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Security.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\System.Security.Permissions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Security.Principal.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Security.Principal.Windows.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Security.SecureString.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.ServiceModel.Web.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.ServiceProcess.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Text.Encoding.CodePages.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Text.Encoding.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Text.Encoding.Extensions.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\system.text.encodings.web\9.0.0\lib\net8.0\System.Text.Encodings.Web.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\system.text.json\9.0.0\lib\net8.0\System.Text.Json.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Text.RegularExpressions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\System.Threading.AccessControl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Threading.Channels.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Threading.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Threading.Overlapped.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Threading.Tasks.Dataflow.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Threading.Tasks.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Threading.Tasks.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Threading.Tasks.Parallel.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Threading.Thread.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Threading.ThreadPool.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Threading.Timer.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Transactions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Transactions.Local.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.ValueTuple.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Web.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Web.HttpUtility.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\System.Windows.Controls.Ribbon.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Windows.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\System.Windows.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\System.Windows.Forms.Design.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\System.Windows.Forms.Design.Editors.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\System.Windows.Forms.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\System.Windows.Forms.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\System.Windows.Input.Manipulations.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\System.Windows.Presentation.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\System.Xaml.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Xml.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Xml.Linq.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Xml.ReaderWriter.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Xml.Serialization.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Xml.XDocument.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Xml.XmlDocument.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Xml.XmlSerializer.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Xml.XPath.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\ref\net8.0\System.Xml.XPath.XDocument.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\topten.richtextkit\0.4.167\lib\net5.0\Topten.RichTextKit.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\UIAutomationClient.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\UIAutomationClientSideProviders.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\UIAutomationProvider.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\UIAutomationTypes.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\WindowsBase.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\ref\net8.0\WindowsFormsIntegration.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\extended.wpf.toolkit\5.0.0\lib\net5.0\Xceed.Wpf.AvalonDock.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\extended.wpf.toolkit\5.0.0\lib\net5.0\Xceed.Wpf.AvalonDock.Themes.Aero.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\extended.wpf.toolkit\5.0.0\lib\net5.0\Xceed.Wpf.AvalonDock.Themes.Metro.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\extended.wpf.toolkit\5.0.0\lib\net5.0\Xceed.Wpf.AvalonDock.Themes.VS2010.dll" />
<ReferencePath Include="C:\Users\USER\.nuget\packages\extended.wpf.toolkit\5.0.0\lib\net5.0\Xceed.Wpf.Toolkit.dll" />
</ItemGroup>
<ItemGroup>
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Controls\AttitudeIndicator.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Controls\Bbox3DViewer.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Controls\GstVideoView.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Controls\HeadingIndicator.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Controls\LabeledBar.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Controls\ManualControlPad.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Controls\MapViewControl.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Controls\ProgressBarText.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Controls\Pulverizador\BicoLequeIndicator.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Controls\Pulverizador\PulverizadorIndicator.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Controls\RiskMeter.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Controls\TemperatureIndicator.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Views\ConfigConexao\ConfigConexaoView.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Views\Operacao\Monitoramento\ControleManualView.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Views\Operacao\Monitoramento\DiagnosticoView.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Views\Operacao\Monitoramento\HistoricoView.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Views\Operacao\Monitoramento\MonitoramentoView.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Views\Operacao\Monitoramento\ParametrizacaoView.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Views\Operacao\Monitoramento\PulverizadorView.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Views\Operacao\Monitoramento\ResumoView.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Views\Operacao\OperacaoBottomView.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Views\Operacao\OperacaoCenterView.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Views\Operacao\OperacaoLeftView.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Views\Operacao\OperacaoRightView.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Views\Operacao\OperacaoTopView.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Views\PreparacaoMapa\PreparacaoMapaBottomView.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Views\PreparacaoMapa\PreparacaoMapaTopView.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Views\PreparacaoMapa\PreparacaoMapaView.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Windows\DockWindow.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Windows\MainWindow.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Windows\NetworkConfigWindow.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\Windows\SelecaoTipoMapa.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\App.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\OperationControl_Content.g.cs" />
<Compile Include="C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\GeneratedInternalTypeHelper.g.cs" />
</ItemGroup>
<ItemGroup>
<Analyzer Include="C:\Program Files\dotnet\sdk\8.0.100\Sdks\Microsoft.NET.Sdk\targets\..\analyzers\Microsoft.CodeAnalysis.CSharp.NetAnalyzers.dll" />
<Analyzer Include="C:\Program Files\dotnet\sdk\8.0.100\Sdks\Microsoft.NET.Sdk\targets\..\analyzers\Microsoft.CodeAnalysis.NetAnalyzers.dll" />
<Analyzer Include="C:\Users\USER\.nuget\packages\system.text.json\9.0.0\analyzers\dotnet\roslyn4.4\cs\System.Text.Json.SourceGeneration.dll" />
<Analyzer Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\analyzers/dotnet/cs/Microsoft.Interop.ComInterfaceGenerator.dll" />
<Analyzer Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\analyzers/dotnet/cs/Microsoft.Interop.JavaScript.JSImportGenerator.dll" />
<Analyzer Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\analyzers/dotnet/cs/Microsoft.Interop.LibraryImportGenerator.dll" />
<Analyzer Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\analyzers/dotnet/cs/Microsoft.Interop.SourceGeneration.dll" />
<Analyzer Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0\analyzers/dotnet/cs/System.Text.RegularExpressions.Generator.dll" />
<Analyzer Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\analyzers/dotnet/System.Windows.Forms.Analyzers.dll" />
<Analyzer Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.0\analyzers/dotnet/cs/System.Windows.Forms.Analyzers.CSharp.dll" />
</ItemGroup>
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
</Project>

View File

@ -42,6 +42,7 @@ namespace OperationControl.ViewModels.Views.Operacao.Monitoramento
var r = VariaveisControleOperacao.RoverEmFoco; var r = VariaveisControleOperacao.RoverEmFoco;
if (r != null) if (r != null)
{ {
r.Controle.ControleManualAcionado = value;
r.Controle.MovimentoAutomatico = value ? false : r.ControleAutomatico; r.Controle.MovimentoAutomatico = value ? false : r.ControleAutomatico;
r.Controle.DirecionalAutomatico = value ? false : r.ControleAutomatico; r.Controle.DirecionalAutomatico = value ? false : r.ControleAutomatico;
VariaveisControleOperacao.EnviarParametrosOperacao(new AgroBase.Models.Operacoes.OperacaoParametrosModel() VariaveisControleOperacao.EnviarParametrosOperacao(new AgroBase.Models.Operacoes.OperacaoParametrosModel()

View File

@ -412,7 +412,7 @@
<StackPanel Orientation="Horizontal" Margin="0,0,0,8"> <StackPanel Orientation="Horizontal" Margin="0,0,0,8">
<Label Content="Lateral" Foreground="#DDDDDD"/> <Label Content="Lateral" Foreground="#DDDDDD"/>
<Slider Width="110" Minimum="-100" Maximum="100" Margin="8,0" Value="{Binding OpcoesVM.GpsLeverArmLateral, Mode=TwoWay}" TickFrequency="1" IsSnapToTickEnabled="True" SmallChange="1" LargeChange="1"/> <Slider Width="110" Minimum="-200" Maximum="200" Margin="8,0" Value="{Binding OpcoesVM.GpsLeverArmLateral, Mode=TwoWay}" TickFrequency="1" IsSnapToTickEnabled="True" SmallChange="1" LargeChange="1"/>
<Label Content="{Binding OpcoesVM.GpsLeverArmLateralTexto}" Foreground="#DDDDDD" Margin="0,0,10,0"/> <Label Content="{Binding OpcoesVM.GpsLeverArmLateralTexto}" Foreground="#DDDDDD" Margin="0,0,10,0"/>
<Label Content="Frontal" Foreground="#DDDDDD"/> <Label Content="Frontal" Foreground="#DDDDDD"/>

View File

@ -19,6 +19,11 @@
<x:Type TypeName="enums:Enums+ModoAgitadorCalda"/> <x:Type TypeName="enums:Enums+ModoAgitadorCalda"/>
</ObjectDataProvider.MethodParameters> </ObjectDataProvider.MethodParameters>
</ObjectDataProvider> </ObjectDataProvider>
<ObjectDataProvider x:Key="CabecasModeloValues" MethodName="GetValues" ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="enums:Enums+CabecasModelo"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</UserControl.Resources> </UserControl.Resources>
<Grid> <Grid>
<Grid.Resources> <Grid.Resources>
@ -177,6 +182,12 @@
<TextBlock Text="Ervas Bico Off (%)" Style="{StaticResource ParamLabelStyle}"/> <TextBlock Text="Ervas Bico Off (%)" Style="{StaticResource ParamLabelStyle}"/>
<TextBox ToolTip="Percentual mínimo de erva para manter o bico ligado. Abaixo desse valor, o bico é desligado." Text="{Binding Parametros.Controle.AtuPercentualErvasBicoOff, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource ParamTextBoxStyle}" Margin="0,0,0,0"/> <TextBox ToolTip="Percentual mínimo de erva para manter o bico ligado. Abaixo desse valor, o bico é desligado." Text="{Binding Parametros.Controle.AtuPercentualErvasBicoOff, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource ParamTextBoxStyle}" Margin="0,0,0,0"/>
<TextBlock Text="Modo Pulverização" Style="{StaticResource ParamLabelStyle}"/>
<ComboBox ToolTip="Define o modo de trabalho da inteligência artificial para detecção do alvo para pulverização." ItemsSource="{Binding Source={StaticResource CabecasModeloValues}}" SelectedItem="{Binding Parametros.Controle.AtuModeloCabeca, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Text="Classe Alvo" Style="{StaticResource ParamLabelStyle}"/>
<TextBox ToolTip="Nome da classe usada como alvo do pulverizador. Não precisa ser informado quando não for Semantic." Text="{Binding Parametros.Controle.AtuClasseAlvo, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource ParamTextBoxStyle}" Margin="0,0,0,0"/>
</StackPanel> </StackPanel>
</Border> </Border>