implementado camera frontal
This commit is contained in:
parent
bd4b9717cd
commit
e107e7a810
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -138,7 +138,7 @@ namespace AgroBase.Forms.IHM
|
|||
|
||||
private void frmAjustes_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
Variaveis.OperacaoEmAndamento.AtualizaListaCameras(new List<Panel>() { pnlCaminho }, Variaveis.OperacaoEmAndamento.CamerasSolo.Select(x => x.panel).ToList(), false);
|
||||
Variaveis.OperacaoEmAndamento.DesligarCameras();
|
||||
}
|
||||
|
||||
#region COMUNICACAO
|
||||
|
|
@ -276,6 +276,7 @@ namespace AgroBase.Forms.IHM
|
|||
private void AtualizarCameras()
|
||||
{
|
||||
flwCamerasSolo.Controls.Clear();
|
||||
OAKCameraService.AtualizarListaCameras(true);
|
||||
Cameras = OAKCameraService.GetListaCameras();
|
||||
for (int i = 0; i < Variaveis.OperacaoEmAndamento.QuantidadeCamerasSolo; i++)
|
||||
{
|
||||
|
|
@ -326,7 +327,11 @@ namespace AgroBase.Forms.IHM
|
|||
}
|
||||
|
||||
CameraCaminho.camera.cameraIndex = CameraCaminho.combo.SelectedIndex;
|
||||
IniciarCameras();
|
||||
|
||||
if (CameraCaminho.camera.cameraIndex > 0)
|
||||
{
|
||||
IniciarCameras();
|
||||
}
|
||||
}
|
||||
|
||||
private void GerarCameraSolo(int idx)
|
||||
|
|
@ -416,7 +421,11 @@ namespace AgroBase.Forms.IHM
|
|||
}
|
||||
|
||||
CameraSolo.camera.cameraIndex = CameraSolo.combo.SelectedIndex;
|
||||
IniciarCameras();
|
||||
|
||||
if (CameraSolo.camera.cameraIndex > 0)
|
||||
{
|
||||
IniciarCameras();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
this.pnlJoystick = new System.Windows.Forms.Panel();
|
||||
this.pnlMapaDinamico = new System.Windows.Forms.Panel();
|
||||
this.pnlCameraCaminho = new System.Windows.Forms.Panel();
|
||||
this.pnlCameraSoloD = new System.Windows.Forms.Panel();
|
||||
this.pnlCameraCaminhoHeat = new System.Windows.Forms.Panel();
|
||||
this.pnlCameraSoloE = new System.Windows.Forms.Panel();
|
||||
this.lblMapaCarregado = new System.Windows.Forms.Label();
|
||||
this.txtStatusAtual = new System.Windows.Forms.TextBox();
|
||||
|
|
@ -63,6 +63,14 @@
|
|||
this.lblModoOperacao = new System.Windows.Forms.Label();
|
||||
this.txtModoOperacao = new System.Windows.Forms.TextBox();
|
||||
this.pnlSensores = new System.Windows.Forms.Panel();
|
||||
this.txtDT = new System.Windows.Forms.TextBox();
|
||||
this.lblDT = new System.Windows.Forms.Label();
|
||||
this.txtET = new System.Windows.Forms.TextBox();
|
||||
this.lblET = new System.Windows.Forms.Label();
|
||||
this.txtDF = new System.Windows.Forms.TextBox();
|
||||
this.lblDF = new System.Windows.Forms.Label();
|
||||
this.txtEF = new System.Windows.Forms.TextBox();
|
||||
this.lblEF = new System.Windows.Forms.Label();
|
||||
this.txtStatusCarro = new System.Windows.Forms.TextBox();
|
||||
this.lblStatusCarro = new System.Windows.Forms.Label();
|
||||
this.txtMargemCorredor = new System.Windows.Forms.TextBox();
|
||||
|
|
@ -96,14 +104,6 @@
|
|||
this.tkbVelocidade = new System.Windows.Forms.TrackBar();
|
||||
this.tabMapa = new System.Windows.Forms.TabPage();
|
||||
this.picFechar = new System.Windows.Forms.PictureBox();
|
||||
this.txtEF = new System.Windows.Forms.TextBox();
|
||||
this.lblEF = new System.Windows.Forms.Label();
|
||||
this.txtDF = new System.Windows.Forms.TextBox();
|
||||
this.lblDF = new System.Windows.Forms.Label();
|
||||
this.txtDT = new System.Windows.Forms.TextBox();
|
||||
this.lblDT = new System.Windows.Forms.Label();
|
||||
this.txtET = new System.Windows.Forms.TextBox();
|
||||
this.lblET = new System.Windows.Forms.Label();
|
||||
this.pnlMapa.SuspendLayout();
|
||||
this.pnlSensores.SuspendLayout();
|
||||
this.statusStrip1.SuspendLayout();
|
||||
|
|
@ -148,12 +148,12 @@
|
|||
this.pnlCameraCaminho.Size = new System.Drawing.Size(210, 150);
|
||||
this.pnlCameraCaminho.TabIndex = 18;
|
||||
//
|
||||
// pnlCameraSoloD
|
||||
// pnlCameraCaminhoHeat
|
||||
//
|
||||
this.pnlCameraSoloD.Location = new System.Drawing.Point(484, 2);
|
||||
this.pnlCameraSoloD.Name = "pnlCameraSoloD";
|
||||
this.pnlCameraSoloD.Size = new System.Drawing.Size(210, 150);
|
||||
this.pnlCameraSoloD.TabIndex = 18;
|
||||
this.pnlCameraCaminhoHeat.Location = new System.Drawing.Point(484, 2);
|
||||
this.pnlCameraCaminhoHeat.Name = "pnlCameraCaminhoHeat";
|
||||
this.pnlCameraCaminhoHeat.Size = new System.Drawing.Size(210, 150);
|
||||
this.pnlCameraCaminhoHeat.TabIndex = 18;
|
||||
//
|
||||
// pnlCameraSoloE
|
||||
//
|
||||
|
|
@ -466,6 +466,86 @@
|
|||
this.pnlSensores.Size = new System.Drawing.Size(307, 497);
|
||||
this.pnlSensores.TabIndex = 32;
|
||||
//
|
||||
// txtDT
|
||||
//
|
||||
this.txtDT.Font = new System.Drawing.Font("Microsoft Sans Serif", 12.25F);
|
||||
this.txtDT.Location = new System.Drawing.Point(195, 819);
|
||||
this.txtDT.Name = "txtDT";
|
||||
this.txtDT.ReadOnly = true;
|
||||
this.txtDT.Size = new System.Drawing.Size(89, 26);
|
||||
this.txtDT.TabIndex = 51;
|
||||
this.txtDT.Text = "0,00";
|
||||
this.txtDT.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// lblDT
|
||||
//
|
||||
this.lblDT.AutoSize = true;
|
||||
this.lblDT.Location = new System.Drawing.Point(160, 822);
|
||||
this.lblDT.Name = "lblDT";
|
||||
this.lblDT.Size = new System.Drawing.Size(30, 20);
|
||||
this.lblDT.TabIndex = 50;
|
||||
this.lblDT.Text = "DT";
|
||||
//
|
||||
// txtET
|
||||
//
|
||||
this.txtET.Font = new System.Drawing.Font("Microsoft Sans Serif", 12.25F);
|
||||
this.txtET.Location = new System.Drawing.Point(41, 822);
|
||||
this.txtET.Name = "txtET";
|
||||
this.txtET.ReadOnly = true;
|
||||
this.txtET.Size = new System.Drawing.Size(89, 26);
|
||||
this.txtET.TabIndex = 49;
|
||||
this.txtET.Text = "0,00";
|
||||
this.txtET.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// lblET
|
||||
//
|
||||
this.lblET.AutoSize = true;
|
||||
this.lblET.Location = new System.Drawing.Point(6, 825);
|
||||
this.lblET.Name = "lblET";
|
||||
this.lblET.Size = new System.Drawing.Size(29, 20);
|
||||
this.lblET.TabIndex = 48;
|
||||
this.lblET.Text = "ET";
|
||||
//
|
||||
// txtDF
|
||||
//
|
||||
this.txtDF.Font = new System.Drawing.Font("Microsoft Sans Serif", 12.25F);
|
||||
this.txtDF.Location = new System.Drawing.Point(195, 787);
|
||||
this.txtDF.Name = "txtDF";
|
||||
this.txtDF.ReadOnly = true;
|
||||
this.txtDF.Size = new System.Drawing.Size(89, 26);
|
||||
this.txtDF.TabIndex = 47;
|
||||
this.txtDF.Text = "0,00";
|
||||
this.txtDF.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// lblDF
|
||||
//
|
||||
this.lblDF.AutoSize = true;
|
||||
this.lblDF.Location = new System.Drawing.Point(160, 790);
|
||||
this.lblDF.Name = "lblDF";
|
||||
this.lblDF.Size = new System.Drawing.Size(31, 20);
|
||||
this.lblDF.TabIndex = 46;
|
||||
this.lblDF.Text = "DF";
|
||||
//
|
||||
// txtEF
|
||||
//
|
||||
this.txtEF.Font = new System.Drawing.Font("Microsoft Sans Serif", 12.25F);
|
||||
this.txtEF.Location = new System.Drawing.Point(41, 790);
|
||||
this.txtEF.Name = "txtEF";
|
||||
this.txtEF.ReadOnly = true;
|
||||
this.txtEF.Size = new System.Drawing.Size(89, 26);
|
||||
this.txtEF.TabIndex = 45;
|
||||
this.txtEF.Text = "0,00";
|
||||
this.txtEF.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// lblEF
|
||||
//
|
||||
this.lblEF.AutoSize = true;
|
||||
this.lblEF.Location = new System.Drawing.Point(6, 793);
|
||||
this.lblEF.Name = "lblEF";
|
||||
this.lblEF.Size = new System.Drawing.Size(30, 20);
|
||||
this.lblEF.TabIndex = 44;
|
||||
this.lblEF.Text = "EF";
|
||||
//
|
||||
// txtStatusCarro
|
||||
//
|
||||
this.txtStatusCarro.Font = new System.Drawing.Font("Microsoft Sans Serif", 12.25F);
|
||||
|
|
@ -796,86 +876,6 @@
|
|||
this.picFechar.TabIndex = 1;
|
||||
this.picFechar.TabStop = false;
|
||||
//
|
||||
// txtEF
|
||||
//
|
||||
this.txtEF.Font = new System.Drawing.Font("Microsoft Sans Serif", 12.25F);
|
||||
this.txtEF.Location = new System.Drawing.Point(41, 790);
|
||||
this.txtEF.Name = "txtEF";
|
||||
this.txtEF.ReadOnly = true;
|
||||
this.txtEF.Size = new System.Drawing.Size(89, 26);
|
||||
this.txtEF.TabIndex = 45;
|
||||
this.txtEF.Text = "0,00";
|
||||
this.txtEF.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// lblEF
|
||||
//
|
||||
this.lblEF.AutoSize = true;
|
||||
this.lblEF.Location = new System.Drawing.Point(6, 793);
|
||||
this.lblEF.Name = "lblEF";
|
||||
this.lblEF.Size = new System.Drawing.Size(30, 20);
|
||||
this.lblEF.TabIndex = 44;
|
||||
this.lblEF.Text = "EF";
|
||||
//
|
||||
// txtDF
|
||||
//
|
||||
this.txtDF.Font = new System.Drawing.Font("Microsoft Sans Serif", 12.25F);
|
||||
this.txtDF.Location = new System.Drawing.Point(195, 787);
|
||||
this.txtDF.Name = "txtDF";
|
||||
this.txtDF.ReadOnly = true;
|
||||
this.txtDF.Size = new System.Drawing.Size(89, 26);
|
||||
this.txtDF.TabIndex = 47;
|
||||
this.txtDF.Text = "0,00";
|
||||
this.txtDF.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// lblDF
|
||||
//
|
||||
this.lblDF.AutoSize = true;
|
||||
this.lblDF.Location = new System.Drawing.Point(160, 790);
|
||||
this.lblDF.Name = "lblDF";
|
||||
this.lblDF.Size = new System.Drawing.Size(31, 20);
|
||||
this.lblDF.TabIndex = 46;
|
||||
this.lblDF.Text = "DF";
|
||||
//
|
||||
// txtDT
|
||||
//
|
||||
this.txtDT.Font = new System.Drawing.Font("Microsoft Sans Serif", 12.25F);
|
||||
this.txtDT.Location = new System.Drawing.Point(195, 819);
|
||||
this.txtDT.Name = "txtDT";
|
||||
this.txtDT.ReadOnly = true;
|
||||
this.txtDT.Size = new System.Drawing.Size(89, 26);
|
||||
this.txtDT.TabIndex = 51;
|
||||
this.txtDT.Text = "0,00";
|
||||
this.txtDT.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// lblDT
|
||||
//
|
||||
this.lblDT.AutoSize = true;
|
||||
this.lblDT.Location = new System.Drawing.Point(160, 822);
|
||||
this.lblDT.Name = "lblDT";
|
||||
this.lblDT.Size = new System.Drawing.Size(30, 20);
|
||||
this.lblDT.TabIndex = 50;
|
||||
this.lblDT.Text = "DT";
|
||||
//
|
||||
// txtET
|
||||
//
|
||||
this.txtET.Font = new System.Drawing.Font("Microsoft Sans Serif", 12.25F);
|
||||
this.txtET.Location = new System.Drawing.Point(41, 822);
|
||||
this.txtET.Name = "txtET";
|
||||
this.txtET.ReadOnly = true;
|
||||
this.txtET.Size = new System.Drawing.Size(89, 26);
|
||||
this.txtET.TabIndex = 49;
|
||||
this.txtET.Text = "0,00";
|
||||
this.txtET.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// lblET
|
||||
//
|
||||
this.lblET.AutoSize = true;
|
||||
this.lblET.Location = new System.Drawing.Point(6, 825);
|
||||
this.lblET.Name = "lblET";
|
||||
this.lblET.Size = new System.Drawing.Size(29, 20);
|
||||
this.lblET.TabIndex = 48;
|
||||
this.lblET.Text = "ET";
|
||||
//
|
||||
// frmDialogoMapa
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
|
|
@ -886,7 +886,7 @@
|
|||
this.Controls.Add(this.tabControl1);
|
||||
this.Controls.Add(this.statusStrip1);
|
||||
this.Controls.Add(this.pnlCameraCaminho);
|
||||
this.Controls.Add(this.pnlCameraSoloD);
|
||||
this.Controls.Add(this.pnlCameraCaminhoHeat);
|
||||
this.Controls.Add(this.lblMapaCarregado);
|
||||
this.Controls.Add(this.pnlCameraSoloE);
|
||||
this.Controls.Add(this.pnlMapa);
|
||||
|
|
@ -948,7 +948,7 @@
|
|||
private System.Windows.Forms.Panel pnlOrientacao;
|
||||
private System.Windows.Forms.Panel pnlInclinacao;
|
||||
private System.Windows.Forms.Panel pnlCameraCaminho;
|
||||
private System.Windows.Forms.Panel pnlCameraSoloD;
|
||||
private System.Windows.Forms.Panel pnlCameraCaminhoHeat;
|
||||
private System.Windows.Forms.Panel pnlCameraSoloE;
|
||||
private System.Windows.Forms.Label lblModoOperacao;
|
||||
private System.Windows.Forms.TextBox txtModoOperacao;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ namespace AgroBase.Forms.IHM
|
|||
|
||||
FuncoesGlobais.DefinirEventosPicBtn(picFechar, "", async () =>
|
||||
{
|
||||
if (Variaveis.OperacaoEmAndamento.Iniciado)
|
||||
if (Variaveis.OperacaoEmAndamento.Iniciado && !Variaveis.OperacaoEmAndamento.Finalizando)
|
||||
{
|
||||
var res = CustomDialog.ShowDialog(
|
||||
"Interromper Operação",
|
||||
|
|
@ -54,7 +54,7 @@ namespace AgroBase.Forms.IHM
|
|||
);
|
||||
if (res == DialogResult.Yes)
|
||||
{
|
||||
await Variaveis.OperacaoEmAndamento.FinalizarOperacao();
|
||||
Task.Run(async () => await Variaveis.OperacaoEmAndamento.FinalizarOperacao());
|
||||
if (Variaveis.OperacaoEmAndamento.Modo == Enums.ModoOperacao.Manual)
|
||||
{
|
||||
this.Close();
|
||||
|
|
@ -63,7 +63,15 @@ namespace AgroBase.Forms.IHM
|
|||
}
|
||||
else
|
||||
{
|
||||
this.Hide();
|
||||
if (Variaveis.OperacaoEmAndamento.StatusAtual == Enums.StatusOperacao.Parametrizando)
|
||||
{
|
||||
Variaveis.OperacaoEmAndamento.DesligarCameras();
|
||||
this.Hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -91,15 +99,16 @@ namespace AgroBase.Forms.IHM
|
|||
|
||||
private void frmDialogoMapa_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
tmrLeitura.Dispose();
|
||||
tmrLeitura?.Dispose();
|
||||
Variaveis.OperacaoEmAndamento.DesligarCameras();
|
||||
}
|
||||
|
||||
public async Task AtualizarRuasSelecionadas(List<string> ruasSelecionadas)
|
||||
{
|
||||
Variaveis.OperacaoEmAndamento.AtualizaListaCameras(new List<Panel>() { pnlCameraCaminho }, new List<Panel>(){ pnlCameraSoloE, pnlCameraSoloD }, true);
|
||||
Variaveis.OperacaoEmAndamento.AtualizaListaCameras(new List<Panel>() { pnlCameraCaminho, pnlCameraCaminhoHeat }, new List<Panel>() { pnlCameraSoloE }, true);
|
||||
|
||||
await Task.Delay(1000);
|
||||
|
||||
GPSService.AtualizarRuasSelecionadas(ruasSelecionadas);
|
||||
}
|
||||
|
||||
|
|
@ -117,16 +126,19 @@ namespace AgroBase.Forms.IHM
|
|||
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
|
||||
var _Trajetoria = Variaveis.OperacaoEmAndamento.Trajetoria;
|
||||
|
||||
MapaDinamico.AtualizarDados(
|
||||
KinectService.Iniciado && KinectService.Leitura.StatusDetecao ? KinectService.Leitura.ObstaculoCritico : null,
|
||||
(float)_Sensoriamento.Trajetoria.AnguloCaminho,
|
||||
(float)_Sensoriamento.Gps.AnguloCarroDefinido,
|
||||
_Sensoriamento.Gps,
|
||||
_Trajetoria._TrajetoriaDinamica,
|
||||
_Trajetoria.CorredorAtual.Pontos,
|
||||
Variaveis.OperacaoEmAndamento.GPSTrajetoria,
|
||||
_Trajetoria.RuasPlantacao
|
||||
);
|
||||
if (_Trajetoria != null && _Trajetoria.CorredorAtual != null)
|
||||
{
|
||||
MapaDinamico.AtualizarDados(
|
||||
KinectService.Iniciado && KinectService.Leitura.StatusDetecao ? KinectService.Leitura.ObstaculoCritico : null,
|
||||
(float)_Trajetoria.AnguloCaminho,
|
||||
(float)_Sensoriamento.Gps.AnguloCarroDefinido,
|
||||
_Sensoriamento.Gps,
|
||||
_Trajetoria._TrajetoriaDinamica,
|
||||
_Trajetoria.CorredorAtual.Pontos,
|
||||
Variaveis.OperacaoEmAndamento.GPSTrajetoria,
|
||||
_Trajetoria.RuasPlantacao
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task tmrLeitura_Tick()
|
||||
|
|
@ -303,27 +315,35 @@ namespace AgroBase.Forms.IHM
|
|||
joystickPosition = joystickCenter;
|
||||
|
||||
// Evento de pintura do painel
|
||||
pnlJoystick.Paint -= PanelJoystickBack_Paint;
|
||||
pnlJoystick.Paint += PanelJoystickBack_Paint;
|
||||
|
||||
// Eventos de toque/mouse
|
||||
pnlJoystick.MouseDown -= PanelJoystickBack_MouseDown;
|
||||
pnlJoystick.MouseDown += PanelJoystickBack_MouseDown;
|
||||
pnlJoystick.MouseMove -= PanelJoystickBack_MouseMove;
|
||||
pnlJoystick.MouseMove += PanelJoystickBack_MouseMove;
|
||||
pnlJoystick.MouseUp -= PanelJoystickBack_MouseUp;
|
||||
pnlJoystick.MouseUp += PanelJoystickBack_MouseUp;
|
||||
|
||||
pnlFreio.BackColor = Color.LightGray;
|
||||
pnlFreio.BorderStyle = BorderStyle.FixedSingle;
|
||||
|
||||
// Eventos de toque/pressão
|
||||
pnlFreio.Paint -= BrakePanel_Paint;
|
||||
pnlFreio.Paint += BrakePanel_Paint;
|
||||
pnlFreio.MouseDown -= BrakePanel_MouseDown;
|
||||
pnlFreio.MouseDown += BrakePanel_MouseDown;
|
||||
pnlFreio.MouseMove -= BrakePanel_MouseMove;
|
||||
pnlFreio.MouseMove += BrakePanel_MouseMove;
|
||||
pnlFreio.MouseUp -= BrakePanel_MouseUp;
|
||||
pnlFreio.MouseUp += BrakePanel_MouseUp;
|
||||
|
||||
// Configuração inicial do freio
|
||||
freioStartPosition = new Point(pnlFreio.Width / 2 - 20, 10);
|
||||
freioPosition = freioStartPosition;
|
||||
|
||||
Variaveis.OperacaoEmAndamento.AtualizaListaCameras(new List<Panel>() { pnlCameraCaminho }, new List<Panel>() { pnlCameraSoloE, pnlCameraSoloD }, true);
|
||||
Variaveis.OperacaoEmAndamento.AtualizaListaCameras(new List<Panel>() { pnlCameraCaminho, pnlCameraCaminhoHeat }, new List<Panel>() { pnlCameraSoloE }, true);
|
||||
|
||||
IniciarOperacao();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ namespace AgroBase.Forms.IHM
|
|||
{
|
||||
CustomDialog.ShowDialog(
|
||||
"Iniciar Operação Manual",
|
||||
$"{Variaveis.OperacaoEmAndamento.ErroOperacaoLiberada}",
|
||||
$"{Variaveis.OperacaoEmAndamento.ErroOperacaoLiberada ?? ""}",
|
||||
MessageBoxIcon.Error,
|
||||
new Dictionary<(string, dynamic), Action>()
|
||||
{
|
||||
|
|
@ -63,27 +63,27 @@ namespace AgroBase.Forms.IHM
|
|||
});
|
||||
FuncoesGlobais.DefinirEventosPicBtn(picDesligar, "Erro ao desligar equipamento!", async () =>
|
||||
{
|
||||
var res = CustomDialog.ShowDialog(
|
||||
"Desligar",
|
||||
"Deseja Desligar o Equipamento?",
|
||||
MessageBoxIcon.Question,
|
||||
new Dictionary<(string, DialogResult?), Action>()
|
||||
{
|
||||
{ ("Sim", DialogResult.Yes), () => { } },
|
||||
{ ("Não", DialogResult.No), () => { } },
|
||||
}
|
||||
);
|
||||
if (res == DialogResult.Yes)
|
||||
if (Variaveis.Producao)
|
||||
{
|
||||
if (!Variaveis.Producao)
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
else
|
||||
var res = CustomDialog.ShowDialog(
|
||||
"Desligar",
|
||||
"Deseja Desligar o Equipamento?",
|
||||
MessageBoxIcon.Question,
|
||||
new Dictionary<(string, DialogResult?), Action>()
|
||||
{
|
||||
{ ("Sim", DialogResult.Yes), () => { } },
|
||||
{ ("Não", DialogResult.No), () => { } },
|
||||
}
|
||||
);
|
||||
if (res == DialogResult.Yes)
|
||||
{
|
||||
Process.Start("shutdown", "/s /t 0");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
});
|
||||
FuncoesGlobais.DefinirEventosPicBtn(picWifi, "Erro ao procurar por atualizações!", async () =>
|
||||
{
|
||||
|
|
@ -126,9 +126,11 @@ namespace AgroBase.Forms.IHM
|
|||
{
|
||||
lblVersao.Text = "v " + Variaveis.Versao;
|
||||
|
||||
tmrDispositivos?.Dispose();
|
||||
tmrDispositivos = new AsyncTaskTimerModel("tmrDispositivos", tmrDispositivos_Tick, 1000, this);
|
||||
tmrDispositivos.Start();
|
||||
|
||||
lblCodigoFalha.Click -= LblCodigoFalha_Click;
|
||||
lblCodigoFalha.Click += LblCodigoFalha_Click;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -499,6 +499,7 @@
|
|||
this.Name = "frmInicioOperacao";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "Preparando operação...";
|
||||
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.frmInicioOperacao_FormClosing);
|
||||
this.Load += new System.EventHandler(this.frmInicioOperacao_Load);
|
||||
this.fpnlInformacoes.ResumeLayout(false);
|
||||
this.fpnlInformacoes.PerformLayout();
|
||||
|
|
|
|||
|
|
@ -207,11 +207,16 @@ namespace AgroBase.Forms.Operacoes
|
|||
{
|
||||
try
|
||||
{
|
||||
(bool sucesso, List<string> ruas) = await Variaveis.OperacaoEmAndamento.CarregarParametrizacaoOperacao(frmDialogo.pnlMapa, frmDialogo.lblMapaCarregado, path);
|
||||
(bool sucesso, List<string> ruas) = Variaveis.OperacaoEmAndamento.CarregarParametrizacaoOperacao(frmDialogo.pnlMapa, frmDialogo.lblMapaCarregado, path);
|
||||
|
||||
bool condicaoOperacaoCarregada() => Variaveis.OperacaoEmAndamento.Trajetoria?.CorredorAtual != null;
|
||||
bool resultado = await FuncoesGlobais.AguardarCondicaoAsync(condicaoOperacaoCarregada, 5000, 200);
|
||||
|
||||
if (!resultado)
|
||||
{
|
||||
throw new Exception("Erro ao carregar a trajetória do mapa!");
|
||||
}
|
||||
|
||||
ruasSelecionadas = ruas;
|
||||
|
||||
foreach (var chb in fpnlInformacoes.Controls.OfType<CheckBox>())
|
||||
|
|
@ -235,7 +240,7 @@ namespace AgroBase.Forms.Operacoes
|
|||
{
|
||||
CustomDialog.ShowDialog(
|
||||
"Erro",
|
||||
"Erro ao carregar operação!",
|
||||
$"Erro ao carregar operação!{Environment.NewLine}{ex.Message}",
|
||||
MessageBoxIcon.Error,
|
||||
new Dictionary<(string, dynamic), Action>()
|
||||
{
|
||||
|
|
@ -336,6 +341,12 @@ namespace AgroBase.Forms.Operacoes
|
|||
return icon.ToBitmap();
|
||||
}
|
||||
|
||||
|
||||
private void frmInicioOperacao_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
if (!frmDialogo.IsDisposed)
|
||||
{
|
||||
frmDialogo.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ namespace AgroBase.Forms.Operacoes
|
|||
//LogsKinect = JsonConvert.DeserializeObject<KinectModel[]>(DeserializarDadosOperacao(ofd.FileName, data.knt ?? Enums.T_Code.Knt.ToString())).ToList();
|
||||
LogsCam_Caminho = JsonConvert.DeserializeObject<CamCaminhoSensoriamentoLogModel[]>(OperacaoModel.DeserializarDadosOperacao(ofd.FileName, data.cam_caminho)).ToList();
|
||||
pathImagensSonarRGB = ofd.FileName.Replace("data.lgop", data.knt + "/rgb_");
|
||||
pathImagensMapaCalor = ofd.FileName.Replace("data.lgop", data.knt + "/heat_");
|
||||
pathImagensMapaCalor = ofd.FileName.Replace("data.lgop", data.cam_caminho + "/");
|
||||
pathImagensCaminho = ofd.FileName.Replace("data.lgop", data.cam_caminho + "/");
|
||||
|
||||
LogsCam_Solo = new List<List<CamSoloSensoriamentoLogModel>>();
|
||||
|
|
@ -974,9 +974,13 @@ namespace AgroBase.Forms.Operacoes
|
|||
}
|
||||
}
|
||||
|
||||
private Bitmap CarregarImagemCamera(string Caminho)
|
||||
private Bitmap CarregarImagemCamera(string Caminho, string complemento = "")
|
||||
{
|
||||
string caminhoCompleto = Caminho + trbMomento.Value + ".jpg";
|
||||
if (!string.IsNullOrEmpty(complemento))
|
||||
{
|
||||
caminhoCompleto = caminhoCompleto.Replace(".jpg", $"{complemento}.jpg");
|
||||
}
|
||||
Bitmap frame = new Bitmap(1, 1);
|
||||
using (Graphics g = Graphics.FromImage(frame))
|
||||
{
|
||||
|
|
@ -1132,6 +1136,7 @@ namespace AgroBase.Forms.Operacoes
|
|||
private void AtualizarInformacoesCameras()
|
||||
{
|
||||
picCameraCaminho.Image = CarregarImagemCamera(pathImagensCaminho);
|
||||
picMapaCalor.Image = CarregarImagemCamera(pathImagensMapaCalor, "_heat");
|
||||
AtualizarInformacoesCameraCaminho();
|
||||
|
||||
for (int i = 0; i < LogsCam_Solo.Count(); i++)
|
||||
|
|
@ -1180,7 +1185,7 @@ namespace AgroBase.Forms.Operacoes
|
|||
txtGPS_Velocidade.Text = (Log?.Velocidade ?? 0).ToString("0.00") + " (" + ((Log?.Velocidade ?? 0) * GPSUtils.ConversaoNosKmh).ToString("0.00") + " km/h)";
|
||||
|
||||
int ID = Convert.ToInt32(Variaveis.IsAgroMonitor ? Variaveis.OperacaoEmAndamento.DispSen.Dados.LoRaParametrosBase.address : Variaveis.ConexaoLoRa.parametros.address);
|
||||
GPSService.EnviarCoordenadasParaMapa(Log?.Latitude ?? 0, Log?.Longitude ?? 0, Log?.CursoVerdadeiro ?? 0, true, ID);
|
||||
GPSService.EnviarCoordenadasParaMapa(Log?.Latitude ?? 0, Log?.Longitude ?? 0, Log?.AnguloCarroDefinido ?? 0, true, ID);
|
||||
|
||||
lblGPS.ForeColor = !Log.Inicializado ? Color.Red : Color.Black;
|
||||
|
||||
|
|
@ -1200,7 +1205,7 @@ namespace AgroBase.Forms.Operacoes
|
|||
null, //LogKnt.Iniciado && LogKnt.StatusDetecao ? LogKnt.ObstaculoCritico : null,
|
||||
(float)LogOpe.Trajetoria.AnguloCaminho,
|
||||
(float)LogOpe.Gps.AnguloCarroDefinido,
|
||||
new GPSModel() { Latitude = Log.Latitude, Longitude = Log.Longitude },
|
||||
Log,
|
||||
_trajaetoria,
|
||||
null, //Variaveis.OperacaoEmAndamento.Mapa.TrajetoriaProjetada.FirstOrDefault(),
|
||||
new List<GPSModel>(LogsGPS.Take(LogsGPS.IndexOf(Log) + 1)),
|
||||
|
|
@ -1385,7 +1390,7 @@ namespace AgroBase.Forms.Operacoes
|
|||
lblMagnetometro.ForeColor = !LogWit.Inicializado ? Color.Red : Color.Black;
|
||||
pnlOrientacaoMagnetometro.Invalidate();
|
||||
pnlInclinacao.Invalidate();
|
||||
visualizador3D.AtualizarAngulos(LogWit.AngleX, LogWit.AngleY, LogWit.AngleZ);
|
||||
visualizador3D.AtualizarAngulos(-LogWit.AngleX, -LogWit.AngleY, LogWit.AngleZ);
|
||||
txtTemperatura.Text = LogWit.Temperatura.ToString("0.00");
|
||||
txtAltitude.Text = LogWit.Altitude.ToString("0.00");
|
||||
txtPressao.Text = LogWit.Pressao + " Pa (" + (LogWit.Pressao / 101300.0).ToString("0.00") + " atm)";
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
using AgroBase.Models;
|
||||
using AgroBase.Services;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
|
@ -37,7 +36,7 @@ namespace AgroBase.Forms
|
|||
GeneralJoystick.IniciarRotinas();
|
||||
VersionamentoService.IniciarRotinas();
|
||||
|
||||
EncerrarProcessosPython();
|
||||
PythonService.EncerrarProcessos();
|
||||
}
|
||||
|
||||
private void frmInstancial_Shown(object sender, EventArgs e)
|
||||
|
|
@ -107,30 +106,12 @@ namespace AgroBase.Forms
|
|||
await Task.Delay(500);
|
||||
}
|
||||
|
||||
EncerrarProcessosPython();
|
||||
PythonService.EncerrarProcessos();
|
||||
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
private static void EncerrarProcessosPython()
|
||||
{
|
||||
foreach (var processo in Process.GetProcessesByName("python"))
|
||||
{
|
||||
try
|
||||
{
|
||||
// Verifica os argumentos do processo
|
||||
string argumentos = processo.StartInfo.Arguments;
|
||||
if (argumentos.Contains("--source=" + Variaveis.NomeAplicacao) || true)
|
||||
{
|
||||
processo.Kill(); // Encerra apenas os processos marcados pelo sistema
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Erro ao encerrar processo: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -62,9 +62,14 @@ namespace AgroBase.Models
|
|||
}
|
||||
browserRgb = null;
|
||||
Task.Run(async () => await Variaveis.MqttService.UnsubscribeAsync(camera._mqttTopico));
|
||||
if (camera.pythonProcess != null)
|
||||
|
||||
lock (camera.processLock)
|
||||
{
|
||||
camera.pythonProcess.Kill();
|
||||
if (camera.pythonProcess != null)
|
||||
{
|
||||
camera.pythonProcess.Kill();
|
||||
camera.pythonProcess = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -150,7 +155,10 @@ namespace AgroBase.Models
|
|||
var depth_data = Leitura.depth_data;
|
||||
|
||||
if (depth_data == null || depth_data.Count == 0)
|
||||
throw new InvalidOperationException("Dados de profundidade inválidos.");
|
||||
{
|
||||
return null;
|
||||
//throw new InvalidOperationException("Dados de profundidade inválidos.");
|
||||
}
|
||||
|
||||
int height = depth_data.Count;
|
||||
int width = depth_data[0].Count;
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ namespace AgroBase.Models
|
|||
public OAKCameraModel device_data { get; set; }
|
||||
public double x_max { get; set; }
|
||||
public double y_max { get; set; }
|
||||
public OAKDLiteSubdivisoesModel subdivisoes { get; set; }
|
||||
public List<List<int>> depth_data { get; set; } = new List<List<int>>();
|
||||
public List<CameraDeepLabV3PlusClasseModel> Classes { get; set; } = new List<CameraDeepLabV3PlusClasseModel>();
|
||||
|
||||
|
|
@ -71,11 +72,64 @@ namespace AgroBase.Models
|
|||
x_max = x_max,
|
||||
y_max = y_max,
|
||||
depth_data = new List<List<int>>(depth_data),
|
||||
Classes = new List<CameraDeepLabV3PlusClasseModel>(Classes)
|
||||
Classes = new List<CameraDeepLabV3PlusClasseModel>(Classes),
|
||||
subdivisoes = subdivisoes?.Clone()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class OAKDLiteSubdivisoesModel
|
||||
{
|
||||
public int x_max { get; set; }
|
||||
public int y_max { get; set; }
|
||||
|
||||
public SubdivisaoModel subdivisoes_cima { get; set; }
|
||||
public SubdivisaoModel subdivisoes_chao { get; set; }
|
||||
|
||||
public OAKDLiteSubdivisoesModel Clone()
|
||||
{
|
||||
return new OAKDLiteSubdivisoesModel()
|
||||
{
|
||||
x_max = x_max,
|
||||
y_max = y_max,
|
||||
subdivisoes_chao = subdivisoes_chao?.Clone(),
|
||||
subdivisoes_cima = subdivisoes_cima?.Clone()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class SubdivisaoModel
|
||||
{
|
||||
public int num_linhas { get; set; }
|
||||
public int num_colunas { get; set; }
|
||||
public List<CelulaModel> celulas { get; set; }
|
||||
|
||||
public SubdivisaoModel Clone()
|
||||
{
|
||||
return new SubdivisaoModel()
|
||||
{
|
||||
num_linhas = num_linhas,
|
||||
num_colunas = num_colunas,
|
||||
celulas = new List<CelulaModel>(celulas)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class CelulaModel
|
||||
{
|
||||
public int linha { get; set; }
|
||||
public int coluna { get; set; }
|
||||
|
||||
public int x { get; set; }
|
||||
public int y { get; set; }
|
||||
|
||||
public int largura { get; set; }
|
||||
public int altura { get; set; }
|
||||
|
||||
public double profundidade_media { get; set; }
|
||||
public double profundidade_calibragem { get; set; }
|
||||
}
|
||||
|
||||
public class CameraDeepLabV3PlusClasseModel
|
||||
{
|
||||
public string Classe { get; set; }
|
||||
|
|
|
|||
|
|
@ -24,10 +24,14 @@ namespace AgroBase.Models
|
|||
panel.Controls.Remove(browser);
|
||||
}
|
||||
browser = null;
|
||||
Task.Run(async () => Variaveis.MqttService.UnsubscribeAsync(camera._mqttTopico));
|
||||
if (camera.pythonProcess != null && !camera.pythonProcess.HasExited)
|
||||
Task.Run(async () => await Variaveis.MqttService.UnsubscribeAsync(camera._mqttTopico));
|
||||
lock (camera.processLock)
|
||||
{
|
||||
camera.pythonProcess.Kill();
|
||||
if (camera.pythonProcess != null)
|
||||
{
|
||||
camera.pythonProcess.Kill();
|
||||
camera.pythonProcess = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ namespace AgroBase.Models
|
|||
{
|
||||
try
|
||||
{
|
||||
lock (mapaService.pythonProcess)
|
||||
lock (mapaService.processLock)
|
||||
{
|
||||
if (mapaService.pythonProcess == null)
|
||||
{
|
||||
|
|
@ -137,7 +137,7 @@ namespace AgroBase.Models
|
|||
|
||||
IniciarProcessamento();
|
||||
|
||||
lock (mapaService.pythonProcess)
|
||||
lock (mapaService.processLock)
|
||||
{
|
||||
mapaService.pythonProcess.Dispose();
|
||||
mapaService.pythonProcess = null;
|
||||
|
|
|
|||
|
|
@ -353,7 +353,7 @@ namespace AgroBase.Models
|
|||
return true;
|
||||
}
|
||||
|
||||
public async Task<(bool, List<string>)> CarregarParametrizacaoOperacao(Panel pnlMapa, Label lblMapa, string opPath = "")
|
||||
public (bool, List<string>) CarregarParametrizacaoOperacao(Panel pnlMapa, Label lblMapa, string opPath = "")
|
||||
{
|
||||
string path = Variaveis.CaminhoSistema + Variaveis.CaminhoOperacoes + MapasVariaveisModel.NomeArquivoMapaInterativoSaida;
|
||||
|
||||
|
|
@ -418,8 +418,8 @@ namespace AgroBase.Models
|
|||
|
||||
Variaveis.OperacaoEmAndamento.Mapa.btnCarregar_Click(new object(), new EventArgs(), path);
|
||||
|
||||
bool condicaoMapaCarregado() => Variaveis.OperacaoEmAndamento.Mapa.mapaService.Carregado;
|
||||
bool resultado = await FuncoesGlobais.AguardarCondicaoAsync(condicaoMapaCarregado, 5000, 200);
|
||||
//bool condicaoMapaCarregado() => Variaveis.OperacaoEmAndamento.Mapa.mapaService.Carregado;
|
||||
//bool resultado = await FuncoesGlobais.AguardarCondicaoAsync(condicaoMapaCarregado, 5000, 200);
|
||||
}
|
||||
|
||||
return (true, ruasSelecionadas);
|
||||
|
|
@ -761,6 +761,8 @@ namespace AgroBase.Models
|
|||
|
||||
Variaveis.OperacaoEmAndamento.Controle.Angulo = Variaveis.OperacaoEmAndamento.Controle.Angulo_Max;
|
||||
Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeSP = Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeMin;
|
||||
|
||||
Variaveis.OperacaoEmAndamento.Sensoriamento.AtualizarDados();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -830,13 +832,14 @@ namespace AgroBase.Models
|
|||
|
||||
Variaveis.OperacaoEmAndamento.Finalizando = true;
|
||||
|
||||
PararCarroOperacaoInterrompida(true);
|
||||
Variaveis.OperacaoEmAndamento.Trajetoria?.LoopAtualizaDados();
|
||||
|
||||
Variaveis.OperacaoEmAndamento.Trajetoria.LoopAtualizaDados();
|
||||
Variaveis.OperacaoEmAndamento.PararCarroOperacaoInterrompida(true);
|
||||
|
||||
await Task.Delay(2000);
|
||||
|
||||
Variaveis.OperacaoEmAndamento.Iniciado = false;
|
||||
|
||||
Variaveis.OperacaoEmAndamento.DataFim = DateTime.Now;
|
||||
|
||||
tmrLogs?.Stop();
|
||||
|
|
@ -1022,11 +1025,11 @@ namespace AgroBase.Models
|
|||
return;
|
||||
}
|
||||
|
||||
Variaveis.OperacaoEmAndamento.DesligarCameras();
|
||||
|
||||
//var listaCameras = CameraService.ObterListaCameras().Values.ToArray();
|
||||
var listaCameras = OAKCameraService.GetListaCameras();
|
||||
|
||||
CamerasSolo.ForEach(cam => cam.DesligarCamera());
|
||||
|
||||
CamerasSolo.Clear();
|
||||
for (int i = 0; i < QuantidadeCamerasSolo; i++)
|
||||
{
|
||||
|
|
@ -1093,11 +1096,11 @@ namespace AgroBase.Models
|
|||
CameraCaminho.camera.cameraIndex = listaCameras.FirstOrDefault(x => x.Id == CameraCaminho.DeviceID)?.Index ?? -1;
|
||||
if (CameraCaminho.camera.cameraIndex > -1 && Iniciar) // && Variaveis.OperacaoEmAndamento.Controle.SegmentacaoSemantica
|
||||
{
|
||||
if (pnlCameraCaminho.Count() > 0)
|
||||
if (pnlCameraCaminho.Count > 0)
|
||||
{
|
||||
CameraCaminho.panelRgb = pnlCameraCaminho[0];
|
||||
}
|
||||
if (pnlCameraCaminho.Count() > 1)
|
||||
if (pnlCameraCaminho.Count > 1)
|
||||
{
|
||||
CameraCaminho.panelHeatmap = pnlCameraCaminho[1];
|
||||
}
|
||||
|
|
@ -1136,18 +1139,16 @@ namespace AgroBase.Models
|
|||
{
|
||||
CameraSolo.camera.ProntoEm = Mensagem.Momento;
|
||||
|
||||
if (CameraSolo.browser == null)
|
||||
if (CameraSolo.browser == null && CameraSolo.panel != null)
|
||||
{
|
||||
CameraSolo.Iniciada = true;
|
||||
CameraSolo.browser = new ChromiumWebBrowser(CameraSolo.camera.URLcamera[0]);
|
||||
CameraSolo.browser.Dock = DockStyle.Fill;
|
||||
|
||||
CameraSolo.panel.Invoke(new Action(async () =>
|
||||
CameraSolo.panel.Invoke(new Action(() =>
|
||||
{
|
||||
CameraSolo.panel.Controls.Add(CameraSolo.browser);
|
||||
CameraSolo.panel.Refresh();
|
||||
await Task.Delay(500);
|
||||
CameraSolo.panel.Refresh();
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
@ -1189,7 +1190,7 @@ namespace AgroBase.Models
|
|||
async (Mensagem) =>
|
||||
{
|
||||
cameraCaminho.UltimaMensagemRecebida = DateTime.Now;
|
||||
if (Mensagem.Momento > cameraCaminho.camera.IniciadoEm && Mensagem.Mensagem == "OK")
|
||||
if (Mensagem.Momento > cameraCaminho.camera.IniciadoEm && Mensagem.Mensagem == "OK_1")
|
||||
{
|
||||
cameraCaminho.camera.ProntoEm = Mensagem.Momento;
|
||||
|
||||
|
|
@ -1197,32 +1198,37 @@ namespace AgroBase.Models
|
|||
{
|
||||
cameraCaminho.Iniciada = true;
|
||||
|
||||
if (cameraCaminho.camera.URLcamera.Count() > 0)
|
||||
if (cameraCaminho.camera.URLcamera.Count > 0)
|
||||
{
|
||||
cameraCaminho.browserRgb = new ChromiumWebBrowser(cameraCaminho.camera.URLcamera[0]);
|
||||
cameraCaminho.browserRgb.Dock = DockStyle.Fill;
|
||||
|
||||
cameraCaminho.panelRgb.Invoke(new Action(async () =>
|
||||
cameraCaminho.panelRgb.Invoke(new Action(() =>
|
||||
{
|
||||
cameraCaminho.panelRgb.Controls.Add(cameraCaminho.browserRgb);
|
||||
cameraCaminho.panelRgb.Refresh();
|
||||
await Task.Delay(500);
|
||||
cameraCaminho.panelRgb.Refresh();
|
||||
cameraCaminho.browserRgb.Refresh();
|
||||
}));
|
||||
FuncoesGlobais.ValidarImagemCameraBrowser(cameraCaminho.browserRgb, cameraCaminho.panelRgb);
|
||||
}
|
||||
await Task.Delay(1000);
|
||||
if (cameraCaminho.camera.URLcamera.Count() > 1)
|
||||
}
|
||||
}
|
||||
else if (Mensagem.Momento > cameraCaminho.camera.IniciadoEm && Mensagem.Mensagem == "OK_2")
|
||||
{
|
||||
cameraCaminho.camera.ProntoEm = Mensagem.Momento;
|
||||
|
||||
if (cameraCaminho.browserHeatmap == null && cameraCaminho.panelHeatmap != null)
|
||||
{
|
||||
cameraCaminho.Iniciada = true;
|
||||
|
||||
if (cameraCaminho.camera.URLcamera.Count > 1)
|
||||
{
|
||||
cameraCaminho.browserHeatmap = new ChromiumWebBrowser(cameraCaminho.camera.URLcamera[1]);
|
||||
cameraCaminho.browserHeatmap.Dock = DockStyle.Fill;
|
||||
|
||||
cameraCaminho.panelHeatmap.Invoke(new Action(async () =>
|
||||
cameraCaminho.panelHeatmap.Invoke(new Action(() =>
|
||||
{
|
||||
cameraCaminho.panelHeatmap.Controls.Add(cameraCaminho.browserHeatmap);
|
||||
cameraCaminho.panelHeatmap.Refresh();
|
||||
await Task.Delay(500);
|
||||
cameraCaminho.panelHeatmap.Refresh();
|
||||
cameraCaminho.browserHeatmap.Refresh();
|
||||
}));
|
||||
FuncoesGlobais.ValidarImagemCameraBrowser(cameraCaminho.browserHeatmap, cameraCaminho.panelHeatmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1242,7 +1248,7 @@ namespace AgroBase.Models
|
|||
{
|
||||
Camera.DesligarCamera();
|
||||
});
|
||||
Variaveis.OperacaoEmAndamento.CameraCaminho.DesligarCamera();
|
||||
Variaveis.OperacaoEmAndamento.CameraCaminho?.DesligarCamera();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
@ -1251,13 +1257,8 @@ namespace AgroBase.Models
|
|||
|
||||
public void AtualizaInformacoesControleOperacao()
|
||||
{
|
||||
if (Variaveis.OperacaoEmAndamento.Modo == ModoOperacao.Manual)
|
||||
if (Variaveis.OperacaoEmAndamento.Modo == ModoOperacao.MapaGPS)
|
||||
{
|
||||
VerificarDesvioPorObstaculos();
|
||||
}
|
||||
else
|
||||
{
|
||||
//Variaveis.OperacaoEmAndamento.OpMapaGPS.CalculaDadosMovimentacaoAutonoma();
|
||||
Variaveis.OperacaoEmAndamento.AtualizarDadosControle(false);
|
||||
}
|
||||
}
|
||||
|
|
@ -1268,7 +1269,7 @@ namespace AgroBase.Models
|
|||
|
||||
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
|
||||
|
||||
bool MovimentoLiberado = Variaveis.OperacaoEmAndamento.StatusAtual != StatusOperacao.Aguardando && Variaveis.OperacaoEmAndamento.StatusAtual != StatusOperacao.Parado && !MKS057DService.Referenciando;
|
||||
bool MovimentoLiberado = Variaveis.OperacaoEmAndamento.StatusAtual == StatusOperacao.EmAndamento && !MKS057DService.Referenciando;
|
||||
|
||||
if (MovimentoLiberado || ForcarEnvio)
|
||||
{
|
||||
|
|
@ -1401,41 +1402,44 @@ namespace AgroBase.Models
|
|||
|
||||
private void VerificarDesvioPorObstaculos()
|
||||
{
|
||||
var Sonar = Variaveis.OperacaoEmAndamento.Sensoriamento.SonarFrontal_Kinect;
|
||||
if (Variaveis.OperacaoEmAndamento.Controle.SonarAtivado && (Sonar?.Iniciado ?? false) && (Sonar?.DesvioNecessario ?? false))
|
||||
if (Variaveis.OperacaoEmAndamento.Controle.SonarAtivado)
|
||||
{
|
||||
Keys TeclaComando =
|
||||
Sonar.DirecaoDesvio == Direcao.Esquerda ? Keys.Left :
|
||||
Sonar.DirecaoDesvio == Direcao.Direita ? Keys.Right :
|
||||
Keys.Escape;
|
||||
var Sonar = Variaveis.OperacaoEmAndamento.Sensoriamento.SonarFrontal_Kinect;
|
||||
if ((Sonar?.Iniciado ?? false) && (Sonar?.DesvioNecessario ?? false))
|
||||
{
|
||||
Keys TeclaComando =
|
||||
Sonar.DirecaoDesvio == Direcao.Esquerda ? Keys.Left :
|
||||
Sonar.DirecaoDesvio == Direcao.Direita ? Keys.Right :
|
||||
Keys.Escape;
|
||||
|
||||
if (Variaveis.OperacaoEmAndamento.Controle.SonarDesvioAutomatico)
|
||||
{
|
||||
Variaveis.OperacaoEmAndamento.Controle.Angulo = Sonar.AnguloDesvio;
|
||||
GeneralJoystick.EnviaComandoMotor(TeclaComando, T_Code.Dir);
|
||||
if (Variaveis.OperacaoEmAndamento.Controle.SonarDesvioAutomatico)
|
||||
{
|
||||
Variaveis.OperacaoEmAndamento.Controle.Angulo = Sonar.AnguloDesvio;
|
||||
GeneralJoystick.EnviaComandoMotor(TeclaComando, T_Code.Dir);
|
||||
}
|
||||
if (Sonar.DirecaoDesvio == Direcao.Parado)
|
||||
{
|
||||
GeneralJoystick.EnviaComandoMotor(Keys.Escape, T_Code.Mov);
|
||||
}
|
||||
}
|
||||
if (Sonar.DirecaoDesvio == Direcao.Parado)
|
||||
{
|
||||
GeneralJoystick.EnviaComandoMotor(Keys.Escape, T_Code.Mov);
|
||||
}
|
||||
}
|
||||
|
||||
var Ultrassom = UltrasonicA05Service.DadosLeitura.Configuracao;
|
||||
if (UltrasonicA05Service.Iniciado)
|
||||
{
|
||||
Keys TeclaComando =
|
||||
Ultrassom.DirecaoDesvio == Direcao.Esquerda ? Keys.Left :
|
||||
Ultrassom.DirecaoDesvio == Direcao.Direita ? Keys.Right :
|
||||
Keys.Escape;
|
||||
var Ultrassom = UltrasonicA05Service.DadosLeitura.Configuracao;
|
||||
if (UltrasonicA05Service.Iniciado && Ultrassom.DesvioNecessario)
|
||||
{
|
||||
Keys TeclaComando =
|
||||
Ultrassom.DirecaoDesvio == Direcao.Esquerda ? Keys.Left :
|
||||
Ultrassom.DirecaoDesvio == Direcao.Direita ? Keys.Right :
|
||||
Keys.Escape;
|
||||
|
||||
if (Ultrassom.ParadaNecessaria)
|
||||
{
|
||||
GeneralJoystick.EnviaComandoMotor(Keys.Escape, T_Code.Mov);
|
||||
}
|
||||
else if (Variaveis.OperacaoEmAndamento.Controle.SonarDesvioAutomatico && Ultrassom.DesvioNecessario)
|
||||
{
|
||||
Variaveis.OperacaoEmAndamento.Controle.Angulo = Variaveis.OperacaoEmAndamento.Controle.Angulo_Max;
|
||||
GeneralJoystick.EnviaComandoMotor(TeclaComando, T_Code.Dir);
|
||||
if (Ultrassom.ParadaNecessaria)
|
||||
{
|
||||
GeneralJoystick.EnviaComandoMotor(Keys.Escape, T_Code.Mov);
|
||||
}
|
||||
else if (Ultrassom.DesvioNecessario)
|
||||
{
|
||||
Variaveis.OperacaoEmAndamento.Controle.Angulo = Variaveis.OperacaoEmAndamento.Controle.Angulo_Max;
|
||||
GeneralJoystick.EnviaComandoMotor(TeclaComando, T_Code.Dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1595,13 +1599,14 @@ namespace AgroBase.Models
|
|||
}
|
||||
|
||||
var MqttTopico = cameraCaminho.camera._mqttTopico;
|
||||
if (MqttTopico != null && MqttTopico.Mensagens.Any(x => x.Momento > cameraCaminho.camera.IniciadoEm))
|
||||
if (MqttTopico != null && MqttTopico.Mensagens.Any(x => x.Momento > cameraCaminho.camera.IniciadoEm && !x.Mensagem.StartsWith("OK")))
|
||||
{
|
||||
try
|
||||
{
|
||||
var Mensagem = MqttTopico.Mensagens.LastOrDefault(x => x.Momento > cameraCaminho.camera.IniciadoEm);
|
||||
if (Mensagem != null)
|
||||
{
|
||||
Console.WriteLine(Mensagem.Mensagem);
|
||||
cameraCaminho.Leitura = JsonConvert.DeserializeObject<CameraDeepLabV3PlusModel>(Mensagem.Mensagem);
|
||||
}
|
||||
}
|
||||
|
|
@ -1797,7 +1802,21 @@ namespace AgroBase.Models
|
|||
|
||||
private void PararCarroOperacaoInterrompida(bool finalizar)
|
||||
{
|
||||
AtualizarDadosControle(true);
|
||||
var Controle = Variaveis.OperacaoEmAndamento.Controle;
|
||||
|
||||
if (Variaveis.OperacaoEmAndamento.Modo == ModoOperacao.MapaGPS)
|
||||
{
|
||||
Variaveis.OperacaoEmAndamento.AtualizarDadosControle(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
GeneralJoystick.EnviaComandoMotor(Keys.Escape, T_Code.Mov, true);
|
||||
GeneralJoystick.EnviaComandoMotor(Keys.Escape, T_Code.Dir, true);
|
||||
foreach (var bico in Variaveis.OperacaoEmAndamento.DispAtu.Dados.BicosPulverizadores)
|
||||
{
|
||||
GeneralJoystick.EnviarComandoAtuador(S_Code.sBIC, false, bico.ID, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (finalizar)
|
||||
{
|
||||
|
|
@ -1808,7 +1827,7 @@ namespace AgroBase.Models
|
|||
}
|
||||
}
|
||||
|
||||
Variaveis.OperacaoEmAndamento.Controle.TiposControle.ForEach(x => x.UltimaDirecao = Direcao.Parado);
|
||||
Controle.TiposControle.ForEach(x => x.UltimaDirecao = Direcao.Parado);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2060,13 +2079,14 @@ namespace AgroBase.Models
|
|||
{
|
||||
tipo = typeof(CamSoloSensoriamentoLogModel),
|
||||
nome = x.Nome,
|
||||
browser = x.browser
|
||||
browsers = new List<ChromiumWebBrowser>() { x.browser }
|
||||
})
|
||||
.Union(new[] {
|
||||
new {
|
||||
tipo = typeof(CamCaminhoSensoriamentoLogModel),
|
||||
nome = cameraCaminho.Nome,
|
||||
browser = cameraCaminho.browserRgb
|
||||
browsers = new List<ChromiumWebBrowser>() { cameraCaminho.browserRgb, cameraCaminho.browserHeatmap },
|
||||
|
||||
}
|
||||
})
|
||||
.ToList();
|
||||
|
|
@ -2093,8 +2113,11 @@ namespace AgroBase.Models
|
|||
};
|
||||
SalvarLog(Camera.nome, logCam, false);
|
||||
|
||||
frame = await FuncoesGlobais.GetBrowserImage(Camera.browser);
|
||||
FuncoesGlobais.SalvarImagemComprimida(frame, Caminho, 100L, 716, 403);
|
||||
foreach (var browser in Camera.browsers)
|
||||
{
|
||||
frame = await FuncoesGlobais.GetBrowserImage(browser);
|
||||
FuncoesGlobais.SalvarImagemComprimida(frame, Caminho, 100L, 716, 403);
|
||||
}
|
||||
}
|
||||
else if (Camera.tipo == typeof(CamCaminhoSensoriamentoLogModel))
|
||||
{
|
||||
|
|
@ -2112,11 +2135,18 @@ namespace AgroBase.Models
|
|||
};
|
||||
SalvarLog(Camera.nome, logCam, false);
|
||||
|
||||
frame = await FuncoesGlobais.GetBrowserImage(Camera.browser);
|
||||
FuncoesGlobais.SalvarImagemComprimida(frame, Caminho, 100L, 716, 403);
|
||||
foreach (var browser in Camera.browsers)
|
||||
{
|
||||
int idx = Camera.browsers.IndexOf(browser);
|
||||
frame = await FuncoesGlobais.GetBrowserImage(browser);
|
||||
if (idx == 1)
|
||||
{
|
||||
Caminho = Caminho.Replace(".jpg", "_heat.jpg");
|
||||
}
|
||||
FuncoesGlobais.SalvarImagemComprimida(frame, Caminho, 30L, 716, 403);
|
||||
}
|
||||
|
||||
Bitmap heatBitmap = cameraCaminho.GenerateHeatmapBitmap();
|
||||
FuncoesGlobais.SalvarImagemComprimida(heatBitmap, Caminho.Replace(".jpg", "_heat.jpg"), 30L);
|
||||
//Bitmap heatBitmap = cameraCaminho.GenerateHeatmapBitmap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ namespace AgroBase.Models
|
|||
}
|
||||
|
||||
public List<PontoTrajetoriaModel> _TrajetoriaFixa { get; set; }
|
||||
private bool _TrajetoriaFixaDefinida
|
||||
public bool _TrajetoriaFixaDefinida
|
||||
{
|
||||
get
|
||||
{
|
||||
|
|
@ -895,11 +895,22 @@ namespace AgroBase.Models
|
|||
|
||||
if (_trajetoriaFixa.Count() > 1 && idxEsq == 0 && idxDir == 0)
|
||||
{
|
||||
var p0 = _trajetoriaFixa.Where(x => x.Tipo == TipoPontoRua.Rua).Skip(2).FirstOrDefault();
|
||||
var p1 = _trajetoriaFixa.Where(x => x.Tipo == TipoPontoRua.Rua).Skip(3).FirstOrDefault();
|
||||
(List<GPSModel> ruaEsq, List<GPSModel> ruaDir) = DeterminarRuasLaterais(p0.Posicao, p1.Posicao, RuasPlantacao[0], RuasPlantacao[1]);
|
||||
idxEsq = RuasPlantacao.IndexOf(ruaEsq);
|
||||
idxDir = RuasPlantacao.IndexOf(ruaDir);
|
||||
var pontos = _trajetoriaFixa.Where(x => x.Tipo == TipoPontoRua.Rua).ToList();
|
||||
if (pontos.Count >= 2)
|
||||
{
|
||||
var p0 = pontos[0];
|
||||
var p1 = pontos[1];
|
||||
|
||||
(List<GPSModel> ruaEsq, List<GPSModel> ruaDir) = DeterminarRuasLaterais(p0.Posicao, p1.Posicao, RuasPlantacao[0], RuasPlantacao[1]);
|
||||
|
||||
idxEsq = RuasPlantacao.IndexOf(ruaEsq);
|
||||
idxDir = RuasPlantacao.IndexOf(ruaDir);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ⚠️ Caso de erro: não há dois pontos de rua, mesmo com mais de 1 ponto na trajetória.
|
||||
Console.WriteLine("Não há ao menos dois pontos do tipo Rua.");
|
||||
}
|
||||
}
|
||||
|
||||
bool ultimoCorredor = idx == Corredores.Count() - 1;
|
||||
|
|
@ -1391,6 +1402,11 @@ namespace AgroBase.Models
|
|||
|
||||
private void AtualizarDistanciaTrajeto()
|
||||
{
|
||||
if (!Variaveis.OperacaoEmAndamento.Trajetoria._TrajetoriaFixaDefinida)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var pontoAtual = Variaveis.OperacaoEmAndamento.Trajetoria.PontoAtual;
|
||||
int idxPontoAtual = pontoAtual.idxPonto + 1;
|
||||
int qtdPontos = Math.Abs(idxPonto - idxPontoAtual) + 1; // Sempre positivo
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ using CefSharp.WinForms;
|
|||
using System.IO;
|
||||
using System.Threading;
|
||||
using AgroBase.Models.Components;
|
||||
using CefSharp;
|
||||
|
||||
namespace AgroBase.Models
|
||||
{
|
||||
|
|
@ -1064,7 +1065,55 @@ namespace AgroBase.Models
|
|||
}
|
||||
}
|
||||
|
||||
public static void ValidarImagemCameraBrowser(ChromiumWebBrowser nav, Control parent)
|
||||
{
|
||||
nav.LoadingStateChanged += async (sender, args) =>
|
||||
{
|
||||
// Aguarde até terminar de carregar
|
||||
if (!args.IsLoading)
|
||||
{
|
||||
var browser = (ChromiumWebBrowser)sender;
|
||||
|
||||
try
|
||||
{
|
||||
// Espera um pequeno tempo para o conteúdo estar disponível
|
||||
await Task.Delay(500);
|
||||
|
||||
// Executa JavaScript para verificar o conteúdo da página
|
||||
var response = await browser.EvaluateScriptAsync(
|
||||
"document.body ? document.body.innerText : ''");
|
||||
|
||||
if (response.Success && response.Result != null)
|
||||
{
|
||||
string conteudo = response.Result.ToString();
|
||||
|
||||
// Verifica mensagens de erro comuns
|
||||
if (conteudo.Contains("Internal Server Error") || conteudo.Contains("Not Found") || conteudo.Length < 20)
|
||||
{
|
||||
Console.WriteLine("Falha no carregamento do stream, recarregando...");
|
||||
await Task.Delay(1000);
|
||||
|
||||
if (parent.IsHandleCreated)
|
||||
{
|
||||
parent.Invoke(new Action(() =>
|
||||
{
|
||||
browser.Refresh();
|
||||
}));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Câmera carregada com sucesso.");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Erro ao verificar página: {ex.Message}");
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ namespace AgroBase.Services
|
|||
public static Dictionary<string, string> CamerasConectadas = new Dictionary<string, string>();
|
||||
|
||||
public Process pythonProcess;
|
||||
public readonly object processLock = new object();
|
||||
public DateTime? IniciadoEm = null;
|
||||
public DateTime? ProntoEm = null;
|
||||
public DateTime? FinalizadoEm = null;
|
||||
|
|
@ -34,8 +35,11 @@ namespace AgroBase.Services
|
|||
{
|
||||
_mqttTopico = await Variaveis.MqttService.AdicionarNovoTopico(MqttTopico, true, 2, mqttCallback);
|
||||
|
||||
pythonProcess = new Process();
|
||||
pythonProcess = PythonService.RunScript(Script, Argumentos);
|
||||
lock (processLock)
|
||||
{
|
||||
pythonProcess = new Process();
|
||||
pythonProcess = PythonService.RunScript(Script, Argumentos);
|
||||
}
|
||||
IniciadoEm = DateTime.Now;
|
||||
|
||||
foreach (string url in FlaskUrl)
|
||||
|
|
|
|||
|
|
@ -455,7 +455,7 @@ namespace AgroBase.Services
|
|||
PenultimaLeitura.TipoOrientacao = UltimaLeitura.TipoOrientacao;
|
||||
|
||||
UltimaLeitura.Momento = DateTime.Now;
|
||||
UltimaLeitura.OrientacaoReal = (headingTrue + 180) % 360; // Inverter o angulo lido para normalizar com o angulo calculado entre leituras
|
||||
UltimaLeitura.OrientacaoReal = headingTrue;
|
||||
UltimaLeitura.TipoOrientacao = status;
|
||||
|
||||
// ✅ Atualiza o ângulo unificado no GPSService
|
||||
|
|
@ -662,8 +662,8 @@ namespace AgroBase.Services
|
|||
// ✅ Se a trajetória estiver vazia, não há o que calcular
|
||||
if (GPSTrajetoria == null || GPSTrajetoria.Count == 0)
|
||||
{
|
||||
Angulo = GPSUtils.CalcularOrientacao(UltimaLeitura, PenultimaLeitura);
|
||||
DistAngulo = GPSUtils.DistanciaEntrePontos(UltimaLeitura, PenultimaLeitura);
|
||||
Angulo = GPSUtils.CalcularOrientacao(PenultimaLeitura, UltimaLeitura);
|
||||
DistAngulo = GPSUtils.DistanciaEntrePontos(PenultimaLeitura, UltimaLeitura);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -729,9 +729,9 @@ namespace AgroBase.Services
|
|||
double distAnguloGPS = UltimaLeitura.Distancia;
|
||||
|
||||
//anguloFinal = CalcularAnguloUnificado(anguloGPS, UltimaLeitura.QualidadeFix, anguloGPSMovimento, distAnguloGPS);
|
||||
anguloFinal = GPSUtils.MisturarAngulosPorDistancia(anguloGPS, anguloGPSMovimento, distAnguloGPS, TrajetoriaMapaOperacaoModel.DistanciaMaximaEntreLeituras, 0.03, 0.3);
|
||||
//anguloFinal = GPSUtils.MisturarAngulosPorDistancia(anguloGPS, anguloGPSMovimento, distAnguloGPS, TrajetoriaMapaOperacaoModel.DistanciaMaximaEntreLeituras, 0.03, 0.3);
|
||||
|
||||
//anguloFinal = anguloGPS;
|
||||
anguloFinal = anguloGPS;
|
||||
}
|
||||
else if (witIniciado)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using AgroBase.Models;
|
||||
using CefSharp.WinForms;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
|
@ -7,7 +6,6 @@ using System.Diagnostics;
|
|||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace AgroBase.Services
|
||||
{
|
||||
|
|
@ -25,6 +23,7 @@ namespace AgroBase.Services
|
|||
{
|
||||
public OpenFileDialog opfMapa;
|
||||
public Process pythonProcess;
|
||||
public readonly object processLock = new object();
|
||||
private string CaminhoSaida = Variaveis.CaminhoSistema + PythonService.CaminhoGeral + PythonService.CaminhoLeitura;
|
||||
public string NomeArquivoMapa = "";
|
||||
public string NomeArquivos = "";
|
||||
|
|
@ -56,17 +55,20 @@ namespace AgroBase.Services
|
|||
NomeArquivos = CaminhoArquivo.Split('\\')[CaminhoArquivo.Split('\\').Length - 1].Replace(extensao, "");
|
||||
CaminhoMapa = CaminhoArquivo.Replace(NomeArquivos, "").Replace(extensao, "").Replace("\\", "/");
|
||||
|
||||
pythonProcess = PythonService.RunScript(script, new string[]
|
||||
lock (processLock)
|
||||
{
|
||||
CaminhoMapa,
|
||||
NomeArquivos,
|
||||
ArquivoSaida,
|
||||
NomeArquivoMapa,
|
||||
MapasVariaveisModel.TopicoCoordenadasGPS,
|
||||
MapasVariaveisModel.TopicoSelecaoRuasMapa,
|
||||
MapasVariaveisModel.TopicoTrajetoriaDinamica,
|
||||
extensao == ".json" ? "1" : "0"
|
||||
});
|
||||
pythonProcess = PythonService.RunScript(script, new string[]
|
||||
{
|
||||
CaminhoMapa,
|
||||
NomeArquivos,
|
||||
ArquivoSaida,
|
||||
NomeArquivoMapa,
|
||||
MapasVariaveisModel.TopicoCoordenadasGPS,
|
||||
MapasVariaveisModel.TopicoSelecaoRuasMapa,
|
||||
MapasVariaveisModel.TopicoTrajetoriaDinamica,
|
||||
extensao == ".json" ? "1" : "0"
|
||||
});
|
||||
}
|
||||
|
||||
MapaUrl = new Uri(CaminhoSaida + NomeArquivoMapa).AbsoluteUri;
|
||||
CaminhoDadosMapa = CaminhoSaida + ArquivoSaida;
|
||||
|
|
|
|||
|
|
@ -71,7 +71,17 @@ public class MqttService
|
|||
|
||||
if (topico.Callback != null)
|
||||
{
|
||||
Task.Run(async () => await FuncoesGlobais.SafeExecuteAsync(async () => await topico.Callback(Mensagem)));
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await topico.Callback(Mensagem); // await real e funcional
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Erro no callback do tópico '{topico.Topico}': {ex}");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ namespace AgroBase.Services
|
|||
StartInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = "python",
|
||||
Arguments = $"{ScriptPath} {Args}",
|
||||
Arguments = $"{ScriptPath} {Args} --source={Variaveis.NomeAplicacao}",
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = false,
|
||||
RedirectStandardError = false,
|
||||
|
|
@ -88,7 +88,7 @@ namespace AgroBase.Services
|
|||
}
|
||||
};
|
||||
|
||||
Console.WriteLine($"{ScriptPath} {Args}");
|
||||
Console.WriteLine($"{pythonProcess.StartInfo.Arguments}");
|
||||
|
||||
//pythonProcess.Exited += PythonProcess_Exited;
|
||||
//pythonProcess.OutputDataReceived += PythonProcess_OutputDataReceived;
|
||||
|
|
@ -196,13 +196,26 @@ namespace AgroBase.Services
|
|||
}
|
||||
}
|
||||
|
||||
public static void EncerrarProcessos()
|
||||
public static void EncerrarProcessos(int processId = -1)
|
||||
{
|
||||
foreach (var processo in processosIniciados)
|
||||
foreach (var processo in Process.GetProcessesByName("python"))
|
||||
{
|
||||
if (!processo.HasExited)
|
||||
try
|
||||
{
|
||||
processo.Kill();
|
||||
// Verifica os argumentos do processo
|
||||
string argumentos = processo.StartInfo.Arguments;
|
||||
if ((processId > -1 && processo.Id == processId))
|
||||
{
|
||||
processo.Kill();
|
||||
}
|
||||
else if (processId == -1)
|
||||
{
|
||||
processo.Kill();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Erro ao encerrar processo: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.IO.Ports;
|
||||
using System.Linq;
|
||||
using System.Management;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
|
@ -936,11 +935,23 @@ namespace AgroBase.Services
|
|||
Console.WriteLine(msg);
|
||||
if (!Variaveis.IsAgroMonitor)
|
||||
{
|
||||
frmInstancial.frmPrincipal.Invoke((MethodInvoker)(() =>
|
||||
if (frmInstancial.frmPrincipal.IsHandleCreated)
|
||||
{
|
||||
frmInstancial.frmPrincipal.lblStatusConexao.Text = msg;
|
||||
frmInstancial.frmIHM.lblStatus.Text = msg;
|
||||
}));
|
||||
frmInstancial.frmPrincipal.Invoke((MethodInvoker)(() =>
|
||||
{
|
||||
frmInstancial.frmPrincipal.lblStatusConexao.Text = msg;
|
||||
|
||||
if (frmInstancial.frmIHM != null && frmInstancial.frmIHM.IsHandleCreated)
|
||||
{
|
||||
frmInstancial.frmIHM.lblStatus.Text = msg;
|
||||
}
|
||||
}));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Opcional: armazenar a mensagem e aplicar depois
|
||||
Console.WriteLine("frmPrincipal ainda não está pronto para receber Invoke.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -142,12 +142,12 @@
|
|||
{
|
||||
"id": 13,
|
||||
"Diretorio": "Python\\Scripts\\",
|
||||
"Arquivo": "street_detector",
|
||||
"Arquivo": "street_detector_oak",
|
||||
"Extensao": ".py",
|
||||
"Versao": "1_0",
|
||||
"ArquivoDownload": "street_detector-1_0.py",
|
||||
"NomeArquivoLocal": "street_detector-1_0.py",
|
||||
"CaminhoCompleto": "Python\\Scripts\\street_detector-1_0.py",
|
||||
"ArquivoDownload": "street_detector_oak-1_0.py",
|
||||
"NomeArquivoLocal": "street_detector_oak-1_0.py",
|
||||
"CaminhoCompleto": "Python\\Scripts\\street_detector_oak-1_0.py",
|
||||
"Atualizado": true,
|
||||
"ArquivoAtualizado": true,
|
||||
"TipoArquivo": 8
|
||||
|
|
|
|||
|
|
@ -1,221 +1 @@
|
|||
{
|
||||
"type": "FeatureCollection",
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"Id": "1",
|
||||
"Name": "CidadeJardimTerreno2",
|
||||
"Length": 14.558011415731592,
|
||||
"Dist1": 14.558011415731592,
|
||||
"Dist2": 0.0
|
||||
},
|
||||
"geometry": {
|
||||
"id": null,
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-47.395205344,
|
||||
-22.172559531333334
|
||||
],
|
||||
[
|
||||
-47.395212610166666,
|
||||
-22.172614638833334
|
||||
],
|
||||
[
|
||||
-47.395219157,
|
||||
-22.172656417833334
|
||||
],
|
||||
[
|
||||
-47.395223544833335,
|
||||
-22.1726892105
|
||||
],
|
||||
[
|
||||
-47.39522414098443,
|
||||
-22.17269369161165
|
||||
],
|
||||
[
|
||||
-47.395225326538004,
|
||||
-22.172702654611555
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"Id": "2",
|
||||
"Name": "CidadeJardimTerreno2",
|
||||
"Length": 14.771318274761821,
|
||||
"Dist1": 14.558011415731592,
|
||||
"Dist2": 0.0
|
||||
},
|
||||
"geometry": {
|
||||
"id": null,
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-47.39521090233333,
|
||||
-22.172708800833334
|
||||
],
|
||||
[
|
||||
-47.395206943666665,
|
||||
-22.172679811
|
||||
],
|
||||
[
|
||||
-47.395202420666664,
|
||||
-22.1726491015
|
||||
],
|
||||
[
|
||||
-47.395198865666664,
|
||||
-22.172615782833333
|
||||
],
|
||||
[
|
||||
-47.395193255833334,
|
||||
-22.172577132833332
|
||||
],
|
||||
[
|
||||
-47.395192610024395,
|
||||
-22.17257265769541
|
||||
],
|
||||
[
|
||||
-47.395191325698136,
|
||||
-22.172563706509337
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"Id": "3",
|
||||
"Name": "CidadeJardimTerreno2",
|
||||
"Length": 14.827915524386164,
|
||||
"Dist1": 14.558011415731592,
|
||||
"Dist2": 0.0
|
||||
},
|
||||
"geometry": {
|
||||
"id": null,
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-47.3951762925,
|
||||
-22.172561603
|
||||
],
|
||||
[
|
||||
-47.395180824166665,
|
||||
-22.172591686166665
|
||||
],
|
||||
[
|
||||
-47.395185745333336,
|
||||
-22.172623080166666
|
||||
],
|
||||
[
|
||||
-47.395190433,
|
||||
-22.172656367166667
|
||||
],
|
||||
[
|
||||
-47.395195199,
|
||||
-22.172693641833334
|
||||
],
|
||||
[
|
||||
-47.39519576904436,
|
||||
-22.172698125891035
|
||||
],
|
||||
[
|
||||
-47.39519690267159,
|
||||
-22.172707094716973
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"Id": "4",
|
||||
"Name": "CidadeJardimTerreno2",
|
||||
"Length": 14.785159385903514,
|
||||
"Dist1": 14.558011415731592,
|
||||
"Dist2": 0.0
|
||||
},
|
||||
"geometry": {
|
||||
"id": null,
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-47.39518293216667,
|
||||
-22.1727127985
|
||||
],
|
||||
[
|
||||
-47.39517819266667,
|
||||
-22.172680514833335
|
||||
],
|
||||
[
|
||||
-47.3951732595,
|
||||
-22.172646752833334
|
||||
],
|
||||
[
|
||||
-47.39516880516667,
|
||||
-22.1726149155
|
||||
],
|
||||
[
|
||||
-47.39516381233334,
|
||||
-22.172581167166665
|
||||
],
|
||||
[
|
||||
-47.39516315429932,
|
||||
-22.172576693573966
|
||||
],
|
||||
[
|
||||
-47.39516184565584,
|
||||
-22.172567745443878
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"Id": "5",
|
||||
"Name": "CidadeJardimTerreno2",
|
||||
"Length": 14.80117692191233,
|
||||
"Dist1": 14.558011415731592,
|
||||
"Dist2": 0.0
|
||||
},
|
||||
"geometry": {
|
||||
"id": null,
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-47.395147317833334,
|
||||
-22.172566031
|
||||
],
|
||||
[
|
||||
-47.395151503166666,
|
||||
-22.172595452333333
|
||||
],
|
||||
[
|
||||
-47.3951561855,
|
||||
-22.172628011166665
|
||||
],
|
||||
[
|
||||
-47.39516159866667,
|
||||
-22.172663757333332
|
||||
],
|
||||
[
|
||||
-47.39516672716667,
|
||||
-22.172697770833334
|
||||
],
|
||||
[
|
||||
-47.395167397572706,
|
||||
-22.172702242832194
|
||||
],
|
||||
[
|
||||
-47.39516873082615,
|
||||
-22.17271118781009
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"Id":"1","Name":"02_04_2025_17_20_50","Length":0.0,"Dist1":0.0,"Dist2":0.0},"geometry":{"id":null,"type":"LineString","coordinates":[[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0]]}}]}
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
<meta name="viewport" content="width=device-width,
|
||||
initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<style>
|
||||
#map_c17ce78bff49a7401eff2508c6dcc0c3 {
|
||||
#map_084fd12da6e91f44659dd95dda10e013 {
|
||||
position: relative;
|
||||
width: 100.0%;
|
||||
height: 100.0%;
|
||||
|
|
@ -39,14 +39,14 @@
|
|||
<body>
|
||||
|
||||
|
||||
<div class="folium-map" id="map_c17ce78bff49a7401eff2508c6dcc0c3" ></div>
|
||||
<div class="folium-map" id="map_084fd12da6e91f44659dd95dda10e013" ></div>
|
||||
|
||||
</body>
|
||||
<script>
|
||||
|
||||
|
||||
var map_c17ce78bff49a7401eff2508c6dcc0c3 = L.map(
|
||||
"map_c17ce78bff49a7401eff2508c6dcc0c3",
|
||||
var map_084fd12da6e91f44659dd95dda10e013 = L.map(
|
||||
"map_084fd12da6e91f44659dd95dda10e013",
|
||||
{
|
||||
center: [0.0, 0.0],
|
||||
crs: L.CRS.EPSG3857,
|
||||
|
|
@ -60,13 +60,13 @@
|
|||
|
||||
|
||||
|
||||
var tile_layer_b68aee685770afdb7f454cf948fb9b33 = L.tileLayer(
|
||||
var tile_layer_67f4a27d47a2b4494d6ed3f07cc58c1c = L.tileLayer(
|
||||
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
|
||||
{"attribution": "\u0026copy; \u003ca href=\"https://www.openstreetmap.org/copyright\"\u003eOpenStreetMap\u003c/a\u003e contributors", "detectRetina": false, "maxNativeZoom": 19, "maxZoom": 19, "minZoom": 0, "noWrap": false, "opacity": 1, "subdomains": "abc", "tms": false}
|
||||
);
|
||||
|
||||
|
||||
tile_layer_b68aee685770afdb7f454cf948fb9b33.addTo(map_c17ce78bff49a7401eff2508c6dcc0c3);
|
||||
tile_layer_67f4a27d47a2b4494d6ed3f07cc58c1c.addTo(map_084fd12da6e91f44659dd95dda10e013);
|
||||
|
||||
</script>
|
||||
|
||||
|
|
@ -87,7 +87,7 @@
|
|||
}
|
||||
trajeto_json_add({"features": []});
|
||||
|
||||
trajeto_json.addTo(map_c17ce78bff49a7401eff2508c6dcc0c3);
|
||||
trajeto_json.addTo(map_084fd12da6e91f44659dd95dda10e013);
|
||||
|
||||
function adicionarGeometria(novaGeometria) {
|
||||
trajeto_json.addData(novaGeometria);
|
||||
|
|
@ -145,7 +145,7 @@
|
|||
|
||||
var marcadorDinamico = L.marker([0, 0], {
|
||||
icon: customIcon
|
||||
}).addTo(map_c17ce78bff49a7401eff2508c6dcc0c3);
|
||||
}).addTo(map_084fd12da6e91f44659dd95dda10e013);
|
||||
|
||||
// Conectar ao broker MQTT
|
||||
const client = mqtt.connect('ws://localhost:9001'); // Use wss para conexão segura
|
||||
|
|
@ -183,7 +183,7 @@
|
|||
marcadorDinamico.setRotationAngle(angulo);
|
||||
|
||||
adicionarCoordenada("Tj", [novaLongitude, novaLatitude]);
|
||||
map_c17ce78bff49a7401eff2508c6dcc0c3.setView(novaPosicao, map_c17ce78bff49a7401eff2508c6dcc0c3.getZoom());
|
||||
map_084fd12da6e91f44659dd95dda10e013.setView(novaPosicao, map_084fd12da6e91f44659dd95dda10e013.getZoom());
|
||||
});
|
||||
|
||||
function calcularOrientacao(P1latitude, P1longitude, P2latitude, P2longitude) {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
<meta name="viewport" content="width=device-width,
|
||||
initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<style>
|
||||
#map_68dcaf9dd7545b82e750e9f498ab7095 {
|
||||
#map_6db772d0d8d14e2d02efe2b399e87581 {
|
||||
position: relative;
|
||||
width: 100.0%;
|
||||
height: 100.0%;
|
||||
|
|
@ -39,16 +39,16 @@
|
|||
<body>
|
||||
|
||||
|
||||
<div class="folium-map" id="map_68dcaf9dd7545b82e750e9f498ab7095" ></div>
|
||||
<div class="folium-map" id="map_6db772d0d8d14e2d02efe2b399e87581" ></div>
|
||||
|
||||
</body>
|
||||
<script>
|
||||
|
||||
|
||||
var map_68dcaf9dd7545b82e750e9f498ab7095 = L.map(
|
||||
"map_68dcaf9dd7545b82e750e9f498ab7095",
|
||||
var map_6db772d0d8d14e2d02efe2b399e87581 = L.map(
|
||||
"map_6db772d0d8d14e2d02efe2b399e87581",
|
||||
{
|
||||
center: [-22.172636164916668, -47.395186322185666],
|
||||
center: [0.0, 0.0],
|
||||
crs: L.CRS.EPSG3857,
|
||||
zoom: 12,
|
||||
zoomControl: true,
|
||||
|
|
@ -60,13 +60,13 @@
|
|||
|
||||
|
||||
|
||||
var tile_layer_18ed5e620d2365ae2eea37d711c8da92 = L.tileLayer(
|
||||
var tile_layer_53d89bd6580a52ed08e8b535dbe73fc5 = L.tileLayer(
|
||||
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
|
||||
{"attribution": "\u0026copy; \u003ca href=\"https://www.openstreetmap.org/copyright\"\u003eOpenStreetMap\u003c/a\u003e contributors", "detectRetina": false, "maxNativeZoom": 19, "maxZoom": 19, "minZoom": 0, "noWrap": false, "opacity": 1, "subdomains": "abc", "tms": false}
|
||||
);
|
||||
|
||||
|
||||
tile_layer_18ed5e620d2365ae2eea37d711c8da92.addTo(map_68dcaf9dd7545b82e750e9f498ab7095);
|
||||
tile_layer_53d89bd6580a52ed08e8b535dbe73fc5.addTo(map_6db772d0d8d14e2d02efe2b399e87581);
|
||||
|
||||
|
||||
|
||||
|
|
@ -82,7 +82,7 @@
|
|||
}*/
|
||||
});
|
||||
}
|
||||
function geo_json_377712b0416695b2616e159ce6022a2d_onEachFeature(feature, layer) {
|
||||
function geo_json_3dd7e60984a746b98c90d1ccb69ef337_onEachFeature(feature, layer) {
|
||||
layer.on({
|
||||
|
||||
click: function(e) {
|
||||
|
|
@ -118,20 +118,20 @@
|
|||
}*/
|
||||
});
|
||||
};
|
||||
var geo_json_377712b0416695b2616e159ce6022a2d = L.geoJson(null, {
|
||||
onEachFeature: geo_json_377712b0416695b2616e159ce6022a2d_onEachFeature,
|
||||
var geo_json_3dd7e60984a746b98c90d1ccb69ef337 = L.geoJson(null, {
|
||||
onEachFeature: geo_json_3dd7e60984a746b98c90d1ccb69ef337_onEachFeature,
|
||||
|
||||
});
|
||||
|
||||
function geo_json_377712b0416695b2616e159ce6022a2d_add (data) {
|
||||
geo_json_377712b0416695b2616e159ce6022a2d
|
||||
function geo_json_3dd7e60984a746b98c90d1ccb69ef337_add (data) {
|
||||
geo_json_3dd7e60984a746b98c90d1ccb69ef337
|
||||
.addData(data);
|
||||
}
|
||||
geo_json_377712b0416695b2616e159ce6022a2d_add({"features": [{"geometry": {"coordinates": [[-47.395205344, -22.172559531333334], [-47.395212610166666, -22.172614638833334], [-47.395219157, -22.172656417833334], [-47.395223544833335, -22.1726892105], [-47.39522414098443, -22.17269369161165], [-47.395225326538004, -22.172702654611555]], "id": null, "type": "LineString"}, "id": 0, "properties": {"Dist1": 14.558011415731592, "Dist2": 0.0, "Id": "1", "Length": 14.558011415731592, "Name": "CidadeJardimTerreno2"}, "type": "Feature"}, {"geometry": {"coordinates": [[-47.39521090233333, -22.172708800833334], [-47.395206943666665, -22.172679811], [-47.395202420666664, -22.1726491015], [-47.395198865666664, -22.172615782833333], [-47.395193255833334, -22.172577132833332], [-47.395192610024395, -22.17257265769541], [-47.395191325698136, -22.172563706509337]], "id": null, "type": "LineString"}, "id": 1, "properties": {"Dist1": 14.558011415731592, "Dist2": 0.0, "Id": "2", "Length": 14.771318274761821, "Name": "CidadeJardimTerreno2"}, "type": "Feature"}, {"geometry": {"coordinates": [[-47.3951762925, -22.172561603], [-47.395180824166665, -22.172591686166665], [-47.395185745333336, -22.172623080166666], [-47.395190433, -22.172656367166667], [-47.395195199, -22.172693641833334], [-47.39519576904436, -22.172698125891035], [-47.39519690267159, -22.172707094716973]], "id": null, "type": "LineString"}, "id": 2, "properties": {"Dist1": 14.558011415731592, "Dist2": 0.0, "Id": "3", "Length": 14.827915524386164, "Name": "CidadeJardimTerreno2"}, "type": "Feature"}, {"geometry": {"coordinates": [[-47.39518293216667, -22.1727127985], [-47.39517819266667, -22.172680514833335], [-47.3951732595, -22.172646752833334], [-47.39516880516667, -22.1726149155], [-47.39516381233334, -22.172581167166665], [-47.39516315429932, -22.172576693573966], [-47.39516184565584, -22.172567745443878]], "id": null, "type": "LineString"}, "id": 3, "properties": {"Dist1": 14.558011415731592, "Dist2": 0.0, "Id": "4", "Length": 14.785159385903514, "Name": "CidadeJardimTerreno2"}, "type": "Feature"}, {"geometry": {"coordinates": [[-47.395147317833334, -22.172566031], [-47.395151503166666, -22.172595452333333], [-47.3951561855, -22.172628011166665], [-47.39516159866667, -22.172663757333332], [-47.39516672716667, -22.172697770833334], [-47.395167397572706, -22.172702242832194], [-47.39516873082615, -22.17271118781009]], "id": null, "type": "LineString"}, "id": 4, "properties": {"Dist1": 14.558011415731592, "Dist2": 0.0, "Id": "5", "Length": 14.80117692191233, "Name": "CidadeJardimTerreno2"}, "type": "Feature"}], "type": "FeatureCollection"});
|
||||
geo_json_3dd7e60984a746b98c90d1ccb69ef337_add({"features": [{"geometry": {"coordinates": [[0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0]], "id": null, "type": "LineString"}, "id": 0, "properties": {"Dist1": 0.0, "Dist2": 0.0, "Id": "1", "Length": 0.0, "Name": "02_04_2025_17_20_50"}, "type": "Feature"}], "type": "FeatureCollection"});
|
||||
|
||||
|
||||
|
||||
geo_json_377712b0416695b2616e159ce6022a2d.addTo(map_68dcaf9dd7545b82e750e9f498ab7095);
|
||||
geo_json_3dd7e60984a746b98c90d1ccb69ef337.addTo(map_6db772d0d8d14e2d02efe2b399e87581);
|
||||
|
||||
</script>
|
||||
|
||||
|
|
@ -152,7 +152,7 @@
|
|||
}
|
||||
trajeto_json_add({"features": []});
|
||||
|
||||
trajeto_json.addTo(map_68dcaf9dd7545b82e750e9f498ab7095);
|
||||
trajeto_json.addTo(map_6db772d0d8d14e2d02efe2b399e87581);
|
||||
|
||||
function adicionarGeometria(novaGeometria) {
|
||||
trajeto_json.addData(novaGeometria);
|
||||
|
|
@ -210,7 +210,7 @@
|
|||
}
|
||||
trajeto_dinamico_json_add({"features": []});
|
||||
|
||||
trajeto_dinamico_json.addTo(map_68dcaf9dd7545b82e750e9f498ab7095);
|
||||
trajeto_dinamico_json.addTo(map_6db772d0d8d14e2d02efe2b399e87581);
|
||||
|
||||
function adicionarGeometriaDinamica(novaGeometria) {
|
||||
trajeto_dinamico_json.addData(novaGeometria);
|
||||
|
|
@ -263,9 +263,9 @@
|
|||
|
||||
var marcadorEquipamento = L.marker([0, 0], {
|
||||
icon: customIcon
|
||||
}).addTo(map_68dcaf9dd7545b82e750e9f498ab7095);
|
||||
}).addTo(map_6db772d0d8d14e2d02efe2b399e87581);
|
||||
|
||||
var marcadorBase = L.marker([0, 0], {}).addTo(map_68dcaf9dd7545b82e750e9f498ab7095);
|
||||
var marcadorBase = L.marker([0, 0], {}).addTo(map_6db772d0d8d14e2d02efe2b399e87581);
|
||||
var icon = L.AwesomeMarkers.icon(
|
||||
{"extraClasses": "fa-rotate-0", "icon": "info-sign", "iconColor": "white", "markerColor": "red", "prefix": "glyphicon"}
|
||||
);
|
||||
|
|
@ -347,7 +347,7 @@
|
|||
}
|
||||
|
||||
if (foco) {
|
||||
map_68dcaf9dd7545b82e750e9f498ab7095.setView(novaPosicao, map_68dcaf9dd7545b82e750e9f498ab7095.getZoom());
|
||||
map_6db772d0d8d14e2d02efe2b399e87581.setView(novaPosicao, map_6db772d0d8d14e2d02efe2b399e87581.getZoom());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -364,7 +364,7 @@
|
|||
function atualizarSelecaoRuas(selecionadas) {
|
||||
selecionadas = JSON.parse(selecionadas);
|
||||
RuasSelecionadas = Array.isArray(selecionadas) ? [...selecionadas] : [];
|
||||
geo_json_377712b0416695b2616e159ce6022a2d.eachLayer(function (layer) {
|
||||
geo_json_3dd7e60984a746b98c90d1ccb69ef337.eachLayer(function (layer) {
|
||||
if (RuasSelecionadas.includes(parseInt(layer.feature.id))) {
|
||||
layer.setStyle({ color: 'blue' });
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import sys
|
|||
import threading
|
||||
import paho.mqtt.client as mqtt
|
||||
import uuid
|
||||
from flask import Flask, Response, request
|
||||
from flask import Flask, Response
|
||||
|
||||
# 🔹 Configurações MQTT
|
||||
mqtt_client = mqtt.Client(f"client_oak_d_lite_{uuid.uuid4()}")
|
||||
|
|
@ -15,57 +15,149 @@ mqtt_client.connect("localhost", port=1883)
|
|||
|
||||
# 🔹 Parâmetros de entrada
|
||||
output_folder = 'Python/Output/'
|
||||
mqtt_topic = sys.argv[1] # Tópico MQTT para envio dos dados de profundidade
|
||||
mqtt_topic = sys.argv[1] # Tópico MQTT para envio dos dados
|
||||
porta = int(sys.argv[2]) # Porta do Flask
|
||||
url = sys.argv[3] # URL do vídeo
|
||||
max_readings = int(sys.argv[4])
|
||||
url_rgb = sys.argv[3] # URL do vídeo RGB
|
||||
url_heatmap = sys.argv[4] # URL do vídeo do Heatmap
|
||||
max_readings = int(sys.argv[5])
|
||||
camera_index = int(sys.argv[6])
|
||||
|
||||
# 🔹 Flask App
|
||||
app = Flask(__name__)
|
||||
|
||||
# 🔹 Criando o pipeline
|
||||
# Função para calcular a moda de um array unidimensional
|
||||
def calc_mode(values):
|
||||
# Arredonda os valores para eliminar pequenas variações
|
||||
rounded = np.round(values, 0)
|
||||
vals, counts = np.unique(rounded, return_counts=True)
|
||||
return vals[np.argmax(counts)]
|
||||
|
||||
# Configuração de filtros
|
||||
NUM_FRAMES_SMOOTH = 5 # Número de frames para suavização temporal
|
||||
SMOOTH_KERNEL = (5, 5) # Tamanho do kernel para suavização espacial
|
||||
OUTLIER_THRESHOLD = 50 # Limiar para remoção de outliers
|
||||
|
||||
depth_buffer = [] # Buffer para armazenar os últimos frames de profundidade
|
||||
|
||||
# Suavização Temporal
|
||||
def smooth_depth(depth_frame):
|
||||
global depth_buffer
|
||||
if len(depth_buffer) >= NUM_FRAMES_SMOOTH:
|
||||
depth_buffer.pop(0) # Remove o frame mais antigo
|
||||
depth_buffer.append(depth_frame) # Adiciona o novo frame
|
||||
return np.mean(depth_buffer, axis=0).astype(np.uint16) # Retorna a média
|
||||
|
||||
# Suavização Espacial (Filtro Gaussiano)
|
||||
def gaussian_smooth(depth_frame):
|
||||
return cv2.GaussianBlur(depth_frame, SMOOTH_KERNEL, 0)
|
||||
|
||||
# Filtro de Mediana para Remover Ruídos
|
||||
def median_filter(depth_frame):
|
||||
return cv2.medianBlur(depth_frame, 5)
|
||||
|
||||
# Remover Outliers (Saltos Extremos)
|
||||
def remove_outliers(depth_frame):
|
||||
depth_median = cv2.medianBlur(depth_frame, 5)
|
||||
diff = np.abs(depth_frame - depth_median)
|
||||
depth_frame[diff > OUTLIER_THRESHOLD] = depth_median[diff > OUTLIER_THRESHOLD]
|
||||
return depth_frame
|
||||
|
||||
# Aplicar filtros no depthFrame
|
||||
def apply_depth_filters(depth_frame):
|
||||
if filtro1:
|
||||
depth_frame = smooth_depth(depth_frame) # 1. Suavização Temporal
|
||||
if filtro2:
|
||||
depth_frame = gaussian_smooth(depth_frame) # 2. Suavização Espacial
|
||||
if filtro3:
|
||||
depth_frame = median_filter(depth_frame) # 3. Filtro de Mediana
|
||||
if filtro4:
|
||||
depth_frame = remove_outliers(depth_frame) # 4. Remoção de Outliers
|
||||
return depth_frame
|
||||
|
||||
# Função para gerar o mapa de calor da profundidade
|
||||
def generate_heatmap(depth_frame):
|
||||
normalized_depth = cv2.normalize(depth_frame, None, 0, 255, cv2.NORM_MINMAX)
|
||||
heatmap = cv2.applyColorMap(normalized_depth.astype(np.uint8), cv2.COLORMAP_JET)
|
||||
return heatmap
|
||||
|
||||
|
||||
|
||||
# ───────────────────────────────────────────────
|
||||
# Configurações da câmera e das matrizes
|
||||
# ───────────────────────────────────────────────
|
||||
RGB_WIDTH, RGB_HEIGHT = 640, 480
|
||||
WIDTH, HEIGHT = 320, 240
|
||||
|
||||
# Região do solo (grid A - parte inferior): ocupa 50% da altura da imagem
|
||||
GROUND_ROWS = 10 # Número de linhas da matriz do solo
|
||||
GROUND_CELLS = 10 # Número de células por linha
|
||||
GROUND_REGION_HEIGHT = int(HEIGHT * 0.5) # 50% da altura da imagem
|
||||
GROUND_TOP_SCALE = 0.5 # A linha mais distante (superior da região) terá 35% da largura total
|
||||
DEPTH_LIMIT = 50 # (Valor de referência para comparação, mas agora usamos calibração)
|
||||
|
||||
# Região aérea (parte superior): ocupa o restante da imagem
|
||||
AIR_ROWS = 10 # Número de linhas na matriz aérea
|
||||
AIR_COLS = 15 # Número de colunas na matriz aérea
|
||||
AIR_REGION_HEIGHT = HEIGHT - GROUND_REGION_HEIGHT # Altura da região aérea
|
||||
|
||||
# ───────────────────────────────────────────────
|
||||
# Parâmetros para calibração e detecção com moda
|
||||
# ───────────────────────────────────────────────
|
||||
NUM_CALIB_FRAMES = 100 # Número de frames para calibração
|
||||
NUM_DETECT_FRAMES = 10 # Número de frames para acumulação antes de calcular a moda na detecção
|
||||
|
||||
# Variável global para armazenar o frame de profundidade atual (para uso no callback)
|
||||
current_depth_frame = None
|
||||
|
||||
show_grid = False
|
||||
filtro1 = True
|
||||
filtro2 = True
|
||||
filtro3 = True
|
||||
filtro4 = True
|
||||
|
||||
# ───────────────────────────────────────────────
|
||||
# Criação do pipeline DepthAI
|
||||
# ───────────────────────────────────────────────
|
||||
pipeline = dai.Pipeline()
|
||||
|
||||
width, height = 1280, 720
|
||||
|
||||
# 📷 Câmera RGB
|
||||
# Nó da câmera RGB
|
||||
cam_rgb = pipeline.create(dai.node.ColorCamera)
|
||||
cam_rgb.setPreviewSize(width, height)
|
||||
cam_rgb.setPreviewSize(RGB_WIDTH, RGB_HEIGHT)
|
||||
cam_rgb.setBoardSocket(dai.CameraBoardSocket.RGB)
|
||||
cam_rgb.setInterleaved(False)
|
||||
|
||||
# Criar XLinkOut para saída RGB
|
||||
xout_rgb = pipeline.create(dai.node.XLinkOut)
|
||||
xout_rgb.setStreamName("rgb")
|
||||
cam_rgb.preview.link(xout_rgb.input)
|
||||
|
||||
# 🔹 Câmera de Profundidade
|
||||
# Nó de profundidade
|
||||
mono_left = pipeline.create(dai.node.MonoCamera)
|
||||
mono_right = pipeline.create(dai.node.MonoCamera)
|
||||
stereo = pipeline.create(dai.node.StereoDepth)
|
||||
|
||||
mono_left.setResolution(dai.MonoCameraProperties.SensorResolution.THE_400_P)
|
||||
mono_right.setResolution(dai.MonoCameraProperties.SensorResolution.THE_400_P)
|
||||
|
||||
mono_left.setResolution(dai.MonoCameraProperties.SensorResolution.THE_480_P)
|
||||
mono_right.setResolution(dai.MonoCameraProperties.SensorResolution.THE_480_P)
|
||||
mono_left.setBoardSocket(dai.CameraBoardSocket.LEFT)
|
||||
mono_right.setBoardSocket(dai.CameraBoardSocket.RIGHT)
|
||||
|
||||
# Configuração do StereoDepth
|
||||
stereo.setDefaultProfilePreset(dai.node.StereoDepth.PresetMode.HIGH_DENSITY)
|
||||
stereo.setLeftRightCheck(True)
|
||||
stereo.setSubpixel(True)
|
||||
stereo = pipeline.create(dai.node.StereoDepth)
|
||||
stereo.setDefaultProfilePreset(dai.node.StereoDepth.PresetMode.ROBOTICS)
|
||||
#stereo.initialConfig.setConfidenceThreshold(250) # Remove ruído, mantendo apenas pontos confiáveis
|
||||
#stereo.initialConfig.setMedianFilter(dai.MedianFilter.KERNEL_7x7) # Usa filtro de mediana forte
|
||||
#stereo.setLeftRightCheck(True) # Ativa verificação para evitar erros
|
||||
#stereo.setExtendedDisparity(False) # Reduz ruído em distâncias curtas
|
||||
#stereo.setSubpixel(True) # Aumenta a precisão da profundidade
|
||||
|
||||
mono_left.out.link(stereo.left)
|
||||
mono_right.out.link(stereo.right)
|
||||
|
||||
# Criar XLinkOut para profundidade
|
||||
xout_depth = pipeline.create(dai.node.XLinkOut)
|
||||
xout_depth.setStreamName("depth")
|
||||
stereo.depth.link(xout_depth.input)
|
||||
|
||||
device_global = None
|
||||
selected_device_info = None
|
||||
camera_iniciada = False
|
||||
|
||||
def initialize_device():
|
||||
global device_global, selected_device_info, camera_iniciada
|
||||
|
||||
# 🔹 Função para enviar vídeo via Flask
|
||||
def generate_video(camera_index):
|
||||
# Listar todas as câmeras conectadas
|
||||
devices = dai.Device.getAllAvailableDevices()
|
||||
|
||||
|
|
@ -80,101 +172,436 @@ def generate_video(camera_index):
|
|||
selected_device_info = devices[camera_index] # Seleciona a câmera correta pelo índice
|
||||
print(f"Usando câmera: {selected_device_info.name} (ID: {selected_device_info.mxid})")
|
||||
|
||||
with dai.Device(pipeline, selected_device_info) as device: # 🔹 Agora usa a câmera correta
|
||||
rgb_queue = device.getOutputQueue(name="rgb", maxSize=4, blocking=False)
|
||||
depth_queue = device.getOutputQueue(name="depth", maxSize=4, blocking=False)
|
||||
device_global = dai.Device(pipeline, selected_device_info)
|
||||
camera_iniciada = True
|
||||
|
||||
readings = []
|
||||
# 🔹 Função para enviar vídeo via Flask
|
||||
def process_depth_data():
|
||||
|
||||
while True:
|
||||
frame_data = rgb_queue.get()
|
||||
if frame_data is None:
|
||||
continue
|
||||
if camera_iniciada == False:
|
||||
initialize_device()
|
||||
|
||||
global device_global, selected_device_info
|
||||
|
||||
timestamp = time.time()
|
||||
depth_queue = device_global.getOutputQueue(name="depth", maxSize=1, blocking=False)
|
||||
|
||||
# 📏 Captura Profundidade
|
||||
# Função para calibrar a região do solo utilizando a moda
|
||||
def calibrate_ground():
|
||||
print("Calibrando região do solo: coletando {} frames...".format(NUM_CALIB_FRAMES))
|
||||
calib_data = np.zeros((GROUND_ROWS, GROUND_CELLS, NUM_CALIB_FRAMES))
|
||||
for frame_idx in range(NUM_CALIB_FRAMES):
|
||||
depth_frame = depth_queue.get().getFrame()
|
||||
depth_frame = apply_depth_filters(depth_frame)
|
||||
for i in range(GROUND_ROWS):
|
||||
y_start = HEIGHT - GROUND_REGION_HEIGHT + i * row_height_ground
|
||||
y_end = y_start + row_height_ground
|
||||
scale = GROUND_TOP_SCALE + (i / (GROUND_ROWS - 1)) * (1 - GROUND_TOP_SCALE) if GROUND_ROWS > 1 else 1
|
||||
effective_width = int(WIDTH * scale)
|
||||
cell_width = effective_width / GROUND_CELLS
|
||||
for j in range(GROUND_CELLS):
|
||||
x_start = int(WIDTH / 2 - effective_width / 2 + j * cell_width)
|
||||
x_end = int(x_start + cell_width)
|
||||
calib_data[i, j, frame_idx] = np.mean(depth_frame[y_start:y_end, x_start:x_end])
|
||||
ground_ref = np.zeros((GROUND_ROWS, GROUND_CELLS))
|
||||
for i in range(GROUND_ROWS):
|
||||
for j in range(GROUND_CELLS):
|
||||
ground_ref[i, j] = calc_mode(calib_data[i, j, :])
|
||||
print("Calibração da região do solo concluída!")
|
||||
return ground_ref
|
||||
|
||||
# Normaliza a profundidade para visualização (mapa de calor)
|
||||
depth_visual = cv2.normalize(depth_frame, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U)
|
||||
depth_visual = cv2.applyColorMap(depth_visual, cv2.COLORMAP_JET)
|
||||
# Função para calibrar a região aérea utilizando a moda
|
||||
def calibrate_air():
|
||||
print("Calibrando região aérea: coletando {} frames...".format(NUM_CALIB_FRAMES))
|
||||
calib_data_air = np.zeros((AIR_ROWS, AIR_COLS, NUM_CALIB_FRAMES))
|
||||
row_height_air = AIR_REGION_HEIGHT // AIR_ROWS
|
||||
cell_width_air = WIDTH // AIR_COLS
|
||||
for frame_idx in range(NUM_CALIB_FRAMES):
|
||||
depth_frame = depth_queue.get().getFrame()
|
||||
depth_frame = apply_depth_filters(depth_frame)
|
||||
for i in range(AIR_ROWS):
|
||||
y_start = i * row_height_air
|
||||
y_end = y_start + row_height_air
|
||||
for j in range(AIR_COLS):
|
||||
x_start = j * cell_width_air
|
||||
x_end = x_start + cell_width_air
|
||||
calib_data_air[i, j, frame_idx] = np.mean(depth_frame[y_start:y_end, x_start:x_end])
|
||||
air_ref = np.zeros((AIR_ROWS, AIR_COLS))
|
||||
for i in range(AIR_ROWS):
|
||||
for j in range(AIR_COLS):
|
||||
air_ref[i, j] = calc_mode(calib_data_air[i, j, :])
|
||||
print("Calibração da região aérea concluída!")
|
||||
return air_ref
|
||||
|
||||
# 📡 Enviar dados via MQTT (Apenas a matriz de profundidade reduzida)
|
||||
depth_data = depth_frame.tolist() # Converte a matriz para lista JSON
|
||||
# Função para calibrar a distância utilizando a moda
|
||||
def calibrate_distance(alvo=2500):
|
||||
global GROUND_REGION_HEIGHT, AIR_REGION_HEIGHT # Garantir que estamos alterando as variáveis globais
|
||||
|
||||
NUM_LINHAS_ANALISE = 80 # Número de linhas horizontais para análise
|
||||
ALTURA_LINHA = HEIGHT // NUM_LINHAS_ANALISE # Altura de cada linha
|
||||
PROFUNDIDADE_ALVO = alvo # Profundidade alvo em cm para definir a região do solo dinamicamente
|
||||
|
||||
media_profundidade_acumulada = np.zeros((NUM_LINHAS_ANALISE, NUM_CALIB_FRAMES))
|
||||
|
||||
print("Calibrando profundidade média com {} frames...".format(NUM_CALIB_FRAMES))
|
||||
|
||||
for frame_idx in range(NUM_CALIB_FRAMES):
|
||||
depth_frame = depth_queue.get().getFrame()
|
||||
depth_frame = apply_depth_filters(depth_frame)
|
||||
|
||||
for i in range(NUM_LINHAS_ANALISE):
|
||||
y_start = HEIGHT - (i + 1) * ALTURA_LINHA
|
||||
y_end = y_start + ALTURA_LINHA
|
||||
x_start_crop = int(WIDTH * 0.0)
|
||||
x_end_crop = int(WIDTH * 1.0)
|
||||
region_values = depth_frame[y_start:y_end, x_start_crop:x_end_crop].flatten()
|
||||
valid_values = region_values[(region_values > 0) & (region_values < 10000)]
|
||||
if valid_values.size > 0:
|
||||
media_profundidade_acumulada[i, frame_idx] = np.mean(valid_values)
|
||||
else:
|
||||
media_profundidade_acumulada[i, frame_idx] = 9999
|
||||
|
||||
media_profundidade = np.array([calc_mode(media_profundidade_acumulada[i, :]) for i in range(NUM_LINHAS_ANALISE)])
|
||||
#print("Médias de profundidade por linha (usando moda):", media_profundidade)
|
||||
|
||||
erro_minimo = float('inf')
|
||||
linha_alvo = None
|
||||
for i in range(NUM_LINHAS_ANALISE):
|
||||
erro = abs(media_profundidade[i] - PROFUNDIDADE_ALVO)
|
||||
if erro < erro_minimo:
|
||||
erro_minimo = erro
|
||||
linha_alvo = i
|
||||
|
||||
if linha_alvo is not None:
|
||||
linha_alvo += 1
|
||||
GROUND_REGION_HEIGHT = HEIGHT - ((NUM_LINHAS_ANALISE - linha_alvo) * ALTURA_LINHA)
|
||||
else:
|
||||
GROUND_REGION_HEIGHT = HEIGHT // 2
|
||||
|
||||
AIR_REGION_HEIGHT = HEIGHT - GROUND_REGION_HEIGHT
|
||||
v = GROUND_REGION_HEIGHT // GROUND_ROWS
|
||||
|
||||
print("Novo GROUND_REGION_HEIGHT:", GROUND_REGION_HEIGHT)
|
||||
print("Novo AIR_REGION_HEIGHT:", AIR_REGION_HEIGHT)
|
||||
print("Novo tamanho das linhas do solo:", v)
|
||||
|
||||
return v
|
||||
|
||||
# Gerar json dos dados das subdivisoes
|
||||
def gerar_json_subdivisoes():
|
||||
data = {
|
||||
"x_max": WIDTH,
|
||||
"y_max": HEIGHT,
|
||||
"subdivisoes_cima": {
|
||||
"num_linhas": AIR_ROWS,
|
||||
"num_colunas": AIR_COLS,
|
||||
"celulas": []
|
||||
},
|
||||
"subdivisoes_chao": {
|
||||
"num_linhas": GROUND_ROWS,
|
||||
"num_colunas": GROUND_CELLS,
|
||||
"celulas": []
|
||||
}
|
||||
}
|
||||
|
||||
# Subdivisões da região aérea
|
||||
row_height_air = AIR_REGION_HEIGHT // AIR_ROWS
|
||||
cell_width_air = WIDTH // AIR_COLS
|
||||
for i in range(AIR_ROWS):
|
||||
for j in range(AIR_COLS):
|
||||
x_start = j * cell_width_air
|
||||
y_start = i * row_height_air
|
||||
data["subdivisoes_cima"]["celulas"].append({
|
||||
"linha": i,
|
||||
"coluna": j,
|
||||
"x": x_start,
|
||||
"y": y_start,
|
||||
"largura": cell_width_air,
|
||||
"altura": row_height_air,
|
||||
"profundidade_media": smoothed_air[i, j],
|
||||
"profundidade_calibragem": air_reference[i, j]
|
||||
})
|
||||
|
||||
# Subdivisões da região do solo
|
||||
row_height_ground = GROUND_REGION_HEIGHT // GROUND_ROWS
|
||||
for i in range(GROUND_ROWS):
|
||||
scale = (GROUND_TOP_SCALE + (i / (GROUND_ROWS - 1)) * (1 - GROUND_TOP_SCALE)) if GROUND_ROWS > 1 else 1
|
||||
effective_width = int(WIDTH * scale)
|
||||
cell_width = effective_width / GROUND_CELLS
|
||||
y_start = HEIGHT - GROUND_REGION_HEIGHT + i * row_height_ground
|
||||
start_x = int(WIDTH / 2 - effective_width / 2)
|
||||
|
||||
try:
|
||||
memory_usage = device.getDdrMemoryUsage()
|
||||
for j in range(GROUND_CELLS):
|
||||
x_start = int(start_x + j * cell_width)
|
||||
data["subdivisoes_chao"]["celulas"].append({
|
||||
"linha": i,
|
||||
"coluna": j,
|
||||
"x": x_start,
|
||||
"y": y_start,
|
||||
"largura": int(cell_width),
|
||||
"altura": row_height_ground,
|
||||
"profundidade_media": smoothed_ground[i, j],
|
||||
"profundidade_calibragem": ground_reference[i, j]
|
||||
})
|
||||
|
||||
return data
|
||||
|
||||
# Calibração inicial
|
||||
row_height_ground = calibrate_distance()
|
||||
ground_reference = calibrate_ground()
|
||||
air_reference = calibrate_air()
|
||||
|
||||
# Preparação para a detecção usando moda (acumula dados de alguns frames)
|
||||
detect_counter = 0
|
||||
detect_data_ground = np.zeros((GROUND_ROWS, GROUND_CELLS, NUM_DETECT_FRAMES))
|
||||
detect_data_air = np.zeros((AIR_ROWS, AIR_COLS, NUM_DETECT_FRAMES))
|
||||
last_detect_ground = np.zeros((GROUND_ROWS, GROUND_CELLS))
|
||||
last_detect_air = np.zeros((AIR_ROWS, AIR_COLS))
|
||||
|
||||
# Parâmetro para o filtro de média móvel
|
||||
alpha = 0.4 # ajuste entre 0 e 1 (valores menores = mais suave)
|
||||
|
||||
# Inicialize as grids filtradas com os valores de calibração (ou com zeros, se preferir)
|
||||
smoothed_ground = ground_reference.copy()
|
||||
smoothed_air = air_reference.copy()
|
||||
|
||||
last_time = time.time()
|
||||
target_fps = 30 # Limita o FPS
|
||||
|
||||
readings = []
|
||||
|
||||
while True:
|
||||
current_time = time.time()
|
||||
if current_time - last_time < 1 / target_fps:
|
||||
time.sleep(0.01)
|
||||
continue
|
||||
last_time = current_time
|
||||
|
||||
in_depth = depth_queue.tryGet()
|
||||
if in_depth is None:
|
||||
continue
|
||||
|
||||
depth_frame = in_depth.getFrame()
|
||||
|
||||
# Aplicação dos filtros em sequência
|
||||
depth_frame = apply_depth_filters(depth_frame)
|
||||
|
||||
# Gera o mapa de calor
|
||||
heatmap = generate_heatmap(depth_frame)
|
||||
# Cria uma cópia do heatmap para desenhar o overlay
|
||||
heatmap_overlay = heatmap.copy()
|
||||
|
||||
# ─────────────────────────────────────────────
|
||||
# Atualiza a grid do SOLO (região inferior) com média móvel
|
||||
# ─────────────────────────────────────────────
|
||||
for i in range(GROUND_ROWS):
|
||||
y_start = HEIGHT - GROUND_REGION_HEIGHT + i * row_height_ground
|
||||
y_end = y_start + row_height_ground
|
||||
scale = (GROUND_TOP_SCALE +
|
||||
(i / (GROUND_ROWS - 1)) * (1 - GROUND_TOP_SCALE)) if GROUND_ROWS > 1 else 1
|
||||
effective_width = int(WIDTH * scale)
|
||||
cell_width = effective_width / GROUND_CELLS
|
||||
|
||||
for j in range(GROUND_CELLS):
|
||||
x_start = int(WIDTH / 2 - effective_width / 2 + j * cell_width)
|
||||
x_end = int(x_start + cell_width)
|
||||
|
||||
# Obtém os valores válidos da região
|
||||
region_values = depth_frame[y_start:y_end, x_start:x_end].flatten()
|
||||
valid_values = region_values[(region_values > 0) & (region_values < 10000)] # Remove valores inválidos
|
||||
|
||||
# Calcula a média da célula e atualiza as variáveis
|
||||
if valid_values.size > 0:
|
||||
measurement = np.mean(valid_values)
|
||||
else:
|
||||
measurement = 9999 # Define um valor alto se não houver dados válidos
|
||||
|
||||
# Atualiza a grid suavizada com a média móvel
|
||||
smoothed_ground[i, j] = alpha * measurement + (1 - alpha) * smoothed_ground[i, j]
|
||||
|
||||
# Atualiza a matriz last_detect_ground com a média real da célula
|
||||
last_detect_ground[i, j] = measurement
|
||||
|
||||
# ─────────────────────────────────────────────
|
||||
# Atualiza a grid da REGIÃO AÉREA (parte superior) com média móvel
|
||||
# ─────────────────────────────────────────────
|
||||
row_height_air = AIR_REGION_HEIGHT // AIR_ROWS
|
||||
cell_width_air = WIDTH // AIR_COLS
|
||||
|
||||
for i in range(AIR_ROWS):
|
||||
y_start = i * row_height_air
|
||||
y_end = y_start + row_height_air
|
||||
|
||||
for j in range(AIR_COLS):
|
||||
x_start = j * cell_width_air
|
||||
x_end = x_start + cell_width_air
|
||||
|
||||
# Obtém os valores válidos da região
|
||||
region_values = depth_frame[y_start:y_end, x_start:x_end].flatten()
|
||||
valid_values = region_values[(region_values > 0) & (region_values < 10000)] # Remove valores inválidos
|
||||
|
||||
# Calcula a média da célula e atualiza as variáveis
|
||||
if valid_values.size > 0:
|
||||
measurement = np.mean(valid_values)
|
||||
else:
|
||||
measurement = 9999 # Define um valor alto se não houver dados válidos
|
||||
|
||||
# Atualiza a grid suavizada com a média móvel
|
||||
smoothed_air[i, j] = alpha * measurement + (1 - alpha) * smoothed_air[i, j]
|
||||
|
||||
# Atualiza a matriz last_detect_air com a média real da célula
|
||||
last_detect_air[i, j] = measurement
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────
|
||||
# Processamento da detecção: Região do SOLO
|
||||
# ─────────────────────────────────────────────
|
||||
for i in range(GROUND_ROWS):
|
||||
y_start = HEIGHT - GROUND_REGION_HEIGHT + i * row_height_ground
|
||||
y_end = y_start + row_height_ground
|
||||
|
||||
scale = (GROUND_TOP_SCALE + (i / (GROUND_ROWS - 1)) * (1 - GROUND_TOP_SCALE)) if GROUND_ROWS > 1 else 1
|
||||
|
||||
effective_width = int(WIDTH * scale)
|
||||
cell_width = effective_width / GROUND_CELLS
|
||||
|
||||
for j in range(GROUND_CELLS):
|
||||
x_start = int(WIDTH / 2 - effective_width / 2 + j * cell_width)
|
||||
x_end = int(x_start + cell_width)
|
||||
# Compara o valor suavizado com a referência calibrada
|
||||
if smoothed_ground[i, j] < (ground_reference[i, j] - DEPTH_LIMIT):
|
||||
# Obstáculo (valor menor: objeto mais próximo)
|
||||
cv2.rectangle(heatmap_overlay, (x_start, y_start), (x_end, y_end), (0, 0, 255), -1)
|
||||
elif smoothed_ground[i, j] > (ground_reference[i, j] + DEPTH_LIMIT):
|
||||
# Erosão (valor maior: superfície rebaixada)
|
||||
cv2.rectangle(heatmap_overlay, (x_start, y_start), (x_end, y_end), (0, 255, 255), -1)
|
||||
if show_grid:
|
||||
cv2.rectangle(heatmap, (x_start, y_start), (x_end, y_end), (255, 255, 255), 1)
|
||||
|
||||
# ─────────────────────────────────────────────
|
||||
# Processamento da detecção: Região AÉREA
|
||||
# ─────────────────────────────────────────────
|
||||
for i in range(AIR_ROWS):
|
||||
y_start = i * row_height_air
|
||||
y_end = y_start + row_height_air
|
||||
|
||||
for j in range(AIR_COLS):
|
||||
x_start = j * cell_width_air
|
||||
x_end = x_start + cell_width_air
|
||||
if smoothed_air[i, j] < (air_reference[i, j] - DEPTH_LIMIT):
|
||||
cv2.rectangle(heatmap_overlay, (x_start, y_start), (x_end, y_end), (0, 255, 0), -1)
|
||||
if show_grid:
|
||||
cv2.rectangle(heatmap, (x_start, y_start), (x_end, y_end), (255, 255, 255), 1)
|
||||
|
||||
|
||||
try:
|
||||
memory_usage = device_global.getDdrMemoryUsage()
|
||||
memory_info = {
|
||||
"remaining": memory_usage.remaining,
|
||||
"total": memory_usage.total,
|
||||
"used": memory_usage.used
|
||||
}
|
||||
except:
|
||||
except:
|
||||
memory_info = None # Se houver erro, define como None
|
||||
|
||||
try:
|
||||
temp = device.getChipTemperature()
|
||||
try:
|
||||
temp = device_global.getChipTemperature()
|
||||
temp_info = {
|
||||
"css": temp.css,
|
||||
"mss": temp.mss,
|
||||
"upa": temp.upa,
|
||||
"dss": temp.dss
|
||||
}
|
||||
except:
|
||||
except:
|
||||
temp_info = None # Se houver erro, define como None
|
||||
|
||||
device_data = {
|
||||
"id": selected_device_info.getMxId(), # ID do dispositivo
|
||||
"name": selected_device_info.name, # Nome do dispositivo
|
||||
"state": selected_device_info.state.name, # Estado do dispositivo
|
||||
"usb_speed": str(device.getUsbSpeed().name) if hasattr(device, 'getUsbSpeed') else None, # Velocidade USB
|
||||
"available_camera_sensors": [sensor.name for sensor in device.getConnectedCameras()], # Sensores de câmera disponíveis
|
||||
"version": str(device.getDeviceInfo().protocol) if hasattr(device, 'getDeviceInfo') else None, # Versão do protocolo
|
||||
"memory_usage": memory_info, # Uso de memória DDR
|
||||
"temperature": temp_info, # Temperatura do chip
|
||||
"bootloader_version": str(device.getBootloaderVersion()) if hasattr(device, 'getBootloaderVersion') else None, # Bootloader
|
||||
"is_pipeline_running": device.isPipelineRunning() if hasattr(device, 'isPipelineRunning') else None # Pipeline rodando?
|
||||
}
|
||||
device_data = {
|
||||
"id": selected_device_info.getMxId(), # ID do dispositivo
|
||||
"name": selected_device_info.name, # Nome do dispositivo
|
||||
"state": selected_device_info.state.name, # Estado do dispositivo
|
||||
"usb_speed": str(device_global.getUsbSpeed().name) if hasattr(device_global, 'getUsbSpeed') else None, # Velocidade USB
|
||||
"available_camera_sensors": [sensor.name for sensor in device_global.getConnectedCameras()], # Sensores de câmera disponíveis
|
||||
"version": str(device_global.getDeviceInfo().protocol) if hasattr(device_global, 'getDeviceInfo') else None, # Versão do protocolo
|
||||
"memory_usage": memory_info, # Uso de memória DDR
|
||||
"temperature": temp_info, # Temperatura do chip
|
||||
"bootloader_version": str(device_global.getBootloaderVersion()) if hasattr(device_global, 'getBootloaderVersion') else None, # Bootloader
|
||||
"is_pipeline_running": device_global.isPipelineRunning() if hasattr(device_global, 'isPipelineRunning') else None # Pipeline rodando?
|
||||
}
|
||||
|
||||
|
||||
json_data = {
|
||||
'timestamp': timestamp,
|
||||
'device_data': device_data,
|
||||
'x_max': width,
|
||||
'y_max': height,
|
||||
'depth_data': depth_data,
|
||||
}
|
||||
json_data = {
|
||||
'timestamp': current_time,
|
||||
'device_data': device_data,
|
||||
'x_max': WIDTH,
|
||||
'y_max': HEIGHT,
|
||||
'subdivisoes': gerar_json_subdivisoes(),
|
||||
}
|
||||
|
||||
readings.append(json_data)
|
||||
readings.append(json_data)
|
||||
|
||||
# Enviar apenas a cada max_readings capturas
|
||||
if len(readings) >= max_readings:
|
||||
mensagem_relevante = readings[-1]
|
||||
mqtt_client.publish(mqtt_topic, json.dumps(mensagem_relevante).encode('utf-8'))
|
||||
readings.clear()
|
||||
# Enviar apenas a cada max_readings capturas
|
||||
if len(readings) >= max_readings:
|
||||
mensagem_relevante = readings[-1]
|
||||
mqtt_client.publish(mqtt_topic, json.dumps(mensagem_relevante).encode('utf-8'))
|
||||
readings.clear()
|
||||
|
||||
|
||||
frame = frame_data.getCvFrame()
|
||||
ret, buffer = cv2.imencode('.jpg', frame)
|
||||
frame = buffer.tobytes()
|
||||
yield (b'--frame\r\n'
|
||||
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
|
||||
video_frame = heatmap
|
||||
ret, buffer = cv2.imencode('.jpg', video_frame, [cv2.IMWRITE_JPEG_QUALITY, 80]) # Reduz qualidade para 80%
|
||||
frame = buffer.tobytes()
|
||||
yield (b'--frame\r\n'
|
||||
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
|
||||
|
||||
# 🔹 Função para enviar vídeo via Flask
|
||||
def view_rgb_video():
|
||||
|
||||
if camera_iniciada == False:
|
||||
initialize_device()
|
||||
|
||||
global device_global, selected_device_info
|
||||
|
||||
rgb_queue = device_global.getOutputQueue(name="rgb", maxSize=1, blocking=False)
|
||||
|
||||
while True:
|
||||
in_rgb = rgb_queue.tryGet()
|
||||
if in_rgb is None:
|
||||
continue
|
||||
|
||||
rgb_frame = in_rgb.getCvFrame()
|
||||
|
||||
video_frame = rgb_frame
|
||||
ret, buffer = cv2.imencode('.jpg', video_frame, [cv2.IMWRITE_JPEG_QUALITY, 80]) # Reduz qualidade para 80%
|
||||
frame = buffer.tobytes()
|
||||
yield (b'--frame\r\n'
|
||||
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
|
||||
|
||||
|
||||
|
||||
def send_script_ready():
|
||||
mqtt_client.publish(mqtt_topic, "OK")
|
||||
def send_script_ready1():
|
||||
mqtt_client.publish(mqtt_topic, "OK_1")
|
||||
|
||||
def send_script_ready2():
|
||||
mqtt_client.publish(mqtt_topic, "OK_2")
|
||||
|
||||
def run_flask_server():
|
||||
app.run(host='0.0.0.0', port=porta, threaded=True, debug=False)
|
||||
|
||||
@app.route('/' + url, methods=['GET'])
|
||||
def video_feed():
|
||||
camera_index = int(request.args.get('camera_index'))
|
||||
return Response(generate_video(camera_index), mimetype='multipart/x-mixed-replace; boundary=frame')
|
||||
# 🔹 Servidores Flask para RGB e Heatmap
|
||||
@app.route('/' + url_rgb, methods=['GET'])
|
||||
def video_feed_rgb():
|
||||
return Response(view_rgb_video(), mimetype='multipart/x-mixed-replace; boundary=frame')
|
||||
|
||||
@app.route('/' + url_heatmap, methods=['GET'])
|
||||
def video_feed_heatmap():
|
||||
return Response(process_depth_data(), mimetype='multipart/x-mixed-replace; boundary=frame')
|
||||
|
||||
if __name__ == '__main__':
|
||||
mqtt_thread = threading.Thread(target=send_script_ready)
|
||||
mqtt_thread.start()
|
||||
run_flask_server()
|
||||
flask_thread = threading.Thread(target=run_flask_server)
|
||||
flask_thread.start()
|
||||
time.sleep(1)
|
||||
mqtt_thread1 = threading.Thread(target=send_script_ready1)
|
||||
mqtt_thread1.start()
|
||||
time.sleep(5)
|
||||
mqtt_thread2 = threading.Thread(target=send_script_ready2)
|
||||
mqtt_thread2.start()
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -185,8 +185,18 @@ namespace AgroMonitor.Forms
|
|||
|
||||
private async Task CarregarOperacao()
|
||||
{
|
||||
(bool carregado, List<string> ruasSelecionadas) = await Variaveis.OperacaoEmAndamento.CarregarParametrizacaoOperacao(pnlMapa, lblMapaCarregado);
|
||||
if (carregado)
|
||||
(bool carregado, List<string> ruasSelecionadas) = Variaveis.OperacaoEmAndamento.CarregarParametrizacaoOperacao(pnlMapa, lblMapaCarregado);
|
||||
|
||||
bool condicaoOperacaoCarregada() => Variaveis.OperacaoEmAndamento.Trajetoria?.CorredorAtual != null;
|
||||
bool resultado = await FuncoesGlobais.AguardarCondicaoAsync(condicaoOperacaoCarregada, 5000, 200);
|
||||
|
||||
if (!resultado)
|
||||
{
|
||||
MessageBox.Show($"Erro ao carregar operação!{Environment.NewLine}Erro ao carregar a trajetória do mapa!", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (carregado && resultado)
|
||||
{
|
||||
tabControl1.SelectedIndex = 1;
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Loading…
Reference in New Issue