Ajustes de estrutura de dados
This commit is contained in:
parent
c5e90f7b44
commit
909b7261d6
|
|
@ -652,96 +652,6 @@
|
||||||
<None Include="Imagens\salvar.png" />
|
<None Include="Imagens\salvar.png" />
|
||||||
<Content Include="Imagens\transferidor.png" />
|
<Content Include="Imagens\transferidor.png" />
|
||||||
<None Include="Imagens\voltar.png" />
|
<None Include="Imagens\voltar.png" />
|
||||||
<Content Include="Python\Models\deeplabv3plus\backbone\hrnetv2.py">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\deeplabv3plus\backbone\mobilenetv2.py">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\deeplabv3plus\backbone\resnet.py">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\deeplabv3plus\backbone\xception.py">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\deeplabv3plus\backbone\__init__.py">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\deeplabv3plus\modeling.py">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\deeplabv3plus\utils.py">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\deeplabv3plus\_deeplab.py">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\deeplabv3plus\__init__.py">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolov7\models\common.py">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolov7\models\experimental.py">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolov7\models\yolo.py">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolov7\models\__init__.py">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolov7\utils\activations.py">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolov7\utils\add_nms.py">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolov7\utils\autoanchor.py">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolov7\utils\aws\resume.py">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolov7\utils\aws\__init__.py">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolov7\utils\datasets.py">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolov7\utils\general.py">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolov7\utils\google_app_engine\additional_requirements.txt">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolov7\utils\google_utils.py">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolov7\utils\loss.py">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolov7\utils\metrics.py">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolov7\utils\plots.py">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolov7\utils\torch_utils.py">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolov7\utils\wandb_logging\log_dataset.py">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolov7\utils\wandb_logging\wandb_utils.py">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolov7\utils\wandb_logging\__init__.py">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolov7\utils\__init__.py">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Output\folium\images\position_marker.png">
|
<Content Include="Python\Output\folium\images\position_marker.png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
|
@ -933,69 +843,6 @@
|
||||||
</Compile>
|
</Compile>
|
||||||
<None Include="Imagens\esp32-s3.jpg" />
|
<None Include="Imagens\esp32-s3.jpg" />
|
||||||
<None Include="Imagens\esp32-wrover.jpg" />
|
<None Include="Imagens\esp32-wrover.jpg" />
|
||||||
<Content Include="Python\Models\yolo\coco.names">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolo\yolov3.cfg">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolo\yolov3.weights">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolo\coco-tiny.names">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolo\yolov3-tiny.cfg">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolo\yolov3-tiny.weights">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolo\yolov3-weed.weights">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolo\crop_weed_detection.weights">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<None Include="Python\Models\deeplabv3plus\backbone\__pycache__\hrnetv2.cpython-311.pyc">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
<None Include="Python\Models\deeplabv3plus\backbone\__pycache__\mobilenetv2.cpython-311.pyc">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
<None Include="Python\Models\deeplabv3plus\backbone\__pycache__\resnet.cpython-311.pyc">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
<None Include="Python\Models\deeplabv3plus\backbone\__pycache__\xception.cpython-311.pyc">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
<None Include="Python\Models\deeplabv3plus\backbone\__pycache__\__init__.cpython-311.pyc">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
<None Include="Python\Models\deeplabv3plus\__pycache__\modeling.cpython-311.pyc">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
<None Include="Python\Models\deeplabv3plus\__pycache__\utils.cpython-311.pyc">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
<None Include="Python\Models\deeplabv3plus\__pycache__\_deeplab.cpython-311.pyc">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
<None Include="Python\Models\deeplabv3plus\__pycache__\__init__.cpython-311.pyc">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
<Content Include="Python\Models\yolov7\utils\aws\mime.sh">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolov7\utils\aws\userdata.sh">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolov7\utils\google_app_engine\app.yaml">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Python\Models\yolov7\utils\google_app_engine\Dockerfile">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<None Include="Python\Output\fonts\glyphicons-halflings-regular.ttf">
|
<None Include="Python\Output\fonts\glyphicons-halflings-regular.ttf">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
|
@ -1024,7 +871,7 @@
|
||||||
<Content Include="Python\Scripts\map_load.py" />
|
<Content Include="Python\Scripts\map_load.py" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Python\Models\yolov7\utils\wandb_logging\__pycache__\" />
|
<Folder Include="Python\Models\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Update="runtimes\win-x64\native\*.dll">
|
<None Update="runtimes\win-x64\native\*.dll">
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ namespace AgroBase.Forms.Atuador
|
||||||
{
|
{
|
||||||
PopularBicos();
|
PopularBicos();
|
||||||
|
|
||||||
nudPressaoSP.Value = Convert.ToInt32(Variaveis.OperacaoEmAndamento.Controle.PressaoLinha);
|
nudPressaoSP.Value = Convert.ToInt32(Variaveis.OperacaoEmAndamento.Parametros.Controle.AtuPressaoLinha);
|
||||||
txtMMassaRef.Text = DispAtu.Dados._MassaRef.ToString();
|
txtMMassaRef.Text = DispAtu.Dados._MassaRef.ToString();
|
||||||
txtMLeituraRef.Text = DispAtu.Dados._MassaLeituraRef.ToString();
|
txtMLeituraRef.Text = DispAtu.Dados._MassaLeituraRef.ToString();
|
||||||
txtPressaoVmin.Text = DispAtu.Dados._PressaoVmin.ToString();
|
txtPressaoVmin.Text = DispAtu.Dados._PressaoVmin.ToString();
|
||||||
|
|
@ -63,7 +63,7 @@ namespace AgroBase.Forms.Atuador
|
||||||
|
|
||||||
private void PopularBicos()
|
private void PopularBicos()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < DispAtu.Dados.QuantidadeBicos; i++)
|
for (int i = 0; i < Variaveis.OperacaoEmAndamento.Parametros.QtdBicos; i++)
|
||||||
{
|
{
|
||||||
string ID = DispAtu.Dados.BicosPulverizadores[i].ID;
|
string ID = DispAtu.Dados.BicosPulverizadores[i].ID;
|
||||||
Label lblBico = new Label()
|
Label lblBico = new Label()
|
||||||
|
|
@ -153,7 +153,7 @@ namespace AgroBase.Forms.Atuador
|
||||||
private void nudPressaoSP_ValueChanged(object sender, EventArgs e)
|
private void nudPressaoSP_ValueChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var Bomba = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombasPressurizadoras.FirstOrDefault();
|
var Bomba = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombasPressurizadoras.FirstOrDefault();
|
||||||
Variaveis.OperacaoEmAndamento.Controle.PressaoLinha = Convert.ToInt32(((NumericUpDown)sender).Value);
|
Variaveis.OperacaoEmAndamento.Parametros.Controle.AtuPressaoLinha = Convert.ToInt32(((NumericUpDown)sender).Value);
|
||||||
GeneralJoystick.EnviarComandoAtuador(S_Code.sBMB, Bomba.ComandoAtuar, Bomba.ID);
|
GeneralJoystick.EnviarComandoAtuador(S_Code.sBMB, Bomba.ComandoAtuar, Bomba.ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -206,7 +206,7 @@ namespace AgroBase.Forms.Atuador
|
||||||
|
|
||||||
private void btnSalvar_Click(object sender, EventArgs e)
|
private void btnSalvar_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Variaveis.OperacaoEmAndamento.Controle.PressaoLinha = Convert.ToDouble(nudPressaoSP.Value);
|
Variaveis.OperacaoEmAndamento.Parametros.Controle.AtuPressaoLinha = Convert.ToDouble(nudPressaoSP.Value);
|
||||||
DispAtu.Dados._MassaRef = Convert.ToDouble(txtMMassaRef.Text);
|
DispAtu.Dados._MassaRef = Convert.ToDouble(txtMMassaRef.Text);
|
||||||
DispAtu.Dados._MassaLeituraRef = Convert.ToDouble(txtMLeituraRef.Text);
|
DispAtu.Dados._MassaLeituraRef = Convert.ToDouble(txtMLeituraRef.Text);
|
||||||
DispAtu.Dados._PressaoVmin = Convert.ToDouble(txtPressaoVmin.Text);
|
DispAtu.Dados._PressaoVmin = Convert.ToDouble(txtPressaoVmin.Text);
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,9 @@ namespace AgroBase.Forms.Atuador
|
||||||
}
|
}
|
||||||
|
|
||||||
chbBicosAtuacao.Checked = Disp.Dados.BicosPulverizadores.Any(x => x.AtuacaoNivelAlto);
|
chbBicosAtuacao.Checked = Disp.Dados.BicosPulverizadores.Any(x => x.AtuacaoNivelAlto);
|
||||||
nudBicosQtd.Value = Disp.Dados.QuantidadeBicos;
|
nudBicosQtd.Value = Variaveis.OperacaoEmAndamento.Parametros.QtdBicos;
|
||||||
txtDensidade.Text = Disp.Dados.DensidadeHerbicida.ToString("0.00");
|
txtDensidade.Text = Disp.Dados.DensidadeHerbicida.ToString("0.00");
|
||||||
nudCapMax.Value = Convert.ToInt32(Variaveis.OperacaoEmAndamento.CapacidadeReservatorio);
|
nudCapMax.Value = Convert.ToInt32(Variaveis.OperacaoEmAndamento.Parametros.QtdCamerasSolo);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void frmAtuConfig_FormClosing(object sender, FormClosingEventArgs e)
|
private void frmAtuConfig_FormClosing(object sender, FormClosingEventArgs e)
|
||||||
|
|
@ -41,9 +41,9 @@ namespace AgroBase.Forms.Atuador
|
||||||
private void btnSalvar_Click(object sender, EventArgs e)
|
private void btnSalvar_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Disp.Dados.BicosPulverizadores.ForEach(x => x.AtuacaoNivelAlto = chbBicosAtuacao.Checked);
|
Disp.Dados.BicosPulverizadores.ForEach(x => x.AtuacaoNivelAlto = chbBicosAtuacao.Checked);
|
||||||
Disp.Dados.QuantidadeBicos = Convert.ToInt32(nudBicosQtd.Value);
|
Variaveis.OperacaoEmAndamento.Parametros.QtdBicos = Convert.ToInt32(nudBicosQtd.Value);
|
||||||
Disp.Dados.DensidadeHerbicida = Convert.ToDouble(txtDensidade.Text.Replace(".", ","));
|
Disp.Dados.DensidadeHerbicida = Convert.ToDouble(txtDensidade.Text.Replace(".", ","));
|
||||||
Variaveis.OperacaoEmAndamento.CapacidadeReservatorio = Convert.ToDouble(nudCapMax.Value);
|
Variaveis.OperacaoEmAndamento.Parametros.CapacidadeReservatorio = Convert.ToDouble(nudCapMax.Value);
|
||||||
|
|
||||||
Disp.SalvarParametros(Disp.Dados);
|
Disp.SalvarParametros(Disp.Dados);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ namespace AgroBase.Forms.IHM
|
||||||
chbSonarAtivado.Enabled = KinectService.Iniciado;
|
chbSonarAtivado.Enabled = KinectService.Iniciado;
|
||||||
if (KinectService.Iniciado)
|
if (KinectService.Iniciado)
|
||||||
{
|
{
|
||||||
chbSonarAtivado.Checked = Variaveis.OperacaoEmAndamento.Controle.SonarAtivado;
|
chbSonarAtivado.Checked = Variaveis.OperacaoEmAndamento.Parametros.Controle.SonarAtivado;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -259,7 +259,7 @@ namespace AgroBase.Forms.IHM
|
||||||
CameraCaminho = Variaveis.OperacaoEmAndamento.DispSen.Dados.CameraCaminho.Clone();
|
CameraCaminho = Variaveis.OperacaoEmAndamento.DispSen.Dados.CameraCaminho.Clone();
|
||||||
CamerasSolo = new List<OAKCameraModel>(Variaveis.OperacaoEmAndamento.DispSen.Dados.CamerasSolo);
|
CamerasSolo = new List<OAKCameraModel>(Variaveis.OperacaoEmAndamento.DispSen.Dados.CamerasSolo);
|
||||||
|
|
||||||
for (int i = 0; i < Variaveis.OperacaoEmAndamento.QuantidadeCamerasSolo; i++)
|
for (int i = 0; i < Variaveis.OperacaoEmAndamento.Parametros.QtdCamerasSolo; i++)
|
||||||
{
|
{
|
||||||
GerarCameraSolo(i);
|
GerarCameraSolo(i);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -526,7 +526,7 @@ namespace AgroBase.Forms.IHM
|
||||||
private async Task EnviarComandoBomba(bool Ligar, double Pressao, int Timeout, AtuadorModel disp = null)
|
private async Task EnviarComandoBomba(bool Ligar, double Pressao, int Timeout, AtuadorModel disp = null)
|
||||||
{
|
{
|
||||||
var Bomba = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombasPressurizadoras.FirstOrDefault();
|
var Bomba = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombasPressurizadoras.FirstOrDefault();
|
||||||
Variaveis.OperacaoEmAndamento.Controle.PressaoLinha = Pressao + 10;
|
Variaveis.OperacaoEmAndamento.Parametros.Controle.AtuPressaoLinha = Pressao + 10;
|
||||||
GeneralJoystick.EnviarComandoAtuador(S_Code.sBMB, Ligar, Bomba.ID);
|
GeneralJoystick.EnviarComandoAtuador(S_Code.sBMB, Ligar, Bomba.ID);
|
||||||
|
|
||||||
DateTime inicio = DateTime.Now;
|
DateTime inicio = DateTime.Now;
|
||||||
|
|
@ -941,7 +941,7 @@ namespace AgroBase.Forms.IHM
|
||||||
|
|
||||||
TipoMovimentoDirecional _oldTipoMovimento = Variaveis.OperacaoEmAndamento.Controle.TipoMovimento;
|
TipoMovimentoDirecional _oldTipoMovimento = Variaveis.OperacaoEmAndamento.Controle.TipoMovimento;
|
||||||
double _oldAngulo = Variaveis.OperacaoEmAndamento.Controle.Angulo;
|
double _oldAngulo = Variaveis.OperacaoEmAndamento.Controle.Angulo;
|
||||||
double _oldVelocidadeMP = Variaveis.OperacaoEmAndamento.Controle.VelocidadeMP;
|
double _oldVelocidadeMP = Variaveis.OperacaoEmAndamento.Parametros.Controle.DirVelocidadeMovimento;
|
||||||
|
|
||||||
DispositivosService<MovimentacaoUnificadaModel> Dispositivo = (DispositivosService<MovimentacaoUnificadaModel>)Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == Enums.T_Code.Mvd);
|
DispositivosService<MovimentacaoUnificadaModel> Dispositivo = (DispositivosService<MovimentacaoUnificadaModel>)Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == Enums.T_Code.Mvd);
|
||||||
|
|
||||||
|
|
@ -952,7 +952,7 @@ namespace AgroBase.Forms.IHM
|
||||||
|
|
||||||
Variaveis.OperacaoEmAndamento.Controle.TipoMovimento = TipoMovimentoDirecional.Diagnostico;
|
Variaveis.OperacaoEmAndamento.Controle.TipoMovimento = TipoMovimentoDirecional.Diagnostico;
|
||||||
Variaveis.OperacaoEmAndamento.Controle.Angulo = 25;
|
Variaveis.OperacaoEmAndamento.Controle.Angulo = 25;
|
||||||
Variaveis.OperacaoEmAndamento.Controle.VelocidadeMP = 30;
|
Variaveis.OperacaoEmAndamento.Parametros.Controle.DirVelocidadeMovimento = 30;
|
||||||
|
|
||||||
bool SenConectado = SerialService.DispositivosMapeados.Any(x => x.Dispositivo == T_Code.Sen);
|
bool SenConectado = SerialService.DispositivosMapeados.Any(x => x.Dispositivo == T_Code.Sen);
|
||||||
idx = PreencheDadosLinha(grid, Testes, idx, SenConectado ? 1 : 0);
|
idx = PreencheDadosLinha(grid, Testes, idx, SenConectado ? 1 : 0);
|
||||||
|
|
@ -1001,7 +1001,7 @@ namespace AgroBase.Forms.IHM
|
||||||
|
|
||||||
Variaveis.OperacaoEmAndamento.Controle.TipoMovimento = _oldTipoMovimento;
|
Variaveis.OperacaoEmAndamento.Controle.TipoMovimento = _oldTipoMovimento;
|
||||||
Variaveis.OperacaoEmAndamento.Controle.Angulo = _oldAngulo;
|
Variaveis.OperacaoEmAndamento.Controle.Angulo = _oldAngulo;
|
||||||
Variaveis.OperacaoEmAndamento.Controle.VelocidadeMP = _oldVelocidadeMP;
|
Variaveis.OperacaoEmAndamento.Parametros.Controle.DirVelocidadeMovimento = _oldVelocidadeMP;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -1227,7 +1227,7 @@ namespace AgroBase.Forms.IHM
|
||||||
bool PzmConectado = SerialService.DispositivosMapeados.Any(x => x.Dispositivo == Enums.T_Code.Pzm);
|
bool PzmConectado = SerialService.DispositivosMapeados.Any(x => x.Dispositivo == Enums.T_Code.Pzm);
|
||||||
idx = PreencheDadosLinha(grid, Testes, idx, PzmConectado ? 1 : 0);
|
idx = PreencheDadosLinha(grid, Testes, idx, PzmConectado ? 1 : 0);
|
||||||
|
|
||||||
var S36V = Variaveis.OperacaoEmAndamento.Sensoriamento.Bateria;
|
var S36V = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Bateria;
|
||||||
bool S36VInicializado = S36V.Iniciado;
|
bool S36VInicializado = S36V.Iniciado;
|
||||||
idx = PreencheDadosLinha(grid, Testes, idx, S36VInicializado ? 1 : 0);
|
idx = PreencheDadosLinha(grid, Testes, idx, S36VInicializado ? 1 : 0);
|
||||||
|
|
||||||
|
|
@ -1264,7 +1264,7 @@ namespace AgroBase.Forms.IHM
|
||||||
double Corrente12V = S12V.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.Corrente).atual.valor;
|
double Corrente12V = S12V.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.Corrente).atual.valor;
|
||||||
idx = PreencheDadosLinha(grid, Testes, idx, Corrente12V);
|
idx = PreencheDadosLinha(grid, Testes, idx, Corrente12V);
|
||||||
|
|
||||||
var SImu = Variaveis.OperacaoEmAndamento.Sensoriamento.IMU;
|
var SImu = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.IMU;
|
||||||
double Orientacao = SImu.Iniciado ? SImu.Rotacao : -1;
|
double Orientacao = SImu.Iniciado ? SImu.Rotacao : -1;
|
||||||
idx = PreencheDadosLinha(grid, Testes, idx, Orientacao);
|
idx = PreencheDadosLinha(grid, Testes, idx, Orientacao);
|
||||||
|
|
||||||
|
|
@ -1274,13 +1274,13 @@ namespace AgroBase.Forms.IHM
|
||||||
bool GpsInicializado = GPSService.Iniciado;
|
bool GpsInicializado = GPSService.Iniciado;
|
||||||
idx = PreencheDadosLinha(grid, Testes, idx, GpsInicializado ? 1 : 0);
|
idx = PreencheDadosLinha(grid, Testes, idx, GpsInicializado ? 1 : 0);
|
||||||
|
|
||||||
double Precisao = GpsInicializado ? (int)Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.QualidadeFix : -1;
|
double Precisao = GpsInicializado ? (int)Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps.QualidadeFix : -1;
|
||||||
idx = PreencheDadosLinha(grid, Testes, idx, Precisao);
|
idx = PreencheDadosLinha(grid, Testes, idx, Precisao);
|
||||||
|
|
||||||
double Satelites = GpsInicializado ? Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.NumeroSatelites : -1;
|
double Satelites = GpsInicializado ? Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps.NumeroSatelites : -1;
|
||||||
idx = PreencheDadosLinha(grid, Testes, idx, Satelites);
|
idx = PreencheDadosLinha(grid, Testes, idx, Satelites);
|
||||||
|
|
||||||
double OrientacaoGPS = GpsInicializado ? Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.OrientacaoReal : -1;
|
double OrientacaoGPS = GpsInicializado ? Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps.OrientacaoReal : -1;
|
||||||
idx = PreencheDadosLinha(grid, Testes, idx, OrientacaoGPS);
|
idx = PreencheDadosLinha(grid, Testes, idx, OrientacaoGPS);
|
||||||
|
|
||||||
bool A05Conectado = SerialService.DispositivosMapeados.Any(x => x.Dispositivo == Enums.T_Code.A05);
|
bool A05Conectado = SerialService.DispositivosMapeados.Any(x => x.Dispositivo == Enums.T_Code.A05);
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ namespace AgroBase.Forms.IHM
|
||||||
|
|
||||||
public void AtualizarMapaDinamico()
|
public void AtualizarMapaDinamico()
|
||||||
{
|
{
|
||||||
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
|
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura;
|
||||||
var _Trajetoria = Variaveis.OperacaoEmAndamento.Trajetoria;
|
var _Trajetoria = Variaveis.OperacaoEmAndamento.Trajetoria;
|
||||||
|
|
||||||
if (_Trajetoria != null && _Trajetoria.CorredorAtual != null)
|
if (_Trajetoria != null && _Trajetoria.CorredorAtual != null)
|
||||||
|
|
@ -160,10 +160,10 @@ namespace AgroBase.Forms.IHM
|
||||||
pnlOrientacao.Invalidate();
|
pnlOrientacao.Invalidate();
|
||||||
pnlInclinacao.Invalidate();
|
pnlInclinacao.Invalidate();
|
||||||
|
|
||||||
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
|
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura;
|
||||||
|
|
||||||
lblUltimaLeituraSolo.Text = "Última Leitura Solo: " + Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorErvas.UltimaMensagem.ToString("HH:mm:ss.fff");
|
lblUltimaLeituraSolo.Text = "Última Leitura Solo: " + _Sensoriamento.OperadorErvas.UltimaMensagem.ToString("HH:mm:ss.fff");
|
||||||
lblUltimaLeituraCaminho.Text = "Última Leitura Caminho: " + Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorVisual.UltimaMensagem.ToString("HH:mm:ss.fff");
|
lblUltimaLeituraCaminho.Text = "Última Leitura Caminho: " + _Sensoriamento.OperadorVisual.UltimaMensagem.ToString("HH:mm:ss.fff");
|
||||||
lblPerformance.Text = _Sensoriamento.DadosPerformance.PerformanceStr;
|
lblPerformance.Text = _Sensoriamento.DadosPerformance.PerformanceStr;
|
||||||
|
|
||||||
lblMapaCarregado.Text = "Operação: " + Variaveis.OperacaoEmAndamento.Descricao;
|
lblMapaCarregado.Text = "Operação: " + Variaveis.OperacaoEmAndamento.Descricao;
|
||||||
|
|
@ -210,7 +210,7 @@ namespace AgroBase.Forms.IHM
|
||||||
tkbVelocidade.Value = Convert.ToInt32(_Sensoriamento.Controle.PercentualVelocidadeSP);
|
tkbVelocidade.Value = Convert.ToInt32(_Sensoriamento.Controle.PercentualVelocidadeSP);
|
||||||
|
|
||||||
tkbAnguloDirecional.Minimum = 0;
|
tkbAnguloDirecional.Minimum = 0;
|
||||||
tkbAnguloDirecional.Maximum = Convert.ToInt32(_Sensoriamento.Controle.Angulo_Max);
|
tkbAnguloDirecional.Maximum = Convert.ToInt32(Variaveis.OperacaoEmAndamento.Parametros.Controle.DirAnguloMaximo);
|
||||||
tkbAnguloDirecional.Value = Math.Abs(Convert.ToInt32(_Sensoriamento.Controle.Angulo));
|
tkbAnguloDirecional.Value = Math.Abs(Convert.ToInt32(_Sensoriamento.Controle.Angulo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -294,8 +294,8 @@ namespace AgroBase.Forms.IHM
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
double angulo = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.AnguloCarroDefinido;
|
double angulo = Variaveis.OperacaoEmAndamento.Parametros?.DadosLeitura?.Gps?.AnguloCarroDefinido ?? 0;
|
||||||
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)angulo, 90, (float)Variaveis.OperacaoEmAndamento.Sensoriamento.Trajetoria.AnguloCaminho);
|
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)angulo, 90, (float)(Variaveis.OperacaoEmAndamento.Parametros?.DadosLeitura?.Trajetoria?.AnguloCaminho ?? 0));
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
|
|
@ -333,15 +333,16 @@ namespace AgroBase.Forms.IHM
|
||||||
pnlJoystick.Visible = false;
|
pnlJoystick.Visible = false;
|
||||||
tabControl1.TabPages.Remove(tabControle);
|
tabControl1.TabPages.Remove(tabControle);
|
||||||
|
|
||||||
|
var pControle = Variaveis.OperacaoEmAndamento.Parametros.Controle;
|
||||||
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
|
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
|
||||||
cmbModoControle.SelectedIndex = (int)_Controle.TipoMovimento;
|
cmbModoControle.SelectedIndex = (int)_Controle.TipoMovimento;
|
||||||
chbSonarAtivado.Checked = _Controle.SonarAtivado;
|
chbSonarAtivado.Checked = pControle.SonarAtivado;
|
||||||
chbFrenagemAutomatica.Checked = _Controle.FrenagemAutomatica;
|
chbFrenagemAutomatica.Checked = pControle.FrenagemAutomatica;
|
||||||
nudVelSemErvas.Value = (int)_Controle.PercentualVelocidadeMax;
|
nudVelSemErvas.Value = (int)pControle.MovVelocidadeSErvasPercent;
|
||||||
nudVelComErvas.Value = (int)_Controle.PercentualVelocidadeMin;
|
nudVelComErvas.Value = (int)pControle.MovVelocidadeCErvasPercent;
|
||||||
chbPulverizadorAutomatico.Checked = _Controle.PulverizadorAutomatico;
|
chbPulverizadorAutomatico.Checked = pControle.PulverizadorAutomatico;
|
||||||
nudPercentualAtuacaoBico.Value = (int)(_Controle.PercentualInicioPulverizacao * 100.0);
|
nudPercentualAtuacaoBico.Value = (int)pControle.AtuPercentualInicioPulverizacao;
|
||||||
nudPressaoLinha.Value = (int)_Controle.PressaoLinha;
|
nudPressaoLinha.Value = (int)pControle.AtuPressaoLinha;
|
||||||
FuncoesGlobais.PreencheValorTrackBar(tkbAnguloDirecional, _Controle.Angulo);
|
FuncoesGlobais.PreencheValorTrackBar(tkbAnguloDirecional, _Controle.Angulo);
|
||||||
FuncoesGlobais.PreencheValorTrackBar(tkbVelocidade, _Controle.PercentualVelocidadeSP);
|
FuncoesGlobais.PreencheValorTrackBar(tkbVelocidade, _Controle.PercentualVelocidadeSP);
|
||||||
|
|
||||||
|
|
@ -670,7 +671,7 @@ namespace AgroBase.Forms.IHM
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 1) Pega o estado atual do seu sistema
|
// 1) Pega o estado atual do seu sistema
|
||||||
var src = Variaveis.OperacaoEmAndamento.ModulosMandatorios;
|
var src = Variaveis.OperacaoEmAndamento.Parametros.ModulosMandatorios;
|
||||||
var saude = HealthWorkerService.ModulosSaude;
|
var saude = HealthWorkerService.ModulosSaude;
|
||||||
|
|
||||||
// 2) Constrói snapshot
|
// 2) Constrói snapshot
|
||||||
|
|
@ -802,7 +803,7 @@ namespace AgroBase.Forms.IHM
|
||||||
|
|
||||||
// escreve de volta na fonte oficial
|
// escreve de volta na fonte oficial
|
||||||
var disp = _modulosUI[idx].Disp;
|
var disp = _modulosUI[idx].Disp;
|
||||||
var alvo = Variaveis.OperacaoEmAndamento.ModulosMandatorios.FirstOrDefault(m => m.Dispositivo.Equals(disp));
|
var alvo = Variaveis.OperacaoEmAndamento.Parametros.ModulosMandatorios.FirstOrDefault(m => m.Dispositivo.Equals(disp));
|
||||||
if (alvo != null)
|
if (alvo != null)
|
||||||
{
|
{
|
||||||
if (alvo.Utilizar && alvo.Mandatorio && !novoUtilizar)
|
if (alvo.Utilizar && alvo.Mandatorio && !novoUtilizar)
|
||||||
|
|
@ -866,16 +867,16 @@ namespace AgroBase.Forms.IHM
|
||||||
{ ("Não", DialogResult.No), () => { } },
|
{ ("Não", DialogResult.No), () => { } },
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
|
var pControle = Variaveis.OperacaoEmAndamento.Parametros.Controle;
|
||||||
if (res == DialogResult.Yes)
|
if (res == DialogResult.Yes)
|
||||||
{
|
{
|
||||||
_Controle.SonarAtivado = chbSonarAtivado.Checked;
|
pControle.SonarAtivado = chbSonarAtivado.Checked;
|
||||||
_Controle.FrenagemAutomatica = chbFrenagemAutomatica.Checked;
|
pControle.FrenagemAutomatica = chbFrenagemAutomatica.Checked;
|
||||||
_Controle.RPM_Max = (int)FuncoesMatematicas.CalculaRPMVelocidade(FuncoesMatematicas.CalculaVelocidadeMsPercentual((int)nudVelSemErvas.Value));
|
pControle.MovVelocidadeSErvasPercent = (int)FuncoesMatematicas.CalculaRPMVelocidade(FuncoesMatematicas.CalculaVelocidadeMsPercentual((int)nudVelSemErvas.Value));
|
||||||
_Controle.RPM_Min = (int)FuncoesMatematicas.CalculaRPMVelocidade(FuncoesMatematicas.CalculaVelocidadeMsPercentual((int)nudVelComErvas.Value));
|
pControle.MovVelocidadeCErvasPercent = (int)FuncoesMatematicas.CalculaRPMVelocidade(FuncoesMatematicas.CalculaVelocidadeMsPercentual((int)nudVelComErvas.Value));
|
||||||
_Controle.PulverizadorAutomatico = chbPulverizadorAutomatico.Checked;
|
pControle.PulverizadorAutomatico = chbPulverizadorAutomatico.Checked;
|
||||||
_Controle.PercentualInicioPulverizacao = ((double)nudPercentualAtuacaoBico.Value / 100.0);
|
pControle.AtuPercentualInicioPulverizacao = ((double)nudPercentualAtuacaoBico.Value / 100.0);
|
||||||
_Controle.PressaoLinha = (double)nudPressaoLinha.Value;
|
pControle.AtuPressaoLinha = (double)nudPressaoLinha.Value;
|
||||||
|
|
||||||
RedisService.AtualizarCampos(
|
RedisService.AtualizarCampos(
|
||||||
CtxKey.DadosPesosMPC,
|
CtxKey.DadosPesosMPC,
|
||||||
|
|
@ -893,13 +894,13 @@ namespace AgroBase.Forms.IHM
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
chbSonarAtivado.Checked = _Controle.SonarAtivado;
|
chbSonarAtivado.Checked = pControle.SonarAtivado;
|
||||||
chbFrenagemAutomatica.Checked = _Controle.FrenagemAutomatica;
|
chbFrenagemAutomatica.Checked = pControle.FrenagemAutomatica;
|
||||||
nudVelSemErvas.Value = (int)_Controle.PercentualVelocidadeMax;
|
nudVelSemErvas.Value = (int)pControle.MovVelocidadeSErvasPercent;
|
||||||
nudVelComErvas.Value = (int)_Controle.PercentualVelocidadeMin;
|
nudVelComErvas.Value = (int)pControle.MovVelocidadeCErvasPercent;
|
||||||
chbPulverizadorAutomatico.Checked = _Controle.PulverizadorAutomatico;
|
chbPulverizadorAutomatico.Checked = pControle.PulverizadorAutomatico;
|
||||||
nudPercentualAtuacaoBico.Value = (int)(_Controle.PercentualInicioPulverizacao * 100.0);
|
nudPercentualAtuacaoBico.Value = (int)pControle.AtuPercentualInicioPulverizacao;
|
||||||
nudPressaoLinha.Value = (int)_Controle.PressaoLinha;
|
nudPressaoLinha.Value = (int)pControle.AtuPressaoLinha;
|
||||||
string pesosMpcStr = RedisService.Get(CtxKey.DadosPesosMPC);
|
string pesosMpcStr = RedisService.Get(CtxKey.DadosPesosMPC);
|
||||||
var pesos = JsonConvert.DeserializeObject<MPCPesosModel>(pesosMpcStr);
|
var pesos = JsonConvert.DeserializeObject<MPCPesosModel>(pesosMpcStr);
|
||||||
txtPesoPosicao.Text = pesos.posicao.ToString();
|
txtPesoPosicao.Text = pesos.posicao.ToString();
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,7 @@ namespace AgroBase.Forms.Operacoes
|
||||||
{
|
{
|
||||||
string disp = chb.Name.Replace("chb", "");
|
string disp = chb.Name.Replace("chb", "");
|
||||||
T_Code Dispositivo = (T_Code)Enum.Parse(typeof(T_Code), disp);
|
T_Code Dispositivo = (T_Code)Enum.Parse(typeof(T_Code), disp);
|
||||||
chb.Checked = Variaveis.OperacaoEmAndamento.ModulosMandatorios.Any(x => x.Dispositivo == Dispositivo && x.Mandatorio);
|
chb.Checked = Variaveis.OperacaoEmAndamento.Parametros.ModulosMandatorios.Any(x => x.Dispositivo == Dispositivo && x.Mandatorio);
|
||||||
}
|
}
|
||||||
|
|
||||||
txtModoOperacao.Text = Variaveis.OperacaoEmAndamento.Modo.ToString();
|
txtModoOperacao.Text = Variaveis.OperacaoEmAndamento.Modo.ToString();
|
||||||
|
|
|
||||||
|
|
@ -60,8 +60,8 @@ namespace AgroBase.Forms.Operacoes
|
||||||
flwCamerasSolo.Controls.Add(pnlCam);
|
flwCamerasSolo.Controls.Add(pnlCam);
|
||||||
}
|
}
|
||||||
|
|
||||||
chbPulverizador.Checked = Variaveis.OperacaoEmAndamento.Controle.PulverizadorAutomatico;
|
chbPulverizador.Checked = Variaveis.OperacaoEmAndamento.Parametros.Controle.PulverizadorAutomatico;
|
||||||
chbSonarAtivado.Checked = Variaveis.OperacaoEmAndamento.Controle.SonarAtivado;
|
chbSonarAtivado.Checked = Variaveis.OperacaoEmAndamento.Parametros.Controle.SonarAtivado;
|
||||||
|
|
||||||
InicializarComandosDirecional();
|
InicializarComandosDirecional();
|
||||||
PopularInformacoesGerais();
|
PopularInformacoesGerais();
|
||||||
|
|
@ -151,7 +151,7 @@ namespace AgroBase.Forms.Operacoes
|
||||||
|
|
||||||
AtualizarInformacoesGerais();
|
AtualizarInformacoesGerais();
|
||||||
|
|
||||||
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
|
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura;
|
||||||
|
|
||||||
lblDistanciaEsquerda.Text = "Distancia Esq: " + _Sensoriamento.Trajetoria.DistanciaEsquerda.ToString("0.00") + " cm";
|
lblDistanciaEsquerda.Text = "Distancia Esq: " + _Sensoriamento.Trajetoria.DistanciaEsquerda.ToString("0.00") + " cm";
|
||||||
lblDistanciaDireita.Text = "Distancia Dir: " + _Sensoriamento.Trajetoria.DistanciaDireita.ToString("0.00") + " cm";
|
lblDistanciaDireita.Text = "Distancia Dir: " + _Sensoriamento.Trajetoria.DistanciaDireita.ToString("0.00") + " cm";
|
||||||
|
|
@ -173,7 +173,7 @@ namespace AgroBase.Forms.Operacoes
|
||||||
chbPulverizador.Checked = false;
|
chbPulverizador.Checked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sonarAtivado = Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorVisual.Status == StatusModulo.Operante;
|
bool sonarAtivado = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.OperadorVisual.Status == StatusModulo.Operante;
|
||||||
chbSonarAtivado.Enabled = sonarAtivado;
|
chbSonarAtivado.Enabled = sonarAtivado;
|
||||||
if (!sonarAtivado)
|
if (!sonarAtivado)
|
||||||
{
|
{
|
||||||
|
|
@ -424,8 +424,8 @@ namespace AgroBase.Forms.Operacoes
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
double angulo = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.OrientacaoReal;
|
double angulo = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps.OrientacaoReal;
|
||||||
double angulo2 = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.AnguloCarroDefinido;
|
double angulo2 = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps.AnguloCarroDefinido;
|
||||||
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)angulo, -90, (float)angulo2);
|
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)angulo, -90, (float)angulo2);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
|
@ -433,7 +433,7 @@ namespace AgroBase.Forms.Operacoes
|
||||||
|
|
||||||
private void pnlAnguloMagnetometro_Paint(object sender, PaintEventArgs e)
|
private void pnlAnguloMagnetometro_Paint(object sender, PaintEventArgs e)
|
||||||
{
|
{
|
||||||
var imu = Variaveis.OperacaoEmAndamento.Sensoriamento.IMU;
|
var imu = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.IMU;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
double angulo = imu.Rotacao;
|
double angulo = imu.Rotacao;
|
||||||
|
|
@ -512,7 +512,7 @@ namespace AgroBase.Forms.Operacoes
|
||||||
var AB12V = _SensoresCorrente.FirstOrDefault(x => x.ID == "AB12V");
|
var AB12V = _SensoresCorrente.FirstOrDefault(x => x.ID == "AB12V");
|
||||||
var AB19V = _SensoresCorrente.FirstOrDefault(x => x.ID == "AB19V");
|
var AB19V = _SensoresCorrente.FirstOrDefault(x => x.ID == "AB19V");
|
||||||
var AB24V = _SensoresCorrente.FirstOrDefault(x => x.ID == "AB24V");
|
var AB24V = _SensoresCorrente.FirstOrDefault(x => x.ID == "AB24V");
|
||||||
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
|
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura;
|
||||||
|
|
||||||
gridDados.Rows[0].Cells[1].Value = _Sensoriamento.TempoDecorrido.ToString("HH:mm:ss");
|
gridDados.Rows[0].Cells[1].Value = _Sensoriamento.TempoDecorrido.ToString("HH:mm:ss");
|
||||||
gridDados.Rows[1].Cells[1].Value = _Sensoriamento.Movimentacao.TempoMovimento.ToString("HH:mm:ss");
|
gridDados.Rows[1].Cells[1].Value = _Sensoriamento.Movimentacao.TempoMovimento.ToString("HH:mm:ss");
|
||||||
|
|
@ -570,15 +570,15 @@ namespace AgroBase.Forms.Operacoes
|
||||||
private void PopularBicos()
|
private void PopularBicos()
|
||||||
{
|
{
|
||||||
var Atuador = Variaveis.OperacaoEmAndamento.DispAtu;
|
var Atuador = Variaveis.OperacaoEmAndamento.DispAtu;
|
||||||
nudPressaoSP.Value = Convert.ToInt32(Variaveis.OperacaoEmAndamento.Controle.PressaoLinha);
|
nudPressaoSP.Value = Convert.ToInt32(Variaveis.OperacaoEmAndamento.Parametros.Controle.AtuPressaoLinha);
|
||||||
|
|
||||||
int panelWidth = pnlAtuadores.Width;
|
int panelWidth = pnlAtuadores.Width;
|
||||||
int circleDiameter = 40; // Diâmetro dos círculos grandes
|
int circleDiameter = 40; // Diâmetro dos círculos grandes
|
||||||
int spaceBetweenCircles = (panelWidth - (circleDiameter * Atuador.Dados.QuantidadeBicos)) / (Atuador.Dados.QuantidadeBicos + 1);
|
int spaceBetweenCircles = (panelWidth - (circleDiameter * Variaveis.OperacaoEmAndamento.Parametros.QtdBicos)) / (Variaveis.OperacaoEmAndamento.Parametros.QtdBicos + 1);
|
||||||
int yPosition = (pnlAtuadores.Height - circleDiameter) / 3; // Centralizado verticalmente
|
int yPosition = (pnlAtuadores.Height - circleDiameter) / 3; // Centralizado verticalmente
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < Atuador.Dados.QuantidadeBicos; i++)
|
for (int i = 0; i < Variaveis.OperacaoEmAndamento.Parametros.QtdBicos; i++)
|
||||||
{
|
{
|
||||||
// Calcula a posição x do círculo
|
// Calcula a posição x do círculo
|
||||||
int xPosition = spaceBetweenCircles + (i * (circleDiameter + spaceBetweenCircles));
|
int xPosition = spaceBetweenCircles + (i * (circleDiameter + spaceBetweenCircles));
|
||||||
|
|
@ -637,7 +637,7 @@ namespace AgroBase.Forms.Operacoes
|
||||||
private void nudPressaoSP_ValueChanged(object sender, EventArgs e)
|
private void nudPressaoSP_ValueChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var Bomba = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombasPressurizadoras.FirstOrDefault();
|
var Bomba = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombasPressurizadoras.FirstOrDefault();
|
||||||
Variaveis.OperacaoEmAndamento.Controle.PressaoLinha = Convert.ToInt32(((NumericUpDown)sender).Value);
|
Variaveis.OperacaoEmAndamento.Parametros.Controle.AtuPressaoLinha = Convert.ToInt32(((NumericUpDown)sender).Value);
|
||||||
GeneralJoystick.EnviarComandoAtuador(S_Code.sBMB, Bomba.ComandoAtuar, Bomba.ID);
|
GeneralJoystick.EnviarComandoAtuador(S_Code.sBMB, Bomba.ComandoAtuar, Bomba.ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -678,12 +678,12 @@ namespace AgroBase.Forms.Operacoes
|
||||||
|
|
||||||
private void chbPulverizador_CheckedChanged(object sender, EventArgs e)
|
private void chbPulverizador_CheckedChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Variaveis.OperacaoEmAndamento.Controle.PulverizadorAutomatico = ((CheckBox)sender).Checked;
|
Variaveis.OperacaoEmAndamento.Parametros.Controle.PulverizadorAutomatico = ((CheckBox)sender).Checked;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void chbSonarAtivado_CheckedChanged(object sender, EventArgs e)
|
private void chbSonarAtivado_CheckedChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Variaveis.OperacaoEmAndamento.Controle.SonarAtivado = ((CheckBox)sender).Checked;
|
Variaveis.OperacaoEmAndamento.Parametros.Controle.SonarAtivado = ((CheckBox)sender).Checked;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void chbSonarDesvioAutomatico_CheckedChanged(object sender, EventArgs e)
|
private void chbSonarDesvioAutomatico_CheckedChanged(object sender, EventArgs e)
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ namespace AgroBase.Forms.Operacoes
|
||||||
pnlCaminho.Invalidate();
|
pnlCaminho.Invalidate();
|
||||||
pnlAnguloCamera.Invalidate();
|
pnlAnguloCamera.Invalidate();
|
||||||
|
|
||||||
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
|
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura;
|
||||||
|
|
||||||
/*var ultimaLeitura = Variaveis.OperacaoEmAndamento.CamerasSolo.OrderByDescending(x => x.Leitura.timestamp).FirstOrDefault();
|
/*var ultimaLeitura = Variaveis.OperacaoEmAndamento.CamerasSolo.OrderByDescending(x => x.Leitura.timestamp).FirstOrDefault();
|
||||||
if (ultimaLeitura != null)
|
if (ultimaLeitura != null)
|
||||||
|
|
@ -282,7 +282,7 @@ namespace AgroBase.Forms.Operacoes
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
double angulo = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.AnguloCarroDefinido;
|
double angulo = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps.AnguloCarroDefinido;
|
||||||
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)angulo, -90);
|
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)angulo, -90);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,8 @@ namespace AgroBase.Forms.Operacoes
|
||||||
|
|
||||||
void CarregarParametros()
|
void CarregarParametros()
|
||||||
{
|
{
|
||||||
ModulosMandatorios = Variaveis.OperacaoEmAndamento.ModulosMandatorios.ToList();
|
var _Parametros = Variaveis.OperacaoEmAndamento.Parametros;
|
||||||
|
ModulosMandatorios = _Parametros.ModulosMandatorios.ToList();
|
||||||
|
|
||||||
cmbOperacao.Items.Clear();
|
cmbOperacao.Items.Clear();
|
||||||
cmbOperacao.Items.AddRange(Enum.GetNames(typeof(ModoOperacao)));
|
cmbOperacao.Items.AddRange(Enum.GetNames(typeof(ModoOperacao)));
|
||||||
|
|
@ -52,24 +53,24 @@ namespace AgroBase.Forms.Operacoes
|
||||||
});
|
});
|
||||||
|
|
||||||
nudVelocidadeComErvas.Minimum = 0;
|
nudVelocidadeComErvas.Minimum = 0;
|
||||||
nudVelocidadeComErvas.Maximum = Convert.ToInt32(VariaveisEquipamento.RPM_Max_Roda);
|
nudVelocidadeComErvas.Maximum = 100;
|
||||||
nudVelocidadeComErvas.Value = Convert.ToInt32(Variaveis.OperacaoEmAndamento.Controle.RPM_Min);
|
nudVelocidadeComErvas.Value = Convert.ToInt32(_Parametros.Controle.MovVelocidadeCErvasPercent);
|
||||||
|
|
||||||
nudVelocidadeSemErvas.Minimum = 0;
|
nudVelocidadeSemErvas.Minimum = 0;
|
||||||
nudVelocidadeSemErvas.Maximum = Convert.ToInt32(VariaveisEquipamento.RPM_Max_Roda);
|
nudVelocidadeSemErvas.Maximum = 100;
|
||||||
nudVelocidadeSemErvas.Value = Convert.ToInt32(Variaveis.OperacaoEmAndamento.Controle.RPM_Max);
|
nudVelocidadeSemErvas.Value = Convert.ToInt32(_Parametros.Controle.MovVelocidadeSErvasPercent);
|
||||||
|
|
||||||
lblKmhCErvas.Text = FuncoesMatematicas.CalculaVelocidadeRPM(Variaveis.OperacaoEmAndamento.Controle.RPM_Min).ToString("0.00") + " Km/h";
|
lblKmhCErvas.Text = FuncoesMatematicas.ConverteMsParaKmh(FuncoesMatematicas.CalculaVelocidadeMsPercentual(_Parametros.Controle.MovVelocidadeCErvasPercent)).ToString("0.00") + " Km/h";
|
||||||
lblKmhSErvas.Text = FuncoesMatematicas.CalculaVelocidadeRPM(Variaveis.OperacaoEmAndamento.Controle.RPM_Max).ToString("0.00") + " Km/h";
|
lblKmhSErvas.Text = FuncoesMatematicas.ConverteMsParaKmh(FuncoesMatematicas.CalculaVelocidadeMsPercentual(_Parametros.Controle.MovVelocidadeSErvasPercent)).ToString("0.00") + " Km/h";
|
||||||
nudAnguloMaximo.Value = Convert.ToInt32(Variaveis.OperacaoEmAndamento.Controle.Angulo_Max);
|
nudAnguloMaximo.Value = Convert.ToInt32(_Parametros.Controle.DirAnguloMaximo);
|
||||||
nudAnguloMinimo.Value = Convert.ToInt32(Variaveis.OperacaoEmAndamento.Controle.Angulo_Min);
|
nudAnguloMinimo.Value = Convert.ToInt32(-_Parametros.Controle.DirAnguloMaximo);
|
||||||
nudVelocidadeMP.Value = Convert.ToInt32(Variaveis.OperacaoEmAndamento.Controle.VelocidadeMP);
|
nudVelocidadeMP.Value = Convert.ToInt32(_Parametros.Controle.DirVelocidadeMovimento);
|
||||||
nudTemposalvarlog.Value = (decimal)Variaveis.OperacaoEmAndamento.tmrLogsInterval / 1000;
|
nudTemposalvarlog.Value = (decimal)Variaveis.OperacaoEmAndamento.tmrLogsInterval / 1000;
|
||||||
nudQtdBicos.Value = Variaveis.OperacaoEmAndamento.DispAtu.Dados.QuantidadeBicos;
|
nudQtdBicos.Value = _Parametros.QtdBicos;
|
||||||
nudQtdCameras.Value = Variaveis.OperacaoEmAndamento.QuantidadeCamerasSolo;
|
nudQtdCameras.Value = _Parametros.QtdCamerasSolo;
|
||||||
nudCapacidadereservatorio.Value = Convert.ToInt32(Variaveis.OperacaoEmAndamento.CapacidadeReservatorio);
|
nudCapacidadereservatorio.Value = Convert.ToInt32(_Parametros.CapacidadeReservatorio);
|
||||||
txtDensidadeherbicida.Text = Variaveis.OperacaoEmAndamento.DispAtu.Dados.DensidadeHerbicida.ToString("0.00");
|
txtDensidadeherbicida.Text = Variaveis.OperacaoEmAndamento.DispAtu.Dados.DensidadeHerbicida.ToString("0.00");
|
||||||
nudAtuarem.Value = Convert.ToInt32(Variaveis.OperacaoEmAndamento.Controle.PercentualInicioPulverizacao * 100);
|
nudAtuarem.Value = Convert.ToInt32(_Parametros.Controle.AtuPercentualInicioPulverizacao);
|
||||||
cmbScriptErvas.SelectedIndex = cmbScriptErvas.Items.IndexOf(Variaveis.OperacaoEmAndamento.DispAtu.Dados.ScriptDeteccaoErvas.Replace(".py", ""));
|
cmbScriptErvas.SelectedIndex = cmbScriptErvas.Items.IndexOf(Variaveis.OperacaoEmAndamento.DispAtu.Dados.ScriptDeteccaoErvas.Replace(".py", ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -125,19 +126,18 @@ namespace AgroBase.Forms.Operacoes
|
||||||
|
|
||||||
void SalvarOperacao()
|
void SalvarOperacao()
|
||||||
{
|
{
|
||||||
Variaveis.OperacaoEmAndamento.ModulosMandatorios = ModulosMandatorios.Where(x => x.Utilizar).ToList();
|
Variaveis.OperacaoEmAndamento.Parametros.ModulosMandatorios = ModulosMandatorios.Where(x => x.Utilizar).ToList();
|
||||||
Variaveis.OperacaoEmAndamento.Controle.RPM_Max = (int)(nudVelocidadeSemErvas.Value);
|
Variaveis.OperacaoEmAndamento.Parametros.Controle.MovVelocidadeSErvasPercent = (int)(nudVelocidadeSemErvas.Value);
|
||||||
Variaveis.OperacaoEmAndamento.Controle.RPM_Min = (int)(nudVelocidadeComErvas.Value);
|
Variaveis.OperacaoEmAndamento.Parametros.Controle.MovVelocidadeCErvasPercent = (int)(nudVelocidadeComErvas.Value);
|
||||||
Variaveis.OperacaoEmAndamento.Controle.Angulo_Max = (int)(nudAnguloMaximo.Value);
|
Variaveis.OperacaoEmAndamento.Parametros.Controle.DirAnguloMaximo = (int)(nudAnguloMaximo.Value);
|
||||||
Variaveis.OperacaoEmAndamento.Controle.Angulo_Min = (int)(nudAnguloMinimo.Value);
|
Variaveis.OperacaoEmAndamento.Parametros.Controle.DirVelocidadeMovimento = (int)(nudVelocidadeMP.Value);
|
||||||
Variaveis.OperacaoEmAndamento.Controle.VelocidadeMP = (int)(nudVelocidadeMP.Value);
|
|
||||||
Variaveis.OperacaoEmAndamento.tmrLogsInterval = (double)(nudTemposalvarlog.Value * 1000);
|
Variaveis.OperacaoEmAndamento.tmrLogsInterval = (double)(nudTemposalvarlog.Value * 1000);
|
||||||
Variaveis.OperacaoEmAndamento.DispAtu.Dados.QuantidadeBicos = (int)nudQtdBicos.Value;
|
Variaveis.OperacaoEmAndamento.Parametros.QtdBicos = (int)nudQtdBicos.Value;
|
||||||
Variaveis.OperacaoEmAndamento.QuantidadeCamerasSolo = (int)nudQtdCameras.Value;
|
Variaveis.OperacaoEmAndamento.Parametros.QtdCamerasSolo = (int)nudQtdCameras.Value;
|
||||||
Variaveis.OperacaoEmAndamento.CapacidadeReservatorio = (double)nudCapacidadereservatorio.Value;
|
Variaveis.OperacaoEmAndamento.Parametros.CapacidadeReservatorio = (double)nudCapacidadereservatorio.Value;
|
||||||
Variaveis.OperacaoEmAndamento.DispAtu.Dados.DensidadeHerbicida = Convert.ToDouble(txtDensidadeherbicida.Text.Replace(".", ","));
|
Variaveis.OperacaoEmAndamento.DispAtu.Dados.DensidadeHerbicida = Convert.ToDouble(txtDensidadeherbicida.Text.Replace(".", ","));
|
||||||
Variaveis.OperacaoEmAndamento.Controle.PercentualInicioPulverizacao = (double)(nudAtuarem.Value / 100);
|
Variaveis.OperacaoEmAndamento.Parametros.Controle.AtuPercentualInicioPulverizacao = (double)(nudAtuarem.Value / 100);
|
||||||
Variaveis.OperacaoEmAndamento.DispAtu.Dados.ScriptDeteccaoErvas = cmbScriptErvas.Text + ".py";
|
//Variaveis.OperacaoEmAndamento.Parametros.DispAtu.Dados.ScriptDeteccaoErvas = cmbScriptErvas.Text + ".py";
|
||||||
|
|
||||||
if (chbSalvar.Checked)
|
if (chbSalvar.Checked)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ namespace AgroBase.Forms
|
||||||
{
|
{
|
||||||
cmbTipoControleDirecional.Items.Clear();
|
cmbTipoControleDirecional.Items.Clear();
|
||||||
cmbTipoControleDirecional.Items.AddRange(Enum.GetNames(typeof(Enums.TiposControladorDirecional)));
|
cmbTipoControleDirecional.Items.AddRange(Enum.GetNames(typeof(Enums.TiposControladorDirecional)));
|
||||||
cmbTipoControleDirecional.SelectedIndex = (int)Variaveis.OperacaoEmAndamento.Controle.TipoControleDirecional;
|
cmbTipoControleDirecional.SelectedIndex = (int)Variaveis.OperacaoEmAndamento.Parametros.Controle.DirTipoMovimento;
|
||||||
|
|
||||||
cmbStatusCorredor.Items.Clear();
|
cmbStatusCorredor.Items.Clear();
|
||||||
cmbStatusCorredor.Items.AddRange(Enum.GetNames(typeof(Enums.StatusCarroMapa)));
|
cmbStatusCorredor.Items.AddRange(Enum.GetNames(typeof(Enums.StatusCarroMapa)));
|
||||||
|
|
@ -116,9 +116,15 @@ namespace AgroBase.Forms
|
||||||
return;
|
return;
|
||||||
AtualizandoTela = true;
|
AtualizandoTela = true;
|
||||||
|
|
||||||
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
|
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura;
|
||||||
var _Trajetoria = Variaveis.OperacaoEmAndamento.Trajetoria;
|
var _Trajetoria = Variaveis.OperacaoEmAndamento.Trajetoria;
|
||||||
|
|
||||||
|
if (_Trajetoria == null)
|
||||||
|
{
|
||||||
|
AtualizandoTela = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
lblStatusOperacao.Text = "Operação: " + Enum.GetName(typeof(StatusOperacao), _Sensoriamento.StatusOperacao);
|
lblStatusOperacao.Text = "Operação: " + Enum.GetName(typeof(StatusOperacao), _Sensoriamento.StatusOperacao);
|
||||||
lblTipoMovimento.Text = _Sensoriamento.Controle.TipoMovimento.ToString();
|
lblTipoMovimento.Text = _Sensoriamento.Controle.TipoMovimento.ToString();
|
||||||
|
|
||||||
|
|
@ -257,12 +263,12 @@ namespace AgroBase.Forms
|
||||||
// Obtém os parâmetros
|
// Obtém os parâmetros
|
||||||
double anguloAtual = double.Parse(txtAnguloGPS.Text);
|
double anguloAtual = double.Parse(txtAnguloGPS.Text);
|
||||||
|
|
||||||
var _Gps = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps;
|
var _Gps = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps;
|
||||||
|
|
||||||
double anguloControle = 0.0;
|
double anguloControle = 0.0;
|
||||||
TipoMovimentoDirecional tipoMovimento = Variaveis.OperacaoEmAndamento.Controle.TipoMovimento;
|
TipoMovimentoDirecional tipoMovimento = Variaveis.OperacaoEmAndamento.Controle.TipoMovimento;
|
||||||
|
|
||||||
var tipoControle = Variaveis.OperacaoEmAndamento.Controle.TipoControleDirecional;
|
var tipoControle = Variaveis.OperacaoEmAndamento.Parametros.Controle.DirTipoMovimento;
|
||||||
|
|
||||||
if (passosOperacao.Count > 0 && Variaveis.OperacaoEmAndamento.Simulando)
|
if (passosOperacao.Count > 0 && Variaveis.OperacaoEmAndamento.Simulando)
|
||||||
{
|
{
|
||||||
|
|
@ -319,7 +325,7 @@ namespace AgroBase.Forms
|
||||||
|
|
||||||
AtualizarPosicaoGPS();
|
AtualizarPosicaoGPS();
|
||||||
|
|
||||||
Variaveis.OperacaoEmAndamento.Sensoriamento.AtualizarDados();
|
Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.AtualizarDados();
|
||||||
|
|
||||||
if (!chbAutomatico.Checked)
|
if (!chbAutomatico.Checked)
|
||||||
{
|
{
|
||||||
|
|
@ -434,8 +440,8 @@ namespace AgroBase.Forms
|
||||||
{
|
{
|
||||||
//double angulo = Variaveis.OperacaoEmAndamento.Trajetoria.AnguloCaminho;
|
//double angulo = Variaveis.OperacaoEmAndamento.Trajetoria.AnguloCaminho;
|
||||||
//double anguloCorredor = Variaveis.OperacaoEmAndamento.Trajetoria.AnguloMedioCorredor;
|
//double anguloCorredor = Variaveis.OperacaoEmAndamento.Trajetoria.AnguloMedioCorredor;
|
||||||
double angulo = Variaveis.OperacaoEmAndamento.Trajetoria.ProximoPonto?.Orientacao ?? 0;
|
double angulo = Variaveis.OperacaoEmAndamento.Trajetoria?.ProximoPonto?.Orientacao ?? 0;
|
||||||
double anguloCorredor = Variaveis.OperacaoEmAndamento.Trajetoria.AnguloCaminho;
|
double anguloCorredor = Variaveis.OperacaoEmAndamento.Trajetoria?.AnguloCaminho ?? 0;
|
||||||
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)angulo, 90, (float)anguloCorredor);
|
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)angulo, 90, (float)anguloCorredor);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
|
@ -445,7 +451,7 @@ namespace AgroBase.Forms
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
double angulo = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps?.AnguloCarroDefinido ?? 0;
|
double angulo = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura?.Gps?.AnguloCarroDefinido ?? 0;
|
||||||
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)angulo, 90);
|
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)angulo, 90);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
|
@ -456,7 +462,7 @@ namespace AgroBase.Forms
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
double angulo = Variaveis.OperacaoEmAndamento.SimulacaoAnguloControle;
|
double angulo = Variaveis.OperacaoEmAndamento.SimulacaoAnguloControle;
|
||||||
double dif = Variaveis.OperacaoEmAndamento.Sensoriamento.Trajetoria?.ErroOrientacaoAngularProximoPonto ?? 0;
|
double dif = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura?.Trajetoria?.ErroOrientacaoAngularProximoPonto ?? 0;
|
||||||
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)angulo, 90, (float)dif);
|
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)angulo, 90, (float)dif);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
|
@ -500,7 +506,7 @@ namespace AgroBase.Forms
|
||||||
|
|
||||||
private void cmbTipoControleDirecional_SelectedIndexChanged(object sender, EventArgs e)
|
private void cmbTipoControleDirecional_SelectedIndexChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Variaveis.OperacaoEmAndamento.Controle.TipoControleDirecional = (TiposControladorDirecional)cmbTipoControleDirecional.SelectedIndex;
|
Variaveis.OperacaoEmAndamento.Parametros.Controle.DirTipoMovimento = (TiposControladorDirecional)cmbTipoControleDirecional.SelectedIndex;
|
||||||
RedisService.AtualizarCampos(CtxKey.DadosOperacao, ("configurado", false));
|
RedisService.AtualizarCampos(CtxKey.DadosOperacao, ("configurado", false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ namespace AgroBase.Forms.Simuladores
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
OAKCameraFrameModel frame = await VisualWorkerService.GetCameraFrame(CameraFrameType.Segmentacao);
|
OAKCameraFrameModel frame = await VisualWorkerService.GetCameraFrame(CameraFrameType.Segmentacao);
|
||||||
var dadosSeg = Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorVisual.Analises.segmentacao;
|
var dadosSeg = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.OperadorVisual.Analises.segmentacao;
|
||||||
DesenharCorredor(frame?.image(), dadosSeg.centros_corredor, dadosSeg.width, dadosSeg.height, 80);
|
DesenharCorredor(frame?.image(), dadosSeg.centros_corredor, dadosSeg.width, dadosSeg.height, 80);
|
||||||
|
|
||||||
this.Invoke((MethodInvoker)(() =>
|
this.Invoke((MethodInvoker)(() =>
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,7 @@ namespace AgroBase.Forms
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
double angulo = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.AnguloCarroDefinido;
|
double angulo = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps.AnguloCarroDefinido;
|
||||||
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)angulo, 90);
|
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)angulo, 90);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
|
@ -476,7 +476,7 @@ namespace AgroBase.Forms
|
||||||
{
|
{
|
||||||
Latitude = GPSService.UltimaLeitura.Latitude,
|
Latitude = GPSService.UltimaLeitura.Latitude,
|
||||||
Longitude = GPSService.UltimaLeitura.Longitude,
|
Longitude = GPSService.UltimaLeitura.Longitude,
|
||||||
Orientation = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.AnguloCarroDefinido
|
Orientation = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps.AnguloCarroDefinido
|
||||||
});
|
});
|
||||||
_robotState.UpdateCurrentRobotState();
|
_robotState.UpdateCurrentRobotState();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,9 +69,9 @@ namespace AgroBase.Forms
|
||||||
AtualizarDadosSensorCorrente("AB36V", lblB36V);
|
AtualizarDadosSensorCorrente("AB36V", lblB36V);
|
||||||
}
|
}
|
||||||
|
|
||||||
lblMagnetometro.ForeColor = Variaveis.OperacaoEmAndamento.Sensoriamento.IMU.Iniciado ? Color.Green : Color.Red;
|
lblMagnetometro.ForeColor = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.IMU.Iniciado ? Color.Green : Color.Red;
|
||||||
|
|
||||||
var Gps = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps;
|
var Gps = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps;
|
||||||
lblGPS.ForeColor = Gps.Inicializado ? Color.Green : Color.Red;
|
lblGPS.ForeColor = Gps.Inicializado ? Color.Green : Color.Red;
|
||||||
if (Gps.Inicializado)
|
if (Gps.Inicializado)
|
||||||
{
|
{
|
||||||
|
|
@ -395,7 +395,7 @@ namespace AgroBase.Forms
|
||||||
|
|
||||||
private void pnlOrientacaoGPS_Paint(object sender, PaintEventArgs e)
|
private void pnlOrientacaoGPS_Paint(object sender, PaintEventArgs e)
|
||||||
{
|
{
|
||||||
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
|
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura;
|
||||||
double Angulo = _Sensoriamento.Gps.OrientacaoReal;
|
double Angulo = _Sensoriamento.Gps.OrientacaoReal;
|
||||||
double AnguloMovimento = _Sensoriamento.Gps.OrientacaoMovimento;
|
double AnguloMovimento = _Sensoriamento.Gps.OrientacaoMovimento;
|
||||||
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)Angulo, -90, (float)AnguloMovimento);
|
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)Angulo, -90, (float)AnguloMovimento);
|
||||||
|
|
@ -403,7 +403,7 @@ namespace AgroBase.Forms
|
||||||
|
|
||||||
private void pnlOrientacaoMagnetometro_Paint(object sender, PaintEventArgs e)
|
private void pnlOrientacaoMagnetometro_Paint(object sender, PaintEventArgs e)
|
||||||
{
|
{
|
||||||
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
|
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura;
|
||||||
double Angulo = _Sensoriamento.IMU.Rotacao;
|
double Angulo = _Sensoriamento.IMU.Rotacao;
|
||||||
double AnguloCorrigido = _Sensoriamento.IMU.RotacaoCorrigida;
|
double AnguloCorrigido = _Sensoriamento.IMU.RotacaoCorrigida;
|
||||||
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)Angulo, -90, (float)AnguloCorrigido);
|
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)Angulo, -90, (float)AnguloCorrigido);
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ namespace AgroBase.Forms
|
||||||
|
|
||||||
private async Task tmrLeitura_Tick()
|
private async Task tmrLeitura_Tick()
|
||||||
{
|
{
|
||||||
var Gps = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps;
|
var Gps = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps;
|
||||||
|
|
||||||
lblAltitude.Text = "Altitude: " + Gps.Altitude.ToString("0.0") + " m";
|
lblAltitude.Text = "Altitude: " + Gps.Altitude.ToString("0.0") + " m";
|
||||||
lblDatahora.Text = "Ultima Leitura: " + Gps.DataHora.ToString("HH:mm:ss");
|
lblDatahora.Text = "Ultima Leitura: " + Gps.DataHora.ToString("HH:mm:ss");
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ namespace AgroBase.Forms
|
||||||
|
|
||||||
private void btnRegistrarPontos_Click(object sender, EventArgs e)
|
private void btnRegistrarPontos_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
GPSModel P1 = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.Clone();
|
GPSModel P1 = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps.Clone();
|
||||||
|
|
||||||
if (Pontos[idxRua].Count == 0)
|
if (Pontos[idxRua].Count == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -127,8 +127,8 @@ namespace AgroBase.Forms
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
double angulo = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.AnguloCarroDefinido;
|
double angulo = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps.AnguloCarroDefinido;
|
||||||
double anguloCorredor = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.OrientacaoMovimento;
|
double anguloCorredor = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps.OrientacaoMovimento;
|
||||||
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)angulo, 90, (float)anguloCorredor);
|
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)angulo, 90, (float)anguloCorredor);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
|
@ -180,7 +180,7 @@ namespace AgroBase.Forms
|
||||||
ultimoPonto = Pontos[Pontos.Count - 2][Pontos[Pontos.Count - 2].Count - 1];
|
ultimoPonto = Pontos[Pontos.Count - 2][Pontos[Pontos.Count - 2].Count - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
var Gps = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps;
|
var Gps = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps;
|
||||||
|
|
||||||
pnlOrientacaoGps.Invalidate();
|
pnlOrientacaoGps.Invalidate();
|
||||||
lblStatusGPS.Text = $"GPS - Precisão: {Gps.PrecisaoCm} cm, " +
|
lblStatusGPS.Text = $"GPS - Precisão: {Gps.PrecisaoCm} cm, " +
|
||||||
|
|
|
||||||
|
|
@ -172,7 +172,7 @@ namespace AgroBase
|
||||||
|
|
||||||
tkbVelocidade.Minimum = 0;
|
tkbVelocidade.Minimum = 0;
|
||||||
tkbVelocidade.Maximum = 100;
|
tkbVelocidade.Maximum = 100;
|
||||||
FuncoesGlobais.PreencheValorTrackBar(tkbVelocidade, Variaveis.OperacaoEmAndamento.Controle.VelocidadeMP);
|
FuncoesGlobais.PreencheValorTrackBar(tkbVelocidade, Variaveis.OperacaoEmAndamento.Parametros.Controle.DirVelocidadeMovimento);
|
||||||
|
|
||||||
tkbAngulo.Minimum = 0;
|
tkbAngulo.Minimum = 0;
|
||||||
tkbAngulo.Maximum = 90;
|
tkbAngulo.Maximum = 90;
|
||||||
|
|
@ -181,7 +181,7 @@ namespace AgroBase
|
||||||
trkKmh.Minimum = 0;
|
trkKmh.Minimum = 0;
|
||||||
trkKmh.Maximum = 100;
|
trkKmh.Maximum = 100;
|
||||||
|
|
||||||
trkRPM.Minimum = Variaveis.OperacaoEmAndamento.Controle.RPM_Min;
|
trkRPM.Minimum = Variaveis.OperacaoEmAndamento.Parametros.Controle.MovVelocidadeCErvasPercent;
|
||||||
trkRPM.Maximum = VariaveisEquipamento.RPM_Max_Roda;
|
trkRPM.Maximum = VariaveisEquipamento.RPM_Max_Roda;
|
||||||
|
|
||||||
AtualizaRPM((int)Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeSP);
|
AtualizaRPM((int)Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeSP);
|
||||||
|
|
@ -267,8 +267,8 @@ namespace AgroBase
|
||||||
|
|
||||||
private void tkbVelocidadeMP_ValueChanged(object sender, EventArgs e)
|
private void tkbVelocidadeMP_ValueChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Variaveis.OperacaoEmAndamento.Controle.VelocidadeMP = tkbVelocidade.Value;
|
Variaveis.OperacaoEmAndamento.Parametros.Controle.DirVelocidadeMovimento = tkbVelocidade.Value;
|
||||||
lblVelocidade.Text = "Velocidade: " + Variaveis.OperacaoEmAndamento.Controle.VelocidadeMP + "%";
|
lblVelocidade.Text = "Velocidade: " + Variaveis.OperacaoEmAndamento.Parametros.Controle.DirVelocidadeMovimento + "%";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tkbAngulo_ValueChanged(object sender, EventArgs e)
|
private void tkbAngulo_ValueChanged(object sender, EventArgs e)
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ namespace AgroBase.Forms
|
||||||
|
|
||||||
private async Task tmrLeitura_Tick()
|
private async Task tmrLeitura_Tick()
|
||||||
{
|
{
|
||||||
var Imu = Variaveis.OperacaoEmAndamento.Sensoriamento.IMU;
|
var Imu = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.IMU;
|
||||||
AnguloX = Imu.InclinacaoFrontal;
|
AnguloX = Imu.InclinacaoFrontal;
|
||||||
AnguloY = Imu.InclinacaoLateral;
|
AnguloY = Imu.InclinacaoLateral;
|
||||||
AnguloZ = Imu.Rotacao;
|
AnguloZ = Imu.Rotacao;
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,8 @@
|
||||||
Aguardando = 3,
|
Aguardando = 3,
|
||||||
EmAndamento = 4,
|
EmAndamento = 4,
|
||||||
Parado = 5,
|
Parado = 5,
|
||||||
Concluido = 6
|
Concluido = 6,
|
||||||
|
Erro = 7
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum StatusCarroMapa
|
public enum StatusCarroMapa
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,8 @@ namespace AgroBase.Models
|
||||||
public DateTime UltimoComandoRespondido { get; set; }
|
public DateTime UltimoComandoRespondido { get; set; }
|
||||||
public double AnguloCarroDefinido { get; set; }
|
public double AnguloCarroDefinido { get; set; }
|
||||||
public int Heartbeat { get; set; } = 0;
|
public int Heartbeat { get; set; } = 0;
|
||||||
|
public double LeverArmLateral { get; set; } = 0;
|
||||||
|
public double LeverArmFrontal { get; set; } = 0;
|
||||||
|
|
||||||
public GPSModel Clone()
|
public GPSModel Clone()
|
||||||
{
|
{
|
||||||
|
|
@ -105,6 +107,10 @@ namespace AgroBase.Models
|
||||||
PDOP = PDOP,
|
PDOP = PDOP,
|
||||||
VDOP = VDOP,
|
VDOP = VDOP,
|
||||||
BaseID = BaseID,
|
BaseID = BaseID,
|
||||||
|
LeverArmFrontal = LeverArmFrontal,
|
||||||
|
LeverArmLateral = LeverArmLateral,
|
||||||
|
X = X,
|
||||||
|
Y = Y
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -826,7 +826,7 @@ namespace AgroBase
|
||||||
private static bool VerificaComandoValidoSonar(Keys Comando)
|
private static bool VerificaComandoValidoSonar(Keys Comando)
|
||||||
{
|
{
|
||||||
List<Keys> ComandosImpedidos = new List<Keys>();
|
List<Keys> ComandosImpedidos = new List<Keys>();
|
||||||
var Sonar = Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorVisual;
|
var Sonar = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.OperadorVisual;
|
||||||
Sonar?.Resumo?.AtualizarStatusBloqueio(false);
|
Sonar?.Resumo?.AtualizarStatusBloqueio(false);
|
||||||
var DeveParar = Sonar?.Resumo?.DeveParar ?? false;
|
var DeveParar = Sonar?.Resumo?.DeveParar ?? false;
|
||||||
if (DeveParar)
|
if (DeveParar)
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ public class MPCController
|
||||||
|
|
||||||
public async Task EnviarDadosTrajetoria(List<PontoTrajetoriaModel> _trajetoria)
|
public async Task EnviarDadosTrajetoria(List<PontoTrajetoriaModel> _trajetoria)
|
||||||
{
|
{
|
||||||
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
|
var pControle = Variaveis.OperacaoEmAndamento.Parametros.Controle;
|
||||||
|
|
||||||
var trajetoria = new
|
var trajetoria = new
|
||||||
{
|
{
|
||||||
|
|
@ -78,10 +78,10 @@ public class MPCController
|
||||||
})
|
})
|
||||||
.ToList(),
|
.ToList(),
|
||||||
horizonte = Horizonte,
|
horizonte = Horizonte,
|
||||||
angulo_max_graus = _Controle.Angulo_Max,
|
angulo_max_graus = pControle.DirAnguloMaximo,
|
||||||
distancia_entre_eixos = (VariaveisEquipamento.DistanciaEntreEixos / 100.0),
|
distancia_entre_eixos = (VariaveisEquipamento.DistanciaEntreEixos / 100.0),
|
||||||
velocidade_min = FuncoesMatematicas.CalculaVelocidadeMsPercentual(_Controle.PercentualVelocidadeMin),
|
velocidade_min = FuncoesMatematicas.CalculaVelocidadeMsPercentual(pControle.MovVelocidadeCErvasPercent),
|
||||||
velocidade_max = FuncoesMatematicas.CalculaVelocidadeMsPercentual(_Controle.PercentualVelocidadeMax)
|
velocidade_max = FuncoesMatematicas.CalculaVelocidadeMsPercentual(pControle.MovVelocidadeSErvasPercent)
|
||||||
};
|
};
|
||||||
|
|
||||||
await Variaveis.MqttServiceLocal.PublishAsync(
|
await Variaveis.MqttServiceLocal.PublishAsync(
|
||||||
|
|
@ -101,7 +101,7 @@ public class MPCController
|
||||||
_dt = (EnviadoEm - _ultimaAtualizacao).TotalSeconds;
|
_dt = (EnviadoEm - _ultimaAtualizacao).TotalSeconds;
|
||||||
double dtCalc = Math.Max(tempoMinimo, Math.Min(tempoMaximo, _dt));
|
double dtCalc = Math.Max(tempoMinimo, Math.Min(tempoMaximo, _dt));
|
||||||
|
|
||||||
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
|
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura;
|
||||||
|
|
||||||
var dadosEnvio = new
|
var dadosEnvio = new
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,10 @@ public class MPCControllerAprimorado
|
||||||
|
|
||||||
public MPCControllerAprimorado()
|
public MPCControllerAprimorado()
|
||||||
{
|
{
|
||||||
this.maxAnguloDirecao = Variaveis.OperacaoEmAndamento?.Controle?.Angulo_Max ?? 30.0;
|
this.maxAnguloDirecao = Variaveis.OperacaoEmAndamento.Parametros?.Controle?.DirAnguloMaximo ?? 30.0;
|
||||||
this.maxAngulo4Rodas = this.maxAnguloDirecao * 0.8;
|
this.maxAngulo4Rodas = this.maxAnguloDirecao * 0.8;
|
||||||
this.velocidadeMin = Variaveis.OperacaoEmAndamento?.Controle?.PercentualVelocidadeMin ?? 20.0;
|
this.velocidadeMin = Variaveis.OperacaoEmAndamento.Parametros?.Controle?.MovVelocidadeCErvasPercent ?? 20.0;
|
||||||
this.velocidadeMax = Variaveis.OperacaoEmAndamento?.Controle?.PercentualVelocidadeMax ?? 100.0;
|
this.velocidadeMax = Variaveis.OperacaoEmAndamento.Parametros?.Controle?.MovVelocidadeSErvasPercent ?? 100.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public (double anguloControle, Enums.TipoMovimentoDirecional modo) CalcularControle(GPSModel posicalAtual, double velocidadeAtual, List<GPSModel> proximaTrajetoria, Enums.TipoMovimentoDirecional[] modosPermitidos)
|
public (double anguloControle, Enums.TipoMovimentoDirecional modo) CalcularControle(GPSModel posicalAtual, double velocidadeAtual, List<GPSModel> proximaTrajetoria, Enums.TipoMovimentoDirecional[] modosPermitidos)
|
||||||
|
|
|
||||||
|
|
@ -28,10 +28,10 @@ public class MPCControllerSimple
|
||||||
{
|
{
|
||||||
// Definições baseadas em variáveis globais
|
// Definições baseadas em variáveis globais
|
||||||
this.horizon = Convert.ToInt32(distancePredict / TrajetoriaMapaOperacaoModel.DistanciaEntrePontos);
|
this.horizon = Convert.ToInt32(distancePredict / TrajetoriaMapaOperacaoModel.DistanciaEntrePontos);
|
||||||
this.maxSteeringAngle = Variaveis.OperacaoEmAndamento?.Controle?.Angulo_Max ?? 30.0;
|
this.maxSteeringAngle = Variaveis.OperacaoEmAndamento.Parametros.Controle?.DirAnguloMaximo ?? 30.0;
|
||||||
this.maxSteeringAngleFourWheels = this.maxSteeringAngle * 1.0;
|
this.maxSteeringAngleFourWheels = this.maxSteeringAngle * 1.0;
|
||||||
this.minVelocity = Variaveis.OperacaoEmAndamento?.Controle?.PercentualVelocidadeMin ?? 20.0;
|
this.minVelocity = Variaveis.OperacaoEmAndamento.Parametros.Controle?.MovVelocidadeCErvasPercent ?? 20.0;
|
||||||
this.maxVelocity = Variaveis.OperacaoEmAndamento?.Controle?.PercentualVelocidadeMax ?? 100.0;
|
this.maxVelocity = Variaveis.OperacaoEmAndamento.Parametros.Controle?.MovVelocidadeSErvasPercent ?? 100.0;
|
||||||
this.accelerationLimit = 1.5; // Limita aceleração a valores realistas
|
this.accelerationLimit = 1.5; // Limita aceleração a valores realistas
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,7 +52,7 @@ public class MPCControllerSimple
|
||||||
List<(double steering, Enums.TipoMovimentoDirecional mode)> candidates = GenerateControlCandidates();
|
List<(double steering, Enums.TipoMovimentoDirecional mode)> candidates = GenerateControlCandidates();
|
||||||
double bestCost = double.MaxValue;
|
double bestCost = double.MaxValue;
|
||||||
(double steeringAngle, Enums.TipoMovimentoDirecional mode) bestControl = (0, Enums.TipoMovimentoDirecional.RodasDianteiras);
|
(double steeringAngle, Enums.TipoMovimentoDirecional mode) bestControl = (0, Enums.TipoMovimentoDirecional.RodasDianteiras);
|
||||||
bool insideStreet = Variaveis.OperacaoEmAndamento.Sensoriamento.Trajetoria.CorredorAtual.Dentro;
|
bool insideStreet = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Trajetoria.CorredorAtual.Dentro;
|
||||||
|
|
||||||
double velocity = FuncoesMatematicas.CalculaVelocidadeMsPercentual(currentVelocity);
|
double velocity = FuncoesMatematicas.CalculaVelocidadeMsPercentual(currentVelocity);
|
||||||
double distanciaPasso = dt * velocity;
|
double distanciaPasso = dt * velocity;
|
||||||
|
|
|
||||||
|
|
@ -666,7 +666,7 @@ namespace AgroBase.Models
|
||||||
|
|
||||||
private void DrawObstacle(Graphics g, float xRobot, float yRobot, Color pointColor, Color borderColor, float angle, Obstaculo obstaculo, float PxToCm)
|
private void DrawObstacle(Graphics g, float xRobot, float yRobot, Color pointColor, Color borderColor, float angle, Obstaculo obstaculo, float PxToCm)
|
||||||
{
|
{
|
||||||
GPSModel posicaoRobo = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps;
|
GPSModel posicaoRobo = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps;
|
||||||
GPSModel posicaoObstaculo = GPSUtils.GerarPontoDeslocado(posicaoRobo, angle, obstaculo.DistanciaMedia_mm / 1000);
|
GPSModel posicaoObstaculo = GPSUtils.GerarPontoDeslocado(posicaoRobo, angle, obstaculo.DistanciaMedia_mm / 1000);
|
||||||
|
|
||||||
float x = xRobot + (float)((posicaoObstaculo.Longitude - posicaoRobo.Longitude) * _zoom);
|
float x = xRobot + (float)((posicaoObstaculo.Longitude - posicaoRobo.Longitude) * _zoom);
|
||||||
|
|
|
||||||
|
|
@ -157,10 +157,11 @@ namespace AgroBase.Models
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PopularTrajetoriaMapa()
|
public void PopularTrajetoriaMapa(MapaFeatureCollectionModel dados = null)
|
||||||
{
|
|
||||||
if (mapaService.DadosMapa != null)
|
|
||||||
{
|
{
|
||||||
|
if (dados != null) mapaService.DadosMapa = dados;
|
||||||
|
if (mapaService.DadosMapa == null) return;
|
||||||
|
|
||||||
double OrientacaoRuas = -999;
|
double OrientacaoRuas = -999;
|
||||||
//DistanciaTotal = 0;
|
//DistanciaTotal = 0;
|
||||||
/*if (!RuasPercorrer.Any())
|
/*if (!RuasPercorrer.Any())
|
||||||
|
|
@ -218,7 +219,6 @@ namespace AgroBase.Models
|
||||||
Variaveis.OperacaoEmAndamento.Trajetoria.ProjetarTrajetoriaFixa();
|
Variaveis.OperacaoEmAndamento.Trajetoria.ProjetarTrajetoriaFixa();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void IniciarProcessamento()
|
private void IniciarProcessamento()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ namespace AgroBase.Models.Modules
|
||||||
FuncoesPinout.SDA,
|
FuncoesPinout.SDA,
|
||||||
FuncoesPinout.SCL,
|
FuncoesPinout.SCL,
|
||||||
};
|
};
|
||||||
public int QuantidadeBicos { get; set; } = 4;
|
//public int QuantidadeBicos { get; set; } = 4;
|
||||||
public double DensidadeHerbicida { get; set; } = 1.0;
|
public double DensidadeHerbicida { get; set; } = 1.0;
|
||||||
public List<AtuadorBicoModel> BicosPulverizadores { get; set; } = new List<AtuadorBicoModel>();
|
public List<AtuadorBicoModel> BicosPulverizadores { get; set; } = new List<AtuadorBicoModel>();
|
||||||
public List<AtuadorBombaModel> BombasPressurizadoras { get; set; } = new List<AtuadorBombaModel>();
|
public List<AtuadorBombaModel> BombasPressurizadoras { get; set; } = new List<AtuadorBombaModel>();
|
||||||
|
|
@ -90,7 +90,7 @@ namespace AgroBase.Models.Modules
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return VolumeReservatorio / Variaveis.OperacaoEmAndamento.CapacidadeReservatorio * 100.0;
|
return VolumeReservatorio / Variaveis.OperacaoEmAndamento.Parametros.CapacidadeReservatorio * 100.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
@ -140,7 +140,7 @@ namespace AgroBase.Models.Modules
|
||||||
}
|
}
|
||||||
public void AtualizaPercentualErvas()
|
public void AtualizaPercentualErvas()
|
||||||
{
|
{
|
||||||
double tempoTotalOperacao = Variaveis.OperacaoEmAndamento.Sensoriamento.TempoDecorridoSeg * 1000.0;
|
double tempoTotalOperacao = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.TempoDecorridoSeg * 1000.0;
|
||||||
|
|
||||||
if (tempoTotalOperacao > 0)
|
if (tempoTotalOperacao > 0)
|
||||||
{
|
{
|
||||||
|
|
@ -225,7 +225,6 @@ namespace AgroBase.Models.Modules
|
||||||
_EnderecoCAN_Rx = 0x12,
|
_EnderecoCAN_Rx = 0x12,
|
||||||
_TaxaAmostragem = 1000,
|
_TaxaAmostragem = 1000,
|
||||||
RequisitarDados = true,
|
RequisitarDados = true,
|
||||||
QuantidadeBicos = 4,
|
|
||||||
BicosPulverizadores = new List<AtuadorBicoModel>(),
|
BicosPulverizadores = new List<AtuadorBicoModel>(),
|
||||||
BombasPressurizadoras = new List<AtuadorBombaModel>()
|
BombasPressurizadoras = new List<AtuadorBombaModel>()
|
||||||
{
|
{
|
||||||
|
|
@ -422,7 +421,7 @@ namespace AgroBase.Models.Modules
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
for (int i = 0; i < Atuador.QuantidadeBicos; i++)
|
for (int i = 0; i < Variaveis.OperacaoEmAndamento.Parametros.QtdBicos; i++)
|
||||||
{
|
{
|
||||||
int posicao = (i + 1);
|
int posicao = (i + 1);
|
||||||
Atuador.BicosPulverizadores.Add(new AtuadorBicoModel()
|
Atuador.BicosPulverizadores.Add(new AtuadorBicoModel()
|
||||||
|
|
@ -779,7 +778,7 @@ namespace AgroBase.Models.Modules
|
||||||
bomba.ComandoAtuar = false;
|
bomba.ComandoAtuar = false;
|
||||||
}
|
}
|
||||||
// Religa a bomba caso esteja desligada, o nivel de herbicida esta estavel e o pulverizador automatico esta ligado
|
// Religa a bomba caso esteja desligada, o nivel de herbicida esta estavel e o pulverizador automatico esta ligado
|
||||||
else if (PercentualReservatorio >= VariaveisEquipamento.PercentualReservatorioMin && leituraEstado == false && Variaveis.OperacaoEmAndamento.Controle.PulverizadorAutomatico)
|
else if (PercentualReservatorio >= VariaveisEquipamento.PercentualReservatorioMin && leituraEstado == false && Variaveis.OperacaoEmAndamento.Parametros.Controle.PulverizadorAutomatico)
|
||||||
{
|
{
|
||||||
bomba.ComandoAtuar = true;
|
bomba.ComandoAtuar = true;
|
||||||
}
|
}
|
||||||
|
|
@ -1077,7 +1076,7 @@ namespace AgroBase.Models.Modules
|
||||||
{
|
{
|
||||||
(byte)Componente,
|
(byte)Componente,
|
||||||
(byte)(conectar ? 1 : 0),
|
(byte)(conectar ? 1 : 0),
|
||||||
(byte)Variaveis.OperacaoEmAndamento.Controle.PressaoLinha,
|
(byte)Variaveis.OperacaoEmAndamento.Parametros.Controle.AtuPressaoLinha,
|
||||||
(byte)(pinout.Pinos.FirstOrDefault(x => x.ComponenteID == ID && x.Funcao == FuncoesPinout.ENA)?.Pino ?? PinoutUtils.PINO_INVALIDO),
|
(byte)(pinout.Pinos.FirstOrDefault(x => x.ComponenteID == ID && x.Funcao == FuncoesPinout.ENA)?.Pino ?? PinoutUtils.PINO_INVALIDO),
|
||||||
(byte)(pinout.Pinos.FirstOrDefault(x => x.Funcao == FuncoesPinout.CS)?.Pino ?? PinoutUtils.PINO_INVALIDO),
|
(byte)(pinout.Pinos.FirstOrDefault(x => x.Funcao == FuncoesPinout.CS)?.Pino ?? PinoutUtils.PINO_INVALIDO),
|
||||||
};
|
};
|
||||||
|
|
@ -1105,12 +1104,12 @@ namespace AgroBase.Models.Modules
|
||||||
new byte[]
|
new byte[]
|
||||||
{
|
{
|
||||||
(byte)(ComandoAtuar ? Estado.Ligado : Estado.Desligado),
|
(byte)(ComandoAtuar ? Estado.Ligado : Estado.Desligado),
|
||||||
(byte)(Variaveis.OperacaoEmAndamento.Controle.PressaoLinha)
|
(byte)(Variaveis.OperacaoEmAndamento.Parametros.Controle.AtuPressaoLinha)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AtingiuPressao() => Variaveis.OperacaoEmAndamento.DispAtu.Dados.PressaoLinha >= Variaveis.OperacaoEmAndamento.Controle.PressaoLinha;
|
public bool AtingiuPressao() => Variaveis.OperacaoEmAndamento.DispAtu.Dados.PressaoLinha >= Variaveis.OperacaoEmAndamento.Parametros.Controle.AtuPressaoLinha;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ namespace AgroBase.Models.Modules
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Convert.ToInt32(((Variaveis.OperacaoEmAndamento.Controle?.VelocidadeMP ?? 0) / 100.0) * Velocidade_Max);
|
return Convert.ToInt32(((Variaveis.OperacaoEmAndamento.Parametros?.Controle?.DirVelocidadeMovimento ?? 0) / 100.0) * Velocidade_Max);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -489,7 +489,7 @@ namespace AgroBase.Models.Modules
|
||||||
}
|
}
|
||||||
|
|
||||||
private double VelocidadeAtual =>
|
private double VelocidadeAtual =>
|
||||||
FuncoesMatematicas.CalculaVelocidadePercentualMs(Variaveis.OperacaoEmAndamento.Sensoriamento.Movimentacao?.VelocidadeMedia ?? 0);
|
FuncoesMatematicas.CalculaVelocidadePercentualMs(Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura?.Movimentacao?.VelocidadeMedia ?? 0);
|
||||||
|
|
||||||
private bool StatusControleEmFreio =>
|
private bool StatusControleEmFreio =>
|
||||||
(Variaveis.OperacaoEmAndamento.Controle?.TiposControle?
|
(Variaveis.OperacaoEmAndamento.Controle?.TiposControle?
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ using static AgroBase.Models.Enums;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using static AgroBase.Services.LoRaEspService;
|
using static AgroBase.Services.LoRaEspService;
|
||||||
using System.Windows.Forms;
|
|
||||||
using AgroBase.Services.Operadores;
|
using AgroBase.Services.Operadores;
|
||||||
using AgroBase.Models.Operadores;
|
using AgroBase.Models.Operadores;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
@ -1689,7 +1688,7 @@ namespace AgroBase.Models.Modules
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int i = 0; i < Variaveis.OperacaoEmAndamento.QuantidadeCamerasSolo; i++)
|
for (int i = 0; i < Variaveis.OperacaoEmAndamento.Parametros.QtdCamerasSolo; i++)
|
||||||
{
|
{
|
||||||
obj.CamerasSolo.Add(new OAKCameraModel());
|
obj.CamerasSolo.Add(new OAKCameraModel());
|
||||||
}
|
}
|
||||||
|
|
@ -2025,7 +2024,7 @@ namespace AgroBase.Models.Modules
|
||||||
GeneralJoystick.EnviarComandoSensoriamento(S_Code.sLED, ledOP.ID, comportamento);
|
GeneralJoystick.EnviarComandoSensoriamento(S_Code.sLED, ledOP.ID, comportamento);
|
||||||
}
|
}
|
||||||
|
|
||||||
var statusLedAt = Variaveis.OperacaoEmAndamento.Controle.MovimentoAutomatico ? StatusLED.Aceso : StatusLED.Apagado;
|
var statusLedAt = Variaveis.OperacaoEmAndamento.Parametros.Controle.MovimentoAutomatico ? StatusLED.Aceso : StatusLED.Apagado;
|
||||||
var valAt = (int?)(ledAT?.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.StatusLEDComando)?.atual?.valor) ?? 0;
|
var valAt = (int?)(ledAT?.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.StatusLEDComando)?.atual?.valor) ?? 0;
|
||||||
if (ledAT != null && (!ledAT.Comportamento.statusLED.Equals(statusLedAt) || (valAt != (int)statusLedAt)))
|
if (ledAT != null && (!ledAT.Comportamento.statusLED.Equals(statusLedAt) || (valAt != (int)statusLedAt)))
|
||||||
{
|
{
|
||||||
|
|
@ -2931,7 +2930,7 @@ namespace AgroBase.Models.Modules
|
||||||
{
|
{
|
||||||
case DadosLoRaParse.ComandoControle:
|
case DadosLoRaParse.ComandoControle:
|
||||||
{
|
{
|
||||||
Keys tecla = (Keys)data[2];
|
BotoesJoystick tecla = (BotoesJoystick)data[2];
|
||||||
int percentualVelocidadeSp = data[3];
|
int percentualVelocidadeSp = data[3];
|
||||||
TipoMovimentoDirecional tipoMovimentoDirecional = (TipoMovimentoDirecional)data[4];
|
TipoMovimentoDirecional tipoMovimentoDirecional = (TipoMovimentoDirecional)data[4];
|
||||||
int anguloMp = data[5];
|
int anguloMp = data[5];
|
||||||
|
|
@ -2939,15 +2938,17 @@ namespace AgroBase.Models.Modules
|
||||||
T_Code dispositivo = (T_Code)data[6];
|
T_Code dispositivo = (T_Code)data[6];
|
||||||
bool emergencia = data[7] == 1;
|
bool emergencia = data[7] == 1;
|
||||||
|
|
||||||
OperacaoControleBaseModel Controle = new OperacaoControleBaseModel()
|
OperacaoComandoBaseModel Controle = new OperacaoComandoBaseModel()
|
||||||
{
|
{
|
||||||
Momento = DateTime.Now,
|
Momento = DateTime.Now,
|
||||||
Tecla = tecla,
|
Tecla = tecla,
|
||||||
AnguloMP = anguloMp,
|
Controle = new OperacaoComandoBaseControleModel()
|
||||||
Emergencia = emergencia,
|
{
|
||||||
|
AnguloSP = anguloMp,
|
||||||
PercentualVelocidadeSP = percentualVelocidadeSp,
|
PercentualVelocidadeSP = percentualVelocidadeSp,
|
||||||
TipoMovimento = tipoMovimentoDirecional,
|
TipoMovimentoDirecional = tipoMovimentoDirecional,
|
||||||
//VelocidadeMP = velocidadeMp,
|
},
|
||||||
|
Emergencia = emergencia,
|
||||||
Dispositivo = dispositivo
|
Dispositivo = dispositivo
|
||||||
};
|
};
|
||||||
Variaveis.OperacaoEmAndamento.ExecutaComandoDaBase(Controle);
|
Variaveis.OperacaoEmAndamento.ExecutaComandoDaBase(Controle);
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -5,25 +5,55 @@ namespace AgroBase.Models.Operacoes
|
||||||
{
|
{
|
||||||
public class OperacaoParametrosModel
|
public class OperacaoParametrosModel
|
||||||
{
|
{
|
||||||
|
public string RoverId { get; set; }
|
||||||
|
public bool Alive { get; set; }
|
||||||
|
public bool Configurado { get; set; }
|
||||||
public ModoOperacao Modo { get; set; }
|
public ModoOperacao Modo { get; set; }
|
||||||
public string Descricao { get; set; }
|
public string Descricao { get; set; }
|
||||||
|
public int QtdCamerasSolo { get; set; }
|
||||||
|
public int QtdBicos { get; set; }
|
||||||
|
public double CapacidadeReservatorio { get; set; }
|
||||||
public List<OperacaoModulosMandatoriosModel> ModulosMandatorios { get; set; }
|
public List<OperacaoModulosMandatoriosModel> ModulosMandatorios { get; set; }
|
||||||
public List<OperacaoParametrosMandatoriosModel> ParametrosMandatorios { get; set; }
|
public List<OperacaoParametrosMandatoriosModel> ParametrosMandatorios { get; set; }
|
||||||
public int MovVelocidadeSErvasPercent { get; set; }
|
public OperacaoParametrosControleModel Controle { get; set; }
|
||||||
public int MovVelocidadeCErvasPercent { get; set; }
|
|
||||||
public int DirAnguloMaximo { get; set; }
|
public MapaFeatureCollectionModel Mapa { get; set; }
|
||||||
public int DirVelocidadeMovimento { get; set; }
|
public List<string> RuasPercorrer { get; set; }
|
||||||
public TiposControladorDirecional DirTipoMovimento { get; set; }
|
|
||||||
public int AtuPercentualDeteccaoVertical { get; set; }
|
public OperacaoSensoriamentoLogModel DadosLeitura { get; set; }
|
||||||
public double AtuCapacidadeReservatorio { get; set; }
|
}
|
||||||
public double AtuPressaoLinha { get; set; }
|
|
||||||
public int AtuDuracaoAtuacao { get; set; }
|
public class OperacaoParametrosControleModel
|
||||||
public MapasModel Mapa { get; set; }
|
{
|
||||||
public UltrasonicA05Configuracoes ConfiguracaoUltrassom { get; set; }
|
|
||||||
public bool SonarAtivado { get; set; }
|
public bool SonarAtivado { get; set; }
|
||||||
public int QtdCamerasSolo { get; set; }
|
|
||||||
public bool MovimentoAutomatico { get; set; }
|
public bool MovimentoAutomatico { get; set; }
|
||||||
public bool PulverizadorAutomatico { get; set; }
|
public bool PulverizadorAutomatico { get; set; }
|
||||||
public bool FrenagemAtuomatica { get; set; }
|
public bool FrenagemAutomatica { get; set; }
|
||||||
|
|
||||||
|
public int MovVelocidadeSErvasPercent { get; set; }
|
||||||
|
public int MovRpmMax
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return System.Convert.ToInt32(VariaveisEquipamento.RPM_Max_Roda * (MovVelocidadeSErvasPercent / 100.0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public int MovVelocidadeCErvasPercent { get; set; }
|
||||||
|
public int MovRpmMin
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return System.Convert.ToInt32(VariaveisEquipamento.RPM_Max_Roda * (MovVelocidadeCErvasPercent / 100.0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public int DirAnguloMaximo { get; set; }
|
||||||
|
public double DirVelocidadeMovimento { get; set; }
|
||||||
|
public TiposControladorDirecional DirTipoMovimento { get; set; }
|
||||||
|
public double AtuPressaoLinha { get; set; }
|
||||||
|
public int AtuDuracaoAtuacao { get; set; }
|
||||||
|
public double AtuPercentualInicioPulverizacao { get; set; }
|
||||||
|
public double AtuAlturaAreaPulverizacao { get; set; }
|
||||||
|
public double AtuPercentualErvasBicoOn { get; set; }
|
||||||
|
public double AtuPercentualErvasBicoOff { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,10 +61,10 @@ namespace AgroBase.Models.Operadores
|
||||||
|
|
||||||
public void AtualizarStatusBloqueio(bool consideraEmMovimento)
|
public void AtualizarStatusBloqueio(bool consideraEmMovimento)
|
||||||
{
|
{
|
||||||
var Sonar = Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorVisual;
|
var Sonar = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.OperadorVisual;
|
||||||
ObstaculoDetectado = (Sonar.Analises?.matriz_confianca?.block?.decision?.parar ?? false);
|
ObstaculoDetectado = (Sonar.Analises?.matriz_confianca?.block?.decision?.parar ?? false);
|
||||||
|
|
||||||
if (!Variaveis.OperacaoEmAndamento.Controle.SonarAtivado)
|
if (!Variaveis.OperacaoEmAndamento.Parametros.Controle.SonarAtivado)
|
||||||
{
|
{
|
||||||
_comandoParadaEnviado = false;
|
_comandoParadaEnviado = false;
|
||||||
DeveParar = false;
|
DeveParar = false;
|
||||||
|
|
|
||||||
|
|
@ -176,7 +176,7 @@ namespace AgroBase.Models
|
||||||
public void DetectarObstaculos(OAKDLiteSubdivisoesModel modelo)
|
public void DetectarObstaculos(OAKDLiteSubdivisoesModel modelo)
|
||||||
{
|
{
|
||||||
Subdivisoes = service.ConverterSubdivisoes(modelo);
|
Subdivisoes = service.ConverterSubdivisoes(modelo);
|
||||||
Obstaculos = service.IdentificarObstaculos(Subdivisoes, Variaveis.OperacaoEmAndamento.Controle.SonarAtivado);
|
Obstaculos = service.IdentificarObstaculos(Subdivisoes, Variaveis.OperacaoEmAndamento.Parametros.Controle.SonarAtivado);
|
||||||
|
|
||||||
AtualizarDadosObstaculos(modelo?.x_max ?? 640, modelo?.y_max ?? 480);
|
AtualizarDadosObstaculos(modelo?.x_max ?? 640, modelo?.y_max ?? 480);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -601,7 +601,7 @@ namespace AgroBase.Models
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return DistanciaMedia / FuncoesMatematicas.ConverteKmhParaMs(Variaveis.OperacaoEmAndamento.Sensoriamento.Movimentacao.VelocidadeMedia);
|
return DistanciaMedia / FuncoesMatematicas.ConverteKmhParaMs(Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Movimentacao.VelocidadeMedia);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public double DeslocamentoNecessarioDesvio
|
public double DeslocamentoNecessarioDesvio
|
||||||
|
|
@ -769,18 +769,18 @@ namespace AgroBase.Models
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
double anguloAbsolutoObstaculo = (Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.AnguloCarroDefinido + AnguloInicial + AnguloFinal) / 2.0;
|
double anguloAbsolutoObstaculo = (Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps.AnguloCarroDefinido + AnguloInicial + AnguloFinal) / 2.0;
|
||||||
double anguloRad = anguloAbsolutoObstaculo * (Math.PI / 180.0);
|
double anguloRad = anguloAbsolutoObstaculo * (Math.PI / 180.0);
|
||||||
|
|
||||||
// Supondo que a distância seja em metros e utilizando uma aproximação simples da Terra como esfera
|
// Supondo que a distância seja em metros e utilizando uma aproximação simples da Terra como esfera
|
||||||
// para converter distância e ângulo em mudança de latitude/longitude.
|
// para converter distância e ângulo em mudança de latitude/longitude.
|
||||||
double deltaLatitude = (DistanciaMedia * Math.Cos(anguloRad)) / 111111; // Dividindo por 111111 para converter metros em graus
|
double deltaLatitude = (DistanciaMedia * Math.Cos(anguloRad)) / 111111; // Dividindo por 111111 para converter metros em graus
|
||||||
double deltaLongitude = (DistanciaMedia * Math.Sin(anguloRad)) / (111111 * Math.Cos(Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.Latitude * (Math.PI / 180.0)));
|
double deltaLongitude = (DistanciaMedia * Math.Sin(anguloRad)) / (111111 * Math.Cos(Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps.Latitude * (Math.PI / 180.0)));
|
||||||
|
|
||||||
return new GPSModel
|
return new GPSModel
|
||||||
{
|
{
|
||||||
Latitude = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.Latitude + deltaLatitude,
|
Latitude = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps.Latitude + deltaLatitude,
|
||||||
Longitude = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.Longitude + deltaLongitude
|
Longitude = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps.Longitude + deltaLongitude
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,9 +36,9 @@ namespace AgroBase.Models
|
||||||
public double TempoEntreLeituras { get; private set; }
|
public double TempoEntreLeituras { get; private set; }
|
||||||
private void AtualizarTempoEntreLeituras()
|
private void AtualizarTempoEntreLeituras()
|
||||||
{
|
{
|
||||||
double dt = Math.Min((1.0 / GPSService.TaxaAmostragemHz), (UltimaAtualizacaoDados - Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.Momento).TotalSeconds);
|
double dt = Math.Min((1.0 / GPSService.TaxaAmostragemHz), (UltimaAtualizacaoDados - Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps.Momento).TotalSeconds);
|
||||||
TempoEntreLeituras = dt;
|
TempoEntreLeituras = dt;
|
||||||
UltimaAtualizacaoDados = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.Momento;
|
UltimaAtualizacaoDados = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps.Momento;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<List<GPSModel>> RuasPlantacao { get; set; }
|
public List<List<GPSModel>> RuasPlantacao { get; set; }
|
||||||
|
|
@ -81,8 +81,8 @@ namespace AgroBase.Models
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
double distPP = GPSUtils.DistanciaEntrePontos(Variaveis.OperacaoEmAndamento.Sensoriamento.Gps, PrimeiroPontoRuaMapa);
|
double distPP = GPSUtils.DistanciaEntrePontos(Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps, PrimeiroPontoRuaMapa);
|
||||||
double distUP = GPSUtils.DistanciaEntrePontos(Variaveis.OperacaoEmAndamento.Sensoriamento.Gps, UltimoPontoRuaMapa);
|
double distUP = GPSUtils.DistanciaEntrePontos(Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps, UltimoPontoRuaMapa);
|
||||||
|
|
||||||
// 0 para mais próximo do primeiro ponto da rua (ENTRANDO)
|
// 0 para mais próximo do primeiro ponto da rua (ENTRANDO)
|
||||||
// 1 para mais próximo do último ponto da rua (SAINDO)
|
// 1 para mais próximo do último ponto da rua (SAINDO)
|
||||||
|
|
@ -122,7 +122,7 @@ namespace AgroBase.Models
|
||||||
{
|
{
|
||||||
new PontoTrajetoriaModel(TipoPontoRua.PosicaoRobo)
|
new PontoTrajetoriaModel(TipoPontoRua.PosicaoRobo)
|
||||||
{
|
{
|
||||||
Posicao = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps,
|
Posicao = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps,
|
||||||
LarguraCorredor = 1.0,
|
LarguraCorredor = 1.0,
|
||||||
idxCorredor = CorredorAtual?.Idx ?? 0,
|
idxCorredor = CorredorAtual?.Idx ?? 0,
|
||||||
Visitado = true
|
Visitado = true
|
||||||
|
|
@ -215,7 +215,7 @@ namespace AgroBase.Models
|
||||||
private void AtualizarAnguloCaminho()
|
private void AtualizarAnguloCaminho()
|
||||||
{
|
{
|
||||||
PontoTrajetoriaModel pontoComparar = PontoAtual.Aproximando ? PontoAtual : ProximoPonto != null ? ProximoPonto : PontoAtual;
|
PontoTrajetoriaModel pontoComparar = PontoAtual.Aproximando ? PontoAtual : ProximoPonto != null ? ProximoPonto : PontoAtual;
|
||||||
AnguloCaminho = GPSUtils.CalcularOrientacao(Variaveis.OperacaoEmAndamento.Sensoriamento.Gps, pontoComparar.Posicao);
|
AnguloCaminho = GPSUtils.CalcularOrientacao(Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps, pontoComparar.Posicao);
|
||||||
}
|
}
|
||||||
[JsonProperty]
|
[JsonProperty]
|
||||||
public double DistanciaEsquerda { get; private set; }
|
public double DistanciaEsquerda { get; private set; }
|
||||||
|
|
@ -223,8 +223,8 @@ namespace AgroBase.Models
|
||||||
public double DistanciaDireita { get; private set; }
|
public double DistanciaDireita { get; private set; }
|
||||||
private void AtualizarDistanciasLaterais()
|
private void AtualizarDistanciasLaterais()
|
||||||
{
|
{
|
||||||
DistanciaEsquerda = CalcularDistanciaLateral(true, Variaveis.OperacaoEmAndamento.Sensoriamento.Gps, CorredorAtual?.idxRuaEsquerda ?? 0, PontoAtual?.Direcao ?? DirecaoCarroRua.Ida);
|
DistanciaEsquerda = CalcularDistanciaLateral(true, Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps, CorredorAtual?.idxRuaEsquerda ?? 0, PontoAtual?.Direcao ?? DirecaoCarroRua.Ida);
|
||||||
DistanciaDireita = CalcularDistanciaLateral(false, Variaveis.OperacaoEmAndamento.Sensoriamento.Gps, CorredorAtual?.idxRuaDireita ?? 0, PontoAtual?.Direcao ?? DirecaoCarroRua.Ida);
|
DistanciaDireita = CalcularDistanciaLateral(false, Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps, CorredorAtual?.idxRuaDireita ?? 0, PontoAtual?.Direcao ?? DirecaoCarroRua.Ida);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double CalcularDistanciaLateral(bool ladoEsquerdo, GPSModel posicaoAtual, int idxRua, DirecaoCarroRua direcaoAtual)
|
public double CalcularDistanciaLateral(bool ladoEsquerdo, GPSModel posicaoAtual, int idxRua, DirecaoCarroRua direcaoAtual)
|
||||||
|
|
@ -472,11 +472,11 @@ namespace AgroBase.Models
|
||||||
{
|
{
|
||||||
if (!velocidadeSemErvasMs.HasValue)
|
if (!velocidadeSemErvasMs.HasValue)
|
||||||
{
|
{
|
||||||
velocidadeSemErvasMs = FuncoesMatematicas.CalculaVelocidadeMsPercentual(Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeMax) * 0.8;
|
velocidadeSemErvasMs = FuncoesMatematicas.CalculaVelocidadeMsPercentual(Variaveis.OperacaoEmAndamento.Parametros.Controle.MovVelocidadeSErvasPercent) * 0.8;
|
||||||
}
|
}
|
||||||
if (!velocidadeComErvasMs.HasValue)
|
if (!velocidadeComErvasMs.HasValue)
|
||||||
{
|
{
|
||||||
velocidadeComErvasMs = FuncoesMatematicas.CalculaVelocidadeMsPercentual(Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeMin);
|
velocidadeComErvasMs = FuncoesMatematicas.CalculaVelocidadeMsPercentual(Variaveis.OperacaoEmAndamento.Parametros.Controle.MovVelocidadeCErvasPercent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Supondo que metade do percurso tem ervas e a outra metade não tem
|
// Supondo que metade do percurso tem ervas e a outra metade não tem
|
||||||
|
|
@ -527,12 +527,12 @@ namespace AgroBase.Models
|
||||||
if (CorredorAtual.Idx > 0) return;
|
if (CorredorAtual.Idx > 0) return;
|
||||||
if (!CorredorAtual.Dentro) return;
|
if (!CorredorAtual.Dentro) return;
|
||||||
|
|
||||||
GPSModel posicaoAtual = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.Clone();
|
GPSModel posicaoAtual = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps.Clone();
|
||||||
|
|
||||||
if (PrimeiroPontoDentroMapa == null) PrimeiroPontoDentroMapa = posicaoAtual;
|
if (PrimeiroPontoDentroMapa == null) PrimeiroPontoDentroMapa = posicaoAtual;
|
||||||
|
|
||||||
var OpVisual = Variaveis.OperacaoEmAndamento.Sensoriamento?.OperadorVisual ?? new VisualWorkerModel();
|
var OpVisual = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura?.OperadorVisual ?? new VisualWorkerModel();
|
||||||
StatusModulo OpVisualStatus = Variaveis.OperacaoEmAndamento.Sensoriamento.ModulosSaude.FirstOrDefault(x => x.modulo == T_Code.Snr)?.status ?? StatusModulo.Desconectado;
|
StatusModulo OpVisualStatus = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.ModulosSaude.FirstOrDefault(x => x.modulo == T_Code.Snr)?.status ?? StatusModulo.Desconectado;
|
||||||
|
|
||||||
if (OpVisualStatus != StatusModulo.Operante) return;
|
if (OpVisualStatus != StatusModulo.Operante) return;
|
||||||
|
|
||||||
|
|
@ -558,7 +558,7 @@ namespace AgroBase.Models
|
||||||
|
|
||||||
private void AtualizarErroCombinado()
|
private void AtualizarErroCombinado()
|
||||||
{
|
{
|
||||||
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
|
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura;
|
||||||
|
|
||||||
//double anguloCamera = _Sensoriamento.OperadorVisual.Leitura.obj?.segmentacao?.angulo_rua ?? 0;
|
//double anguloCamera = _Sensoriamento.OperadorVisual.Leitura.obj?.segmentacao?.angulo_rua ?? 0;
|
||||||
double anguloCorredor = AnguloMedioCorredor;
|
double anguloCorredor = AnguloMedioCorredor;
|
||||||
|
|
@ -575,7 +575,7 @@ namespace AgroBase.Models
|
||||||
double curvaDaRua = GPSUtils.CalcularDiferencaAngulo(anguloProximoPonto, anguloCorredor);
|
double curvaDaRua = GPSUtils.CalcularDiferencaAngulo(anguloProximoPonto, anguloCorredor);
|
||||||
|
|
||||||
// Peso do desalinhamento atual (prioriza alinhar o robô ao corredor)
|
// Peso do desalinhamento atual (prioriza alinhar o robô ao corredor)
|
||||||
double pesoAlinhamento = Math.Min(Math.Abs(desalinhamentoComRua) / Variaveis.OperacaoEmAndamento.Controle.Angulo_Max, 1.0); // Normaliza até 30°
|
double pesoAlinhamento = Math.Min(Math.Abs(desalinhamentoComRua) / Variaveis.OperacaoEmAndamento.Parametros.Controle.DirAnguloMaximo, 1.0); // Normaliza até 30°
|
||||||
|
|
||||||
// Peso do centro (prioriza ir pro ponto central do corredor)
|
// Peso do centro (prioriza ir pro ponto central do corredor)
|
||||||
double pesoCentro = 1.0 - pesoAlinhamento;
|
double pesoCentro = 1.0 - pesoAlinhamento;
|
||||||
|
|
@ -736,9 +736,9 @@ namespace AgroBase.Models
|
||||||
double limiarDistanciaMargem = DistanciaErroMapaPlantacao > -1 ? DistanciaErroMapaPlantacao : 5.0;
|
double limiarDistanciaMargem = DistanciaErroMapaPlantacao > -1 ? DistanciaErroMapaPlantacao : 5.0;
|
||||||
double distanciaCorredor = CorredorAtual.DistanciaTotal;
|
double distanciaCorredor = CorredorAtual.DistanciaTotal;
|
||||||
double distanciaRestanteCorredor = CorredorAtual.DistanciaRestante;
|
double distanciaRestanteCorredor = CorredorAtual.DistanciaRestante;
|
||||||
double distanciaUltimoPontoCorredor = GPSUtils.DistanciaEntrePontos(Variaveis.OperacaoEmAndamento.Sensoriamento.Gps, CorredorAtual.Pontos.LastOrDefault().Posicao);
|
double distanciaUltimoPontoCorredor = GPSUtils.DistanciaEntrePontos(Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps, CorredorAtual.Pontos.LastOrDefault().Posicao);
|
||||||
var OpVisual = Variaveis.OperacaoEmAndamento.Sensoriamento?.OperadorVisual ?? new VisualWorkerModel();
|
var OpVisual = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura?.OperadorVisual ?? new VisualWorkerModel();
|
||||||
StatusModulo OpVisualStatus = Variaveis.OperacaoEmAndamento.Sensoriamento.ModulosSaude.FirstOrDefault(x => x.modulo == T_Code.Snr)?.status ?? StatusModulo.Desconectado;
|
StatusModulo OpVisualStatus = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.ModulosSaude.FirstOrDefault(x => x.modulo == T_Code.Snr)?.status ?? StatusModulo.Desconectado;
|
||||||
var DadosSegmentacao = OpVisual.Analises?.segmentacao ?? new VisualWorkerMessageSegmentacaoSemanticaModel();
|
var DadosSegmentacao = OpVisual.Analises?.segmentacao ?? new VisualWorkerMessageSegmentacaoSemanticaModel();
|
||||||
|
|
||||||
if (OpVisualStatus == StatusModulo.Operante || Variaveis.OperacaoEmAndamento.Simulando) //OpVisual.Iniciado &&
|
if (OpVisualStatus == StatusModulo.Operante || Variaveis.OperacaoEmAndamento.Simulando) //OpVisual.Iniciado &&
|
||||||
|
|
@ -782,7 +782,7 @@ namespace AgroBase.Models
|
||||||
double anguloControle = Variaveis.OperacaoEmAndamento.Controle.Angulo;
|
double anguloControle = Variaveis.OperacaoEmAndamento.Controle.Angulo;
|
||||||
if (abrirCurva && !CorredorAtual.Ultimo)
|
if (abrirCurva && !CorredorAtual.Ultimo)
|
||||||
{
|
{
|
||||||
anguloControle = CorredorAtual.idxRuaDireita > CorredorAtual.idxRuaEsquerda ? Variaveis.OperacaoEmAndamento.Controle.Angulo_Min : Variaveis.OperacaoEmAndamento.Controle.Angulo_Max;
|
anguloControle = CorredorAtual.idxRuaDireita > CorredorAtual.idxRuaEsquerda ? -Variaveis.OperacaoEmAndamento.Parametros.Controle.DirAnguloMaximo : Variaveis.OperacaoEmAndamento.Parametros.Controle.DirAnguloMaximo;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pontosMarcar = 0;
|
int pontosMarcar = 0;
|
||||||
|
|
@ -812,7 +812,7 @@ namespace AgroBase.Models
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Angulo de controle definido de {Variaveis.OperacaoEmAndamento.Controle.Angulo} para {anguloControle}");
|
Console.WriteLine($"Angulo de controle definido de {Variaveis.OperacaoEmAndamento.Controle.Angulo} para {anguloControle}");
|
||||||
Variaveis.OperacaoEmAndamento.Controle.Angulo = anguloControle;
|
Variaveis.OperacaoEmAndamento.Controle.Angulo = anguloControle;
|
||||||
Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeSP = Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeMin;
|
Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeSP = Variaveis.OperacaoEmAndamento.Parametros.Controle.MovVelocidadeCErvasPercent;
|
||||||
Variaveis.OperacaoEmAndamento.Controle.TipoMovimento = TipoMovimentoDirecional.MovimentoArco;
|
Variaveis.OperacaoEmAndamento.Controle.TipoMovimento = TipoMovimentoDirecional.MovimentoArco;
|
||||||
Variaveis.OperacaoEmAndamento.Controle.TiposControle.FirstOrDefault(x => x.Tipo == T_Code.Dir).DelayEnvioComandoExtra = 1500;
|
Variaveis.OperacaoEmAndamento.Controle.TiposControle.FirstOrDefault(x => x.Tipo == T_Code.Dir).DelayEnvioComandoExtra = 1500;
|
||||||
Variaveis.OperacaoEmAndamento.Controle.TiposControle.FirstOrDefault(x => x.Tipo == T_Code.Mov).DelayEnvioComandoExtra = 2000;
|
Variaveis.OperacaoEmAndamento.Controle.TiposControle.FirstOrDefault(x => x.Tipo == T_Code.Mov).DelayEnvioComandoExtra = 2000;
|
||||||
|
|
@ -933,7 +933,7 @@ namespace AgroBase.Models
|
||||||
Console.WriteLine("Muito tempo sem receber novo comando do Manager Worker! Reduzindo Velocidade!");
|
Console.WriteLine("Muito tempo sem receber novo comando do Manager Worker! Reduzindo Velocidade!");
|
||||||
RedisService.AtualizarCampos(
|
RedisService.AtualizarCampos(
|
||||||
CtxKey.DadosControle,
|
CtxKey.DadosControle,
|
||||||
("velocidade_sp", _Controle.PercentualVelocidadeMin)
|
("velocidade_sp", Variaveis.OperacaoEmAndamento.Parametros.Controle.MovVelocidadeCErvasPercent)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1179,7 +1179,7 @@ namespace AgroBase.Models
|
||||||
idxCorredor = 0,
|
idxCorredor = 0,
|
||||||
idxPonto = 0,
|
idxPonto = 0,
|
||||||
idxPontoCorredor = 0,
|
idxPontoCorredor = 0,
|
||||||
Posicao = posicaoRobo ?? Variaveis.OperacaoEmAndamento.Sensoriamento.Gps,
|
Posicao = posicaoRobo ?? Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps,
|
||||||
Orientacao = 0,
|
Orientacao = 0,
|
||||||
Direcao = direcaoAtual,
|
Direcao = direcaoAtual,
|
||||||
Visitado = true,
|
Visitado = true,
|
||||||
|
|
@ -1478,7 +1478,7 @@ namespace AgroBase.Models
|
||||||
|
|
||||||
public void AjustarTrajetoriaParaDesvio(Obstaculo obstaculo)
|
public void AjustarTrajetoriaParaDesvio(Obstaculo obstaculo)
|
||||||
{
|
{
|
||||||
GPSModel posicaoAtual = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps;
|
GPSModel posicaoAtual = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps;
|
||||||
|
|
||||||
double distanciaObstaculo = ((double)obstaculo.DistanciaMedia_mm / 1000);
|
double distanciaObstaculo = ((double)obstaculo.DistanciaMedia_mm / 1000);
|
||||||
double larguraObstaculo = ((double)obstaculo.Largura_mm / 1000);
|
double larguraObstaculo = ((double)obstaculo.Largura_mm / 1000);
|
||||||
|
|
@ -1726,7 +1726,7 @@ namespace AgroBase.Models
|
||||||
|
|
||||||
private void AtualizarOrientacaoAtual()
|
private void AtualizarOrientacaoAtual()
|
||||||
{
|
{
|
||||||
OrientacaoAtual = GPSUtils.CalcularOrientacao(Variaveis.OperacaoEmAndamento.Sensoriamento.Gps, Posicao);
|
OrientacaoAtual = GPSUtils.CalcularOrientacao(Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps, Posicao);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AtualizarOrientacaoAnterior()
|
private void AtualizarOrientacaoAnterior()
|
||||||
|
|
@ -1780,7 +1780,7 @@ namespace AgroBase.Models
|
||||||
|
|
||||||
private void AtualizarDistanciaAtual()
|
private void AtualizarDistanciaAtual()
|
||||||
{
|
{
|
||||||
DistanciaAtual = GPSUtils.DistanciaEntrePontos(Variaveis.OperacaoEmAndamento.Sensoriamento.Gps, Posicao);
|
DistanciaAtual = GPSUtils.DistanciaEntrePontos(Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Gps, Posicao);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AtualizarDistanciaAnterior()
|
private void AtualizarDistanciaAnterior()
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ namespace AgroBase.Models
|
||||||
public static string CaminhoParametros { get; } = "Parametros/";
|
public static string CaminhoParametros { get; } = "Parametros/";
|
||||||
public static string CaminhoModelos { get; } = "C:\\AgroBaseModels\\";
|
public static string CaminhoModelos { get; } = "C:\\AgroBaseModels\\";
|
||||||
public static List<IDispositivosService> DispositivosConectados { get; set; } = new List<IDispositivosService>();
|
public static List<IDispositivosService> DispositivosConectados { get; set; } = new List<IDispositivosService>();
|
||||||
public static OperacaoModel OperacaoEmAndamento { get; set; } = new OperacaoModel(ModoOperacao.Manual);
|
public static OperacaoModel OperacaoEmAndamento { get; set; } = new OperacaoModel(ModoOperacao.MapaGPS);
|
||||||
public static MqttService MqttServiceLocal { get; set; }
|
public static MqttService MqttServiceLocal { get; set; }
|
||||||
public static MqttService MqttServiceBase { get; set; }
|
public static MqttService MqttServiceBase { get; set; }
|
||||||
public static LoRaEspService LoraService
|
public static LoRaEspService LoraService
|
||||||
|
|
@ -109,7 +109,7 @@ namespace AgroBase.Models
|
||||||
MqttServiceBase.Topicos.Clear();
|
MqttServiceBase.Topicos.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
MqttServiceLocal = new MqttService("localhost", 1883, IsAgroMonitor ? "base" : VariaveisEquipamento.Parametros.serial_number, true, msg => Console.WriteLine($"[MQTT localhost:{1883}] - {msg}"));
|
MqttServiceLocal = new MqttService("localhost", 1883, VariaveisEquipamento.Parametros.serial_number, true, msg => Console.WriteLine($"[MQTT localhost:{1883}] - {msg}"));
|
||||||
await MqttServiceLocal.AdicionarNovoTopico(MapasVariaveisModel.TopicoCoordenadasGPS);
|
await MqttServiceLocal.AdicionarNovoTopico(MapasVariaveisModel.TopicoCoordenadasGPS);
|
||||||
await MqttServiceLocal.AdicionarNovoTopico(MapasVariaveisModel.TopicoTrajetoriaDinamica);
|
await MqttServiceLocal.AdicionarNovoTopico(MapasVariaveisModel.TopicoTrajetoriaDinamica);
|
||||||
await MqttServiceLocal.AdicionarNovoTopico(MapasVariaveisModel.TopicoSelecaoRuasMapa, true, 1, async (message) =>
|
await MqttServiceLocal.AdicionarNovoTopico(MapasVariaveisModel.TopicoSelecaoRuasMapa, true, 1, async (message) =>
|
||||||
|
|
@ -120,14 +120,19 @@ namespace AgroBase.Models
|
||||||
MqttServiceBase = new MqttService(VariaveisEquipamento.Parametros.base_ip, 1883, VariaveisEquipamento.Parametros.serial_number, false, msg => Console.WriteLine($"[MQTT {VariaveisEquipamento.Parametros.base_ip}:{1883}] - {msg}"));
|
MqttServiceBase = new MqttService(VariaveisEquipamento.Parametros.base_ip, 1883, VariaveisEquipamento.Parametros.serial_number, false, msg => Console.WriteLine($"[MQTT {VariaveisEquipamento.Parametros.base_ip}:{1883}] - {msg}"));
|
||||||
await MqttServiceBase.AdicionarNovoTopico(VariaveisMonitoramento.TopicoMqttDispositivos);
|
await MqttServiceBase.AdicionarNovoTopico(VariaveisMonitoramento.TopicoMqttDispositivos);
|
||||||
await MqttServiceBase.AdicionarNovoTopico(VariaveisEquipamento.TopicoMqttTelemetria.Replace("<id>", VariaveisEquipamento.Parametros.serial_number));
|
await MqttServiceBase.AdicionarNovoTopico(VariaveisEquipamento.TopicoMqttTelemetria.Replace("<id>", VariaveisEquipamento.Parametros.serial_number));
|
||||||
|
await MqttServiceBase.AdicionarNovoTopico(VariaveisEquipamento.TopicoMqttParametros.Replace("<id>", VariaveisEquipamento.Parametros.serial_number));
|
||||||
|
await MqttServiceBase.AdicionarNovoTopico(VariaveisEquipamento.TopicoMqttHeartbeat.Replace("<id>", VariaveisEquipamento.Parametros.serial_number), true, 1, async (message) =>
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(message.Mensagem)) return;
|
||||||
|
VariaveisOperacao.PosicaoBase.UltimoComandoRespondido = DateTime.Now;
|
||||||
|
});
|
||||||
await MqttServiceBase.AdicionarNovoTopico(VariaveisEquipamento.TopicoMqttComandos.Replace("<id>", VariaveisEquipamento.Parametros.serial_number), true, 1, async (message) =>
|
await MqttServiceBase.AdicionarNovoTopico(VariaveisEquipamento.TopicoMqttComandos.Replace("<id>", VariaveisEquipamento.Parametros.serial_number), true, 1, async (message) =>
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(message.Mensagem))
|
if (string.IsNullOrEmpty(message.Mensagem)) return;
|
||||||
return;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string json = message.Mensagem;
|
string json = message.Mensagem;
|
||||||
var cmd = JsonConvert.DeserializeObject<OperacaoControleBaseModel>(json);
|
var cmd = JsonConvert.DeserializeObject<OperacaoComandoBaseModel>(json);
|
||||||
OperacaoEmAndamento.ExecutaComandoDaBase(cmd);
|
OperacaoEmAndamento.ExecutaComandoDaBase(cmd);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
@ -160,6 +165,7 @@ namespace AgroBase.Models
|
||||||
{
|
{
|
||||||
string json = message.Mensagem;
|
string json = message.Mensagem;
|
||||||
var posicao = JsonConvert.DeserializeObject<GPSModel>(json);
|
var posicao = JsonConvert.DeserializeObject<GPSModel>(json);
|
||||||
|
posicao.Momento = DateTime.Now;
|
||||||
VariaveisOperacao.PosicaoBase = posicao;
|
VariaveisOperacao.PosicaoBase = posicao;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
@ -197,15 +203,17 @@ namespace AgroBase.Models
|
||||||
_parametros = value;
|
_parametros = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public static string TopicoMqttHeartbeat { get; } = $"agrobot/v1/rover/<id>/heartbeat";
|
||||||
public static string TopicoMqttComandos { get; } = $"agrobot/v1/rover/<id>/cmd";
|
public static string TopicoMqttComandos { get; } = $"agrobot/v1/rover/<id>/cmd";
|
||||||
public static string TopicoMqttTelemetria { get; } = $"agrobot/v1/rover/<id>/telemetry";
|
public static string TopicoMqttTelemetria { get; } = $"agrobot/v1/rover/<id>/telemetry";
|
||||||
|
public static string TopicoMqttParametros { get; } = $"agrobot/v1/rover/<id>/parameters";
|
||||||
public static double LarguraEsquerda { get; } = 44.0; // 62
|
public static double LarguraEsquerda { get; } = 44.0; // 62
|
||||||
public static double LarguraDireita { get; } = 44.0; // 22
|
public static double LarguraDireita { get; } = 44.0; // 22
|
||||||
public static double ComprimentoFrente { get; } = 7.0; // 7
|
public static double ComprimentoFrente { get; } = 7.0; // 7
|
||||||
public static double ComprimentoTras { get; } = 107.0; // 107
|
public static double ComprimentoTras { get; } = 107.0; // 107
|
||||||
public static double LeverArmFrontal { get; } = 1.0;
|
|
||||||
public static double LeverArmLateral { get; } = 0.0;
|
|
||||||
public static double DistanciaEntreEixos { get; } = 92.0;
|
public static double DistanciaEntreEixos { get; } = 92.0;
|
||||||
|
public static double LeverArmFrontal { get; set; } = 100.0; // cm
|
||||||
|
public static double LeverArmLateral { get; set; } = 0.0; // cm
|
||||||
public static double LarguraEquipamentoMm
|
public static double LarguraEquipamentoMm
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
@ -219,6 +227,9 @@ namespace AgroBase.Models
|
||||||
public static double PercentualTensaoBateriaMin { get; set; } = 25.0;
|
public static double PercentualTensaoBateriaMin { get; set; } = 25.0;
|
||||||
public static double PercentualReservatorioMin { get; set; } = 8.0;
|
public static double PercentualReservatorioMin { get; set; } = 8.0;
|
||||||
public static double PercentualToleranciaPressaoLinha { get; set; } = 0.15;
|
public static double PercentualToleranciaPressaoLinha { get; set; } = 0.15;
|
||||||
|
public static int QuantidadeCamerasSolo { get; set; } = 1;
|
||||||
|
public static int QuantidadeBicosPulverizadores { get; set; } = 4;
|
||||||
|
public static double CapacidadeReservatorio { get; set; } = 30;
|
||||||
public static double ReducaoDirecional { get; set; } = 20.0;
|
public static double ReducaoDirecional { get; set; } = 20.0;
|
||||||
public static int RPM_Min_Roda { get; set; } = 15;
|
public static int RPM_Min_Roda { get; set; } = 15;
|
||||||
public static int RPM_Max_Roda
|
public static int RPM_Max_Roda
|
||||||
|
|
@ -554,6 +565,8 @@ namespace AgroBase.Models
|
||||||
public bool Carregado { get; set; }
|
public bool Carregado { get; set; }
|
||||||
public string serial_number { get; set; }
|
public string serial_number { get; set; }
|
||||||
public string base_ip { get; set; }
|
public string base_ip { get; set; }
|
||||||
|
public int base_porta_caminho { get; set; }
|
||||||
|
public int base_porta_ervas { get; set; }
|
||||||
|
|
||||||
public void AtualizarParametros()
|
public void AtualizarParametros()
|
||||||
{
|
{
|
||||||
|
|
@ -568,6 +581,8 @@ namespace AgroBase.Models
|
||||||
|
|
||||||
serial_number = par.serial_number;
|
serial_number = par.serial_number;
|
||||||
base_ip = par.base_ip;
|
base_ip = par.base_ip;
|
||||||
|
base_porta_caminho = par.base_porta_caminho;
|
||||||
|
base_porta_ervas = par.base_porta_ervas;
|
||||||
|
|
||||||
Carregado = true;
|
Carregado = true;
|
||||||
}
|
}
|
||||||
|
|
@ -590,7 +605,7 @@ namespace AgroBase.Models
|
||||||
{
|
{
|
||||||
if (!Variaveis.IsAgroMonitor && Variaveis.OperacaoEmAndamento.DispAtu != null)
|
if (!Variaveis.IsAgroMonitor && Variaveis.OperacaoEmAndamento.DispAtu != null)
|
||||||
{
|
{
|
||||||
return Variaveis.OperacaoEmAndamento.Sensoriamento.Atuador.PercentualErvasTerreno / 100.0;
|
return Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Atuador.PercentualErvasTerreno / 100.0;
|
||||||
}
|
}
|
||||||
return 0.3;
|
return 0.3;
|
||||||
}
|
}
|
||||||
|
|
@ -601,7 +616,7 @@ namespace AgroBase.Models
|
||||||
{
|
{
|
||||||
if (!Variaveis.IsAgroMonitor && Variaveis.OperacaoEmAndamento.DispAtu != null)
|
if (!Variaveis.IsAgroMonitor && Variaveis.OperacaoEmAndamento.DispAtu != null)
|
||||||
{
|
{
|
||||||
return (100.0 - Variaveis.OperacaoEmAndamento.Sensoriamento.Atuador.PercentualErvasTerreno) / 100.0;
|
return (100.0 - Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Atuador.PercentualErvasTerreno) / 100.0;
|
||||||
}
|
}
|
||||||
return 0.7;
|
return 0.7;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -217,7 +217,7 @@ namespace AgroMonitor
|
||||||
idxTick++;
|
idxTick++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async void EnviarDadosControle(string rover_id, OperacaoControleBaseModel controle)
|
public static async void EnviarDadosControle(string rover_id, OperacaoComandoBaseModel controle)
|
||||||
{
|
{
|
||||||
var topico = Variaveis.MqttServiceLocal.Topicos.FirstOrDefault(x => x.Topico == VariaveisEquipamento.TopicoMqttComandos.Replace("<id>", rover_id));
|
var topico = Variaveis.MqttServiceLocal.Topicos.FirstOrDefault(x => x.Topico == VariaveisEquipamento.TopicoMqttComandos.Replace("<id>", rover_id));
|
||||||
if (topico != null)
|
if (topico != null)
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ namespace AgroBase.Services
|
||||||
|
|
||||||
public void AtualizarConsumo()
|
public void AtualizarConsumo()
|
||||||
{
|
{
|
||||||
var Bateria = Variaveis.OperacaoEmAndamento.Sensoriamento.Bateria;
|
var Bateria = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Bateria;
|
||||||
|
|
||||||
if (!Bateria.Iniciado)
|
if (!Bateria.Iniciado)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -943,9 +943,13 @@ namespace AgroBase.Services
|
||||||
{
|
{
|
||||||
PenultimaLeitura.Ntrip_ativado = UltimaLeitura.Ntrip_ativado;
|
PenultimaLeitura.Ntrip_ativado = UltimaLeitura.Ntrip_ativado;
|
||||||
PenultimaLeitura.Heartbeat = UltimaLeitura.Heartbeat;
|
PenultimaLeitura.Heartbeat = UltimaLeitura.Heartbeat;
|
||||||
|
PenultimaLeitura.LeverArmFrontal = UltimaLeitura.LeverArmFrontal;
|
||||||
|
PenultimaLeitura.LeverArmLateral = UltimaLeitura.LeverArmLateral;
|
||||||
|
|
||||||
UltimaLeitura.Ntrip_ativado = CorrecaoRTK_Ntrip;
|
UltimaLeitura.Ntrip_ativado = CorrecaoRTK_Ntrip;
|
||||||
UltimaLeitura.Heartbeat = (UltimaLeitura.Heartbeat + 1) % 10;
|
UltimaLeitura.Heartbeat = (UltimaLeitura.Heartbeat + 1) % 10;
|
||||||
|
UltimaLeitura.LeverArmFrontal = VariaveisEquipamento.LeverArmFrontal;
|
||||||
|
UltimaLeitura.LeverArmLateral = VariaveisEquipamento.LeverArmLateral;
|
||||||
|
|
||||||
if (Variaveis.IsAgroMonitor)
|
if (Variaveis.IsAgroMonitor)
|
||||||
{
|
{
|
||||||
|
|
@ -1142,7 +1146,7 @@ namespace AgroBase.Services
|
||||||
{
|
{
|
||||||
double anguloFinal = 0.0;
|
double anguloFinal = 0.0;
|
||||||
|
|
||||||
bool imuIniciado = Variaveis.OperacaoEmAndamento.Sensoriamento.IMU?.Iniciado ?? false;
|
bool imuIniciado = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura?.IMU?.Iniciado ?? false;
|
||||||
bool gpsIniciado = Iniciado;
|
bool gpsIniciado = Iniciado;
|
||||||
|
|
||||||
if (imuIniciado)
|
if (imuIniciado)
|
||||||
|
|
@ -1162,7 +1166,7 @@ namespace AgroBase.Services
|
||||||
double heading = UltimaLeitura.OrientacaoReal;
|
double heading = UltimaLeitura.OrientacaoReal;
|
||||||
double angMov = UltimaLeitura.OrientacaoMovimento;
|
double angMov = UltimaLeitura.OrientacaoMovimento;
|
||||||
double distJan = UltimaLeitura.Distancia;
|
double distJan = UltimaLeitura.Distancia;
|
||||||
double velPercent = Variaveis.OperacaoEmAndamento.Simulando ? Variaveis.OperacaoEmAndamento.Controle.RPM_SP : Variaveis.OperacaoEmAndamento.Sensoriamento.Movimentacao?.RPMMedio ?? 0;
|
double velPercent = Variaveis.OperacaoEmAndamento.Simulando ? Variaveis.OperacaoEmAndamento.Controle.RPM_SP : Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura?.Movimentacao?.RPMMedio ?? 0;
|
||||||
bool rtkFix = UltimaLeitura.QualidadeFix == TiposCorrecaoGPS.RTKFixo;
|
bool rtkFix = UltimaLeitura.QualidadeFix == TiposCorrecaoGPS.RTKFixo;
|
||||||
double angAnterior = UltimaLeitura.AnguloCarroDefinido;
|
double angAnterior = UltimaLeitura.AnguloCarroDefinido;
|
||||||
|
|
||||||
|
|
@ -1173,7 +1177,7 @@ namespace AgroBase.Services
|
||||||
else if (imuIniciado)
|
else if (imuIniciado)
|
||||||
{
|
{
|
||||||
// Apenas o WT901C está disponível
|
// Apenas o WT901C está disponível
|
||||||
anguloFinal = Variaveis.OperacaoEmAndamento.Sensoriamento.IMU.RotacaoCorrigida;
|
anguloFinal = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.IMU.RotacaoCorrigida;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -1330,10 +1334,10 @@ namespace AgroBase.Services
|
||||||
|
|
||||||
public class GeoLeverArm
|
public class GeoLeverArm
|
||||||
{
|
{
|
||||||
public GeoLeverArm(double _xb = 0, double _yb = 0, bool _invH = false, bool _mirrL = false)
|
public GeoLeverArm(double _xbCm = 0, double _ybCm = 0, bool _invH = false, bool _mirrL = false)
|
||||||
{
|
{
|
||||||
xB = _xb;
|
xB = _xbCm / 100.0;
|
||||||
yB = _yb;
|
yB = _ybCm / 100.0;
|
||||||
invertHeading = _invH;
|
invertHeading = _invH;
|
||||||
mirrorLateral = _mirrL;
|
mirrorLateral = _mirrL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -624,7 +624,7 @@ namespace AgroBase.Services
|
||||||
|
|
||||||
public static Bitmap ExibirObstaculos(Bitmap bitmap, List<Subdivisao> subdivisoes, List<Obstaculo> obstaculos, bool ExibirTexto = false)
|
public static Bitmap ExibirObstaculos(Bitmap bitmap, List<Subdivisao> subdivisoes, List<Obstaculo> obstaculos, bool ExibirTexto = false)
|
||||||
{
|
{
|
||||||
if (bitmap == null || (!Variaveis.OperacaoEmAndamento.Controle.SonarAtivado && Variaveis.OperacaoEmAndamento.Iniciado))
|
if (bitmap == null || (!Variaveis.OperacaoEmAndamento.Parametros.Controle.SonarAtivado && Variaveis.OperacaoEmAndamento.Iniciado))
|
||||||
{
|
{
|
||||||
return bitmap;
|
return bitmap;
|
||||||
}
|
}
|
||||||
|
|
@ -968,7 +968,7 @@ namespace AgroBase.Services
|
||||||
|
|
||||||
private static List<Obstaculo> IdentificarObstaculos()
|
private static List<Obstaculo> IdentificarObstaculos()
|
||||||
{
|
{
|
||||||
if (!Variaveis.OperacaoEmAndamento.Controle.SonarAtivado || Parametros.Subdivisoes == null)
|
if (!Variaveis.OperacaoEmAndamento.Parametros.Controle.SonarAtivado || Parametros.Subdivisoes == null)
|
||||||
{
|
{
|
||||||
return new List<Obstaculo>();
|
return new List<Obstaculo>();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -682,7 +682,7 @@ namespace AgroBase.Services
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void EnviarDadosComandoControle(OperacaoControleBaseModel Controle, byte EnderecoDestinatario)
|
public static void EnviarDadosComandoControle(OperacaoComandoBaseModel Controle, byte EnderecoDestinatario)
|
||||||
{
|
{
|
||||||
if (Iniciado)
|
if (Iniciado)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ namespace AgroBase.Services
|
||||||
if (ageRxMs > beaconPeriodoMs + 2000) return;
|
if (ageRxMs > beaconPeriodoMs + 2000) return;
|
||||||
|
|
||||||
// --- ENVIO (ideal: agregue em 1-2 frames) ---
|
// --- ENVIO (ideal: agregue em 1-2 frames) ---
|
||||||
var s = Variaveis.OperacaoEmAndamento.Sensoriamento;
|
var s = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura;
|
||||||
|
|
||||||
foreach (var dado in LoRaSerializer.SerializeGPS(s.Gps))
|
foreach (var dado in LoRaSerializer.SerializeGPS(s.Gps))
|
||||||
Variaveis.LoraService?.EnviarDadosLoRaViaCAN(dado);
|
Variaveis.LoraService?.EnviarDadosLoRaViaCAN(dado);
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,7 @@ namespace AgroBase.Services
|
||||||
return (Endereco, model);
|
return (Endereco, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] SerializeControleModel(OperacaoControleBaseModel model)
|
public static byte[] SerializeControleModel(OperacaoComandoBaseModel model)
|
||||||
{
|
{
|
||||||
List<byte> bytes = new List<byte>();
|
List<byte> bytes = new List<byte>();
|
||||||
|
|
||||||
|
|
@ -174,26 +174,26 @@ namespace AgroBase.Services
|
||||||
bytes.AddRange(BitConverter.GetBytes((int)model.Dispositivo));
|
bytes.AddRange(BitConverter.GetBytes((int)model.Dispositivo));
|
||||||
|
|
||||||
// Serializar RPM
|
// Serializar RPM
|
||||||
bytes.AddRange(BitConverter.GetBytes(model.PercentualVelocidadeSP));
|
bytes.AddRange(BitConverter.GetBytes(model.Controle.PercentualVelocidadeSP));
|
||||||
|
|
||||||
// Serializar AnguloMP
|
// Serializar AnguloMP
|
||||||
bytes.AddRange(BitConverter.GetBytes(model.AnguloMP));
|
bytes.AddRange(BitConverter.GetBytes(model.Controle.AnguloSP));
|
||||||
|
|
||||||
// Serializar VelocidadeMP
|
// Serializar VelocidadeMP
|
||||||
bytes.AddRange(BitConverter.GetBytes(model.VelocidadeMP));
|
bytes.AddRange(BitConverter.GetBytes(model.Controle.VelocidadeMP));
|
||||||
|
|
||||||
// Serializar Emergencia
|
// Serializar Emergencia
|
||||||
bytes.AddRange(BitConverter.GetBytes(model.Emergencia));
|
bytes.AddRange(BitConverter.GetBytes(model.Emergencia));
|
||||||
|
|
||||||
// Serializar TipoMovimento (int)
|
// Serializar TipoMovimento (int)
|
||||||
bytes.AddRange(BitConverter.GetBytes((int)model.TipoMovimento));
|
bytes.AddRange(BitConverter.GetBytes((int)model.Controle.TipoMovimentoDirecional));
|
||||||
|
|
||||||
return bytes.ToArray();
|
return bytes.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static OperacaoControleBaseModel DeserializeControleModel(byte[] bytes)
|
public static OperacaoComandoBaseModel DeserializeControleModel(byte[] bytes)
|
||||||
{
|
{
|
||||||
OperacaoControleBaseModel model = new OperacaoControleBaseModel();
|
OperacaoComandoBaseModel model = new OperacaoComandoBaseModel();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
// Desserializar Momento (DateTime)
|
// Desserializar Momento (DateTime)
|
||||||
|
|
@ -201,7 +201,7 @@ namespace AgroBase.Services
|
||||||
index += sizeof(long);
|
index += sizeof(long);
|
||||||
|
|
||||||
// Desserializar Tecla (int)
|
// Desserializar Tecla (int)
|
||||||
model.Tecla = (Keys)BitConverter.ToInt32(bytes, index);
|
model.Tecla = (BotoesJoystick)BitConverter.ToInt32(bytes, index);
|
||||||
index += sizeof(int);
|
index += sizeof(int);
|
||||||
|
|
||||||
// Desserializar Dispositivo (int)
|
// Desserializar Dispositivo (int)
|
||||||
|
|
@ -209,15 +209,15 @@ namespace AgroBase.Services
|
||||||
index += sizeof(int);
|
index += sizeof(int);
|
||||||
|
|
||||||
// Desserializar RPM
|
// Desserializar RPM
|
||||||
model.PercentualVelocidadeSP = BitConverter.ToDouble(bytes, index);
|
model.Controle.PercentualVelocidadeSP = BitConverter.ToDouble(bytes, index);
|
||||||
index += sizeof(double);
|
index += sizeof(double);
|
||||||
|
|
||||||
// Desserializar AnguloMP
|
// Desserializar AnguloMP
|
||||||
model.AnguloMP = BitConverter.ToDouble(bytes, index);
|
model.Controle.AnguloSP = BitConverter.ToDouble(bytes, index);
|
||||||
index += sizeof(double);
|
index += sizeof(double);
|
||||||
|
|
||||||
// Desserializar VelocidadeMP
|
// Desserializar VelocidadeMP
|
||||||
model.VelocidadeMP = BitConverter.ToDouble(bytes, index);
|
model.Controle.VelocidadeMP = BitConverter.ToDouble(bytes, index);
|
||||||
index += sizeof(double);
|
index += sizeof(double);
|
||||||
|
|
||||||
// Desserializar Emergencia
|
// Desserializar Emergencia
|
||||||
|
|
@ -225,7 +225,7 @@ namespace AgroBase.Services
|
||||||
index += sizeof(bool);
|
index += sizeof(bool);
|
||||||
|
|
||||||
// Desserializar TipoMovimento (int)
|
// Desserializar TipoMovimento (int)
|
||||||
model.TipoMovimento = (TipoMovimentoDirecional)BitConverter.ToInt32(bytes, index);
|
model.Controle.TipoMovimentoDirecional = (TipoMovimentoDirecional)BitConverter.ToInt32(bytes, index);
|
||||||
index += sizeof(int);
|
index += sizeof(int);
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
|
|
@ -274,14 +274,14 @@ namespace AgroBase.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] SerializeComandoControle(OperacaoControleBaseModel Controle)
|
public static byte[] SerializeComandoControle(OperacaoComandoBaseModel Controle)
|
||||||
{
|
{
|
||||||
List<byte> dados = new List<byte>();
|
List<byte> dados = new List<byte>();
|
||||||
dados.AddRange(CanPrefix(DadosLoRaParse.ComandoControle));
|
dados.AddRange(CanPrefix(DadosLoRaParse.ComandoControle));
|
||||||
dados.Add((byte)Controle.Tecla); // 1 byte
|
dados.Add((byte)Controle.Tecla); // 1 byte
|
||||||
dados.Add((byte)Controle.PercentualVelocidadeSP); // 1 byte
|
dados.Add((byte)Controle.Controle.PercentualVelocidadeSP); // 1 byte
|
||||||
dados.Add((byte)Controle.TipoMovimento); // 1 byte
|
dados.Add((byte)Controle.Controle.TipoMovimentoDirecional); // 1 byte
|
||||||
dados.Add((byte)Controle.AnguloMP); // 1 byte
|
dados.Add((byte)Controle.Controle.AnguloSP); // 1 byte
|
||||||
//dados.Add((byte)Controle.VelocidadeMP); // 1 byte
|
//dados.Add((byte)Controle.VelocidadeMP); // 1 byte
|
||||||
dados.Add((byte)Controle.Dispositivo); // 1 byte
|
dados.Add((byte)Controle.Dispositivo); // 1 byte
|
||||||
dados.Add((byte)(Controle.Emergencia ? 1 : 0)); // 1 byte
|
dados.Add((byte)(Controle.Emergencia ? 1 : 0)); // 1 byte
|
||||||
|
|
@ -296,7 +296,8 @@ namespace AgroBase.Services
|
||||||
dados.Add((byte)Controle.PercentualVelocidadeSP); // 1 byte
|
dados.Add((byte)Controle.PercentualVelocidadeSP); // 1 byte
|
||||||
dados.Add((byte)Controle.TipoMovimento); // 1 byte
|
dados.Add((byte)Controle.TipoMovimento); // 1 byte
|
||||||
dados.Add((byte)Controle.Angulo); // 1 byte
|
dados.Add((byte)Controle.Angulo); // 1 byte
|
||||||
dados.Add((byte)Controle.VelocidadeMP); // 1 byte
|
//dados.Add((byte)Controle.VelocidadeMP); // 1 byte
|
||||||
|
dados.Add((byte)0); // 1 byte
|
||||||
return dados.ToArray();
|
return dados.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ namespace AgroBase.Services.Operadores
|
||||||
AtualizarDadosModulos();
|
AtualizarDadosModulos();
|
||||||
AtualizarDadosControleOperacao();
|
AtualizarDadosControleOperacao();
|
||||||
|
|
||||||
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
|
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura;
|
||||||
|
|
||||||
if (_Sensoriamento == null)
|
if (_Sensoriamento == null)
|
||||||
{
|
{
|
||||||
|
|
@ -165,6 +165,9 @@ namespace AgroBase.Services.Operadores
|
||||||
{
|
{
|
||||||
RedisService.AtualizarCampos(
|
RedisService.AtualizarCampos(
|
||||||
CtxKey.DadosEquipamento,
|
CtxKey.DadosEquipamento,
|
||||||
|
("base_ip", VariaveisEquipamento.Parametros.base_ip),
|
||||||
|
("base_porta_caminho", VariaveisEquipamento.Parametros.base_porta_caminho),
|
||||||
|
("base_porta_ervas", VariaveisEquipamento.Parametros.base_porta_ervas),
|
||||||
("largura", VariaveisEquipamento.LarguraEquipamentoMm / 1000.0),
|
("largura", VariaveisEquipamento.LarguraEquipamentoMm / 1000.0),
|
||||||
("distancia_entre_eixos", VariaveisEquipamento.DistanciaEntreEixos / 100.0),
|
("distancia_entre_eixos", VariaveisEquipamento.DistanciaEntreEixos / 100.0),
|
||||||
("percentual_reservatorio_min", VariaveisEquipamento.PercentualReservatorioMin),
|
("percentual_reservatorio_min", VariaveisEquipamento.PercentualReservatorioMin),
|
||||||
|
|
@ -195,6 +198,8 @@ namespace AgroBase.Services.Operadores
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _Parametros = Variaveis.OperacaoEmAndamento.Parametros;
|
||||||
|
var pControle = _Parametros.Controle;
|
||||||
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
|
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
|
||||||
|
|
||||||
RedisService.AtualizarCampos(
|
RedisService.AtualizarCampos(
|
||||||
|
|
@ -202,20 +207,20 @@ namespace AgroBase.Services.Operadores
|
||||||
("configurado", true),
|
("configurado", true),
|
||||||
("modo", Variaveis.OperacaoEmAndamento.Modo),
|
("modo", Variaveis.OperacaoEmAndamento.Modo),
|
||||||
("tempo_aguardar_inicio_operacao", Variaveis.OperacaoEmAndamento.TempoIniciarOperacao),
|
("tempo_aguardar_inicio_operacao", Variaveis.OperacaoEmAndamento.TempoIniciarOperacao),
|
||||||
("modulos_mandatorios", Variaveis.OperacaoEmAndamento.ModulosMandatorios.Where(x => x.Mandatorio && x.Utilizar).Select(x => (int)x.Dispositivo).ToArray()),
|
("modulos_mandatorios", _Parametros.ModulosMandatorios.Where(x => x.Mandatorio && x.Utilizar).Select(x => (int)x.Dispositivo).ToArray()),
|
||||||
("modulos_opcionais", Variaveis.OperacaoEmAndamento.ModulosMandatorios.Where(x => !x.Mandatorio && x.Utilizar).Select(x => (int)x.Dispositivo).ToArray()),
|
("modulos_opcionais", _Parametros.ModulosMandatorios.Where(x => !x.Mandatorio && x.Utilizar).Select(x => (int)x.Dispositivo).ToArray()),
|
||||||
("parametros_mandatorios", Variaveis.OperacaoEmAndamento.ParametrosMandatorios.Where(x => x.Mandatorio && x.Utilizar).Select(x => (int)x.Parametro).ToArray()),
|
("parametros_mandatorios", _Parametros.ParametrosMandatorios.Where(x => x.Mandatorio && x.Utilizar).Select(x => (int)x.Parametro).ToArray()),
|
||||||
("Mov", new
|
("Mov", new
|
||||||
{
|
{
|
||||||
percent_vel_max = _Controle.PercentualVelocidadeMax,
|
percent_vel_max = pControle.MovVelocidadeSErvasPercent,
|
||||||
percent_vel_min = _Controle.PercentualVelocidadeMin,
|
percent_vel_min = pControle.MovVelocidadeCErvasPercent,
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
("Dir", new
|
("Dir", new
|
||||||
{
|
{
|
||||||
angulo_max = _Controle.Angulo_Max,
|
angulo_max = pControle.DirAnguloMaximo,
|
||||||
vel_movimento = _Controle.VelocidadeMP,
|
vel_movimento = pControle.DirVelocidadeMovimento,
|
||||||
tipo_controle = (int)_Controle.TipoControleDirecional,
|
tipo_controle = (int)pControle.DirTipoMovimento,
|
||||||
mpc = new
|
mpc = new
|
||||||
{
|
{
|
||||||
pontos = Variaveis.OperacaoEmAndamento.Trajetoria?._TrajetoriaFixa?
|
pontos = Variaveis.OperacaoEmAndamento.Trajetoria?._TrajetoriaFixa?
|
||||||
|
|
@ -228,9 +233,9 @@ namespace AgroBase.Services.Operadores
|
||||||
})
|
})
|
||||||
.ToList(),
|
.ToList(),
|
||||||
horizonte = 2.5,
|
horizonte = 2.5,
|
||||||
angulo_max_graus = _Controle.Angulo_Max,
|
angulo_max_graus = pControle.DirAnguloMaximo,
|
||||||
velocidade_min = FuncoesMatematicas.CalculaVelocidadeMsPercentual(_Controle.PercentualVelocidadeMin),
|
velocidade_min = FuncoesMatematicas.CalculaVelocidadeMsPercentual(pControle.MovVelocidadeCErvasPercent),
|
||||||
velocidade_max = FuncoesMatematicas.CalculaVelocidadeMsPercentual(_Controle.PercentualVelocidadeMax),
|
velocidade_max = FuncoesMatematicas.CalculaVelocidadeMsPercentual(pControle.MovVelocidadeSErvasPercent),
|
||||||
tempo_entre_comandos = (Variaveis.OperacaoEmAndamento.Controle.TiposControle.FirstOrDefault(x => x.Tipo == Enums.T_Code.Dir)?.DelayEnvioComando ?? 500) / 1000.0,
|
tempo_entre_comandos = (Variaveis.OperacaoEmAndamento.Controle.TiposControle.FirstOrDefault(x => x.Tipo == Enums.T_Code.Dir)?.DelayEnvioComando ?? 500) / 1000.0,
|
||||||
passos_atraso = 1
|
passos_atraso = 1
|
||||||
}
|
}
|
||||||
|
|
@ -238,11 +243,14 @@ namespace AgroBase.Services.Operadores
|
||||||
),
|
),
|
||||||
("Atu", new
|
("Atu", new
|
||||||
{
|
{
|
||||||
qtd_bicos = Variaveis.OperacaoEmAndamento.DispAtu.Dados.QuantidadeBicos,
|
qtd_bicos = _Parametros.QtdBicos,
|
||||||
tempo_atuacao = _Controle.TempoAtuacao,
|
tempo_atuacao = pControle.AtuDuracaoAtuacao,
|
||||||
capacidade_reservatorio = Variaveis.OperacaoEmAndamento.CapacidadeReservatorio,
|
capacidade_reservatorio = _Parametros.CapacidadeReservatorio,
|
||||||
pressao_linha = _Controle.PressaoLinha,
|
pressao_linha = pControle.AtuPressaoLinha,
|
||||||
percent_vertical_deteccao = _Controle.PercentualInicioPulverizacao,
|
percent_vertical_deteccao = pControle.AtuPercentualInicioPulverizacao,
|
||||||
|
height_area_deteccao = pControle.AtuAlturaAreaPulverizacao,
|
||||||
|
pct_erva_bico_on = pControle.AtuPercentualErvasBicoOn,
|
||||||
|
pct_erva_bico_off = pControle.AtuPercentualErvasBicoOff
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
("Snr", new
|
("Snr", new
|
||||||
|
|
@ -268,12 +276,13 @@ namespace AgroBase.Services.Operadores
|
||||||
|
|
||||||
public static void AtualizarDadosControleOperacao()
|
public static void AtualizarDadosControleOperacao()
|
||||||
{
|
{
|
||||||
|
var pControle = Variaveis.OperacaoEmAndamento.Parametros.Controle;
|
||||||
RedisService.AtualizarCampos(
|
RedisService.AtualizarCampos(
|
||||||
CtxKey.DadosControle,
|
CtxKey.DadosControle,
|
||||||
("pulverizador_automatico", Variaveis.OperacaoEmAndamento.Controle.PulverizadorAutomatico),
|
("pulverizador_automatico", pControle.PulverizadorAutomatico),
|
||||||
("movimento_automatico", Variaveis.OperacaoEmAndamento.Controle.MovimentoAutomatico),
|
("movimento_automatico", pControle.MovimentoAutomatico),
|
||||||
("frenagem_automatica", Variaveis.OperacaoEmAndamento.Controle.FrenagemAutomatica),
|
("frenagem_automatica", pControle.FrenagemAutomatica),
|
||||||
("sonar_ativado", Variaveis.OperacaoEmAndamento.Controle.SonarAtivado)
|
("sonar_ativado", pControle.SonarAtivado)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -281,7 +290,7 @@ namespace AgroBase.Services.Operadores
|
||||||
{
|
{
|
||||||
if (Variaveis.OperacaoEmAndamento.DispMvd == null) return;
|
if (Variaveis.OperacaoEmAndamento.DispMvd == null) return;
|
||||||
|
|
||||||
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
|
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura;
|
||||||
var agora = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
var agora = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||||||
|
|
||||||
//Console.WriteLine(RedisService.Get(RedisService.ModKey(Enums.T_Code.Gps)));
|
//Console.WriteLine(RedisService.Get(RedisService.ModKey(Enums.T_Code.Gps)));
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ namespace AgroBase.Services.Operadores
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ManagerWorkerCommandType.EnviarDadosControle:
|
case ManagerWorkerCommandType.EnviarDadosControle:
|
||||||
if (Variaveis.OperacaoEmAndamento.Controle.MovimentoAutomatico)
|
if (Variaveis.OperacaoEmAndamento.Parametros.Controle.MovimentoAutomatico)
|
||||||
{
|
{
|
||||||
AtualizarControle(comando.@params);
|
AtualizarControle(comando.@params);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ namespace AgroBase.Services.Operadores
|
||||||
if (!Conectado)
|
if (!Conectado)
|
||||||
{
|
{
|
||||||
TempoDesconectado++;
|
TempoDesconectado++;
|
||||||
if (Variaveis.OperacaoEmAndamento.Iniciado && Variaveis.OperacaoEmAndamento.Controle.MovimentoAutomatico)
|
if (Variaveis.OperacaoEmAndamento.Iniciado && Variaveis.OperacaoEmAndamento.Parametros.Controle.MovimentoAutomatico)
|
||||||
{
|
{
|
||||||
RedisService.AtualizarCampos(
|
RedisService.AtualizarCampos(
|
||||||
CtxKey.DadosOperacao,
|
CtxKey.DadosOperacao,
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ namespace AgroBase.Services.Operadores
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WeedWorkerCommandType.EnviarDadosControle:
|
case WeedWorkerCommandType.EnviarDadosControle:
|
||||||
if (Variaveis.OperacaoEmAndamento.Controle.PulverizadorAutomatico)
|
if (Variaveis.OperacaoEmAndamento.Parametros.Controle.PulverizadorAutomatico)
|
||||||
{
|
{
|
||||||
AtualizarControle(comando.@params);
|
AtualizarControle(comando.@params);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -371,7 +371,7 @@ namespace AgroBase.Services
|
||||||
});
|
});
|
||||||
if (PrimeiraExecucao)
|
if (PrimeiraExecucao)
|
||||||
{
|
{
|
||||||
OperacaoModel.CarregarParametrosOperacaoPadrao(ModoOperacao.Manual);
|
OperacaoModel.CarregarParametrosOperacaoPadrao(ModoOperacao.MapaGPS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,7 @@ namespace AgroBase.Services
|
||||||
|
|
||||||
public static Bitmap ExibirObstaculos(Bitmap bitmap, SonarCamModel leitura, bool ExibirTexto = false)
|
public static Bitmap ExibirObstaculos(Bitmap bitmap, SonarCamModel leitura, bool ExibirTexto = false)
|
||||||
{
|
{
|
||||||
if (bitmap == null || (!Variaveis.OperacaoEmAndamento.Controle.SonarAtivado && Variaveis.OperacaoEmAndamento.Iniciado))
|
if (bitmap == null || (!Variaveis.OperacaoEmAndamento.Parametros.Controle.SonarAtivado && Variaveis.OperacaoEmAndamento.Iniciado))
|
||||||
{
|
{
|
||||||
return bitmap;
|
return bitmap;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -6,12 +6,23 @@ from health_worker.modulos.imu import IMUCamera
|
||||||
from shared.enums import StatusModulo, T_Code
|
from shared.enums import StatusModulo, T_Code
|
||||||
from shared.contexto_global_redis import ContextoGlobalRedis, CtxKey
|
from shared.contexto_global_redis import ContextoGlobalRedis, CtxKey
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import cv2
|
||||||
|
GST_LAUNCH = r"C:\Program Files\gstreamer\1.0\msvc_x86_64\bin\gst-launch-1.0.exe"
|
||||||
|
|
||||||
class CameraOak:
|
class CameraOak:
|
||||||
def __init__(self, mostrar_log, mx_id, modelo_ia_seg=None, modelo_ia_det=None):
|
def __init__(self, mostrar_log, mx_id, modelo_ia_seg=None, modelo_ia_det=None):
|
||||||
self.mostrar_log = mostrar_log
|
self.mostrar_log = mostrar_log
|
||||||
self.modelo_ia_seg = modelo_ia_seg
|
self.modelo_ia_seg = modelo_ia_seg
|
||||||
self.modelo_ia_det = modelo_ia_det
|
self.modelo_ia_det = modelo_ia_det
|
||||||
|
|
||||||
|
self.gst_proc = None
|
||||||
|
self.gst_WIDTH = 640
|
||||||
|
self.gst_HEIGHT = 360
|
||||||
|
self.gst_FPS = 10
|
||||||
|
self.gst_BIT_RATE = 500
|
||||||
|
self._ultimo_envio_gst = 0.0
|
||||||
|
|
||||||
self.dispositivo = T_Code.Vzo
|
self.dispositivo = T_Code.Vzo
|
||||||
self.modelo = "Desconhecido"
|
self.modelo = "Desconhecido"
|
||||||
self.ultima_saude = {}
|
self.ultima_saude = {}
|
||||||
|
|
@ -72,6 +83,39 @@ class CameraOak:
|
||||||
_camera["tem_depht"] = self.tem_depth
|
_camera["tem_depht"] = self.tem_depth
|
||||||
_camera["tem_imu"] = self.tem_imu
|
_camera["tem_imu"] = self.tem_imu
|
||||||
|
|
||||||
|
# Criar processo para transmissao de video
|
||||||
|
try:
|
||||||
|
_cfg = ContextoGlobalRedis.get_equipamento() or {}
|
||||||
|
_ip = _cfg.get("base_ip")
|
||||||
|
_porta = _cfg.get("base_porta_caminho") if self.dispositivo == T_Code.Snr else _cfg.get("base_porta_ervas")
|
||||||
|
if _ip is not None and _porta is not None:
|
||||||
|
self.mostrar_log(f"Iniciando GStreamer para {_ip}:{_porta}...")
|
||||||
|
gst_cmd = [
|
||||||
|
GST_LAUNCH,
|
||||||
|
"fdsrc", "fd=0",
|
||||||
|
"!", "videoparse",
|
||||||
|
f"width={self.gst_WIDTH}", f"height={self.gst_HEIGHT}",
|
||||||
|
"format=bgr",
|
||||||
|
f"framerate={self.gst_FPS}/1",
|
||||||
|
"!", "videoconvert",
|
||||||
|
"!", "videoscale",
|
||||||
|
"!", f"video/x-raw,width={self.gst_WIDTH},height={self.gst_HEIGHT}",
|
||||||
|
"!", "x264enc", "tune=zerolatency", "speed-preset=ultrafast",
|
||||||
|
f"bitrate={self.gst_BIT_RATE}", "key-int-max=20",
|
||||||
|
"!", "rtph264pay", "config-interval=-1", "pt=96",
|
||||||
|
#"!", "h264parse", "!", "mpegtsmux",
|
||||||
|
"!", "udpsink",
|
||||||
|
f"host={_ip}", f"port={_porta}",
|
||||||
|
"sync=false", "async=false",
|
||||||
|
]
|
||||||
|
self.gst_proc = subprocess.Popen(
|
||||||
|
gst_cmd,
|
||||||
|
stdin=subprocess.PIPE,
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
self.gst_proc = None
|
||||||
|
self.mostrar_log(f"Erro ao criar script de transmissao de video: {e}")
|
||||||
|
|
||||||
# Fase 2: criar pipeline e instanciar normalmente
|
# Fase 2: criar pipeline e instanciar normalmente
|
||||||
try:
|
try:
|
||||||
self.pipeline = self._criar_pipeline()
|
self.pipeline = self._criar_pipeline()
|
||||||
|
|
@ -350,6 +394,32 @@ class CameraOak:
|
||||||
#self.timestamp_ultimo_frame_rgb = time.time()
|
#self.timestamp_ultimo_frame_rgb = time.time()
|
||||||
dur = time.time() - start
|
dur = time.time() - start
|
||||||
|
|
||||||
|
_stream_on = (ContextoGlobalRedis.get_camera(self.mx_id) or {}).get("streaming", False)
|
||||||
|
if self.gst_proc is not None and _stream_on:
|
||||||
|
# --- CONTROLE DE FPS PARA STREAMING ---
|
||||||
|
enviar_para_gst = True
|
||||||
|
if getattr(self, "gst_FPS", None) and self.gst_FPS > 0:
|
||||||
|
intervalo_min = 1.0 / float(self.gst_FPS)
|
||||||
|
agora = time.time()
|
||||||
|
if (agora - self._ultimo_envio_gst) < intervalo_min:
|
||||||
|
enviar_para_gst = False
|
||||||
|
else:
|
||||||
|
self._ultimo_envio_gst = agora
|
||||||
|
if frame is not None and frame.size > 0 and enviar_para_gst:
|
||||||
|
# --- RESIZE SÓ PARA O STREAM ---
|
||||||
|
if frame.shape[1] != self.gst_WIDTH or frame.shape[0] != self.gst_HEIGHT:
|
||||||
|
frame_stream = cv2.resize(
|
||||||
|
frame,
|
||||||
|
(self.gst_WIDTH, self.gst_HEIGHT),
|
||||||
|
interpolation=cv2.INTER_AREA
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
frame_stream = frame
|
||||||
|
try:
|
||||||
|
self.gst_proc.stdin.write(frame_stream.tobytes())
|
||||||
|
except BrokenPipeError:
|
||||||
|
self.mostrar_log("GStreamer fechou o pipe. Encerrando.")
|
||||||
|
|
||||||
resultado = {
|
resultado = {
|
||||||
"erro": None,
|
"erro": None,
|
||||||
"duracao": dur,
|
"duracao": dur,
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,6 @@ def load_seg_config(force_reload=False):
|
||||||
# "frames_histerese": 2,
|
# "frames_histerese": 2,
|
||||||
# "min_area_px": 400,
|
# "min_area_px": 400,
|
||||||
# "max_area_frac": 0.2,
|
# "max_area_frac": 0.2,
|
||||||
# "area_atuacao_bicos": 0.1,
|
|
||||||
# "ia_roi_begin": 0.0,
|
# "ia_roi_begin": 0.0,
|
||||||
# "ia_roi_size": 1.0,
|
# "ia_roi_size": 1.0,
|
||||||
# "ia_resolution": [512,288],
|
# "ia_resolution": [512,288],
|
||||||
|
|
@ -79,7 +78,6 @@ def load_seg_config(force_reload=False):
|
||||||
"frames_histerese": 2,
|
"frames_histerese": 2,
|
||||||
"min_area_px": 400,
|
"min_area_px": 400,
|
||||||
"max_area_frac": 0.2,
|
"max_area_frac": 0.2,
|
||||||
"area_atuacao_bicos": 0.1,
|
|
||||||
"ia_roi_begin": 0.0,
|
"ia_roi_begin": 0.0,
|
||||||
"ia_roi_size": 1.0,
|
"ia_roi_size": 1.0,
|
||||||
"ia_resolution": [512,288],
|
"ia_resolution": [512,288],
|
||||||
|
|
@ -97,8 +95,6 @@ def load_seg_config(force_reload=False):
|
||||||
"det_every_n": 0,
|
"det_every_n": 0,
|
||||||
|
|
||||||
"usar_radar_global_gate": True,
|
"usar_radar_global_gate": True,
|
||||||
"min_frac_erva_por_bico_on": 0.02,
|
|
||||||
"min_frac_erva_por_bico_off": 0.01,
|
|
||||||
"max_frac_cana_por_bico": 0.009,
|
"max_frac_cana_por_bico": 0.009,
|
||||||
"ema_frac_bico": 0.35,
|
"ema_frac_bico": 0.35,
|
||||||
"on_frames_required": 3,
|
"on_frames_required": 3,
|
||||||
|
|
@ -115,7 +111,10 @@ def load_seg_config(force_reload=False):
|
||||||
|
|
||||||
_CONFIG_CACHE["ia_model_path"] = ContextoGlobalRedis.get_equipamento().get("path_ia_model_ervas", "C:/AgroBaseModels/Ervas/model-2_1.blob")
|
_CONFIG_CACHE["ia_model_path"] = ContextoGlobalRedis.get_equipamento().get("path_ia_model_ervas", "C:/AgroBaseModels/Ervas/model-2_1.blob")
|
||||||
_CONFIG_CACHE["ia_labelmap_path"] = ContextoGlobalRedis.get_equipamento().get("path_ia_labelmap_ervas", "C:/AgroBaseModels/Ervas/model-2_1.txt")
|
_CONFIG_CACHE["ia_labelmap_path"] = ContextoGlobalRedis.get_equipamento().get("path_ia_labelmap_ervas", "C:/AgroBaseModels/Ervas/model-2_1.txt")
|
||||||
_CONFIG_CACHE["faixa_atuacao_bicos"] = dadosAtu.get("percent_vertical_deteccao", 0.3)
|
_CONFIG_CACHE["faixa_atuacao_bicos"] = dadosAtu.get("percent_vertical_deteccao", 0.7)
|
||||||
|
_CONFIG_CACHE["area_atuacao_bicos"] = dadosAtu.get("height_area_deteccao", 0.1)
|
||||||
|
_CONFIG_CACHE["min_frac_erva_por_bico_on"] = dadosAtu.get("pct_erva_bico_on", 0.02)
|
||||||
|
_CONFIG_CACHE["min_frac_erva_por_bico_off"] = dadosAtu.get("pct_erva_bico_off", 0.01)
|
||||||
return _CONFIG_CACHE
|
return _CONFIG_CACHE
|
||||||
|
|
||||||
def reload_seg_config():
|
def reload_seg_config():
|
||||||
|
|
|
||||||
|
|
@ -269,7 +269,7 @@ namespace AgroMonitor.Forms
|
||||||
Keys[] TeclasDir = { Keys.A, Keys.D };
|
Keys[] TeclasDir = { Keys.A, Keys.D };
|
||||||
Keys[] TeclasMov = { Keys.W, Keys.S, Keys.Space };
|
Keys[] TeclasMov = { Keys.W, Keys.S, Keys.Space };
|
||||||
|
|
||||||
OperacaoControleBaseModel Controle = new OperacaoControleBaseModel()
|
OperacaoComandoBaseModel Controle = new OperacaoComandoBaseModel()
|
||||||
{
|
{
|
||||||
Momento = DateTime.Now,
|
Momento = DateTime.Now,
|
||||||
Tecla = DeParaTeclas[Tecla],
|
Tecla = DeParaTeclas[Tecla],
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using OperationControl.Models;
|
using OperationControl.Models;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using Application = System.Windows.Application;
|
||||||
|
|
||||||
namespace OperationControl
|
namespace OperationControl
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
</LinearGradientBrush>
|
</LinearGradientBrush>
|
||||||
|
|
||||||
<conv:MultiplyConverter x:Key="MultiplyConverter"/>
|
<conv:MultiplyConverter x:Key="MultiplyConverter"/>
|
||||||
|
<conv:LateralErrorToOffsetConverter x:Key="LateralErrorToOffsetConverter"/>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
|
|
||||||
<!-- MOLDURA -->
|
<!-- MOLDURA -->
|
||||||
|
|
@ -30,6 +31,13 @@
|
||||||
BorderBrush="#2ECC71">
|
BorderBrush="#2ECC71">
|
||||||
<Grid>
|
<Grid>
|
||||||
|
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<!-- parte de cima: horizonte / attitude -->
|
||||||
|
<RowDefinition/>
|
||||||
|
<!-- parte de baixo: barra de erro lateral -->
|
||||||
|
<RowDefinition Height="24"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<!-- VIEWPORT: corta o conteúdo dentro do quadro -->
|
<!-- VIEWPORT: corta o conteúdo dentro do quadro -->
|
||||||
<Grid x:Name="Viewport" ClipToBounds="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
<Grid x:Name="Viewport" ClipToBounds="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||||
|
|
||||||
|
|
@ -101,6 +109,37 @@
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
<!-- BARRA DE ERRO LATERAL (linha 1) -->
|
||||||
|
<Grid Grid.Row="1" Margin="2,6,2,0">
|
||||||
|
<Border x:Name="LateralTrack" CornerRadius="4" Background="#222" BorderBrush="#555" BorderThickness="1">
|
||||||
|
<Grid>
|
||||||
|
<!-- linha de referência (meio da rua) -->
|
||||||
|
<Rectangle Width="2" Fill="#666" HorizontalAlignment="Center" RadiusX="1" RadiusY="1"/>
|
||||||
|
|
||||||
|
<!-- barrinha que se move com o erro -->
|
||||||
|
<Rectangle Width="32" Height="6" RadiusX="3" RadiusY="3" Fill="#F1C40F" Stroke="#222" StrokeThickness="0.5">
|
||||||
|
<Rectangle.RenderTransform>
|
||||||
|
<TranslateTransform>
|
||||||
|
<TranslateTransform.X>
|
||||||
|
<MultiBinding Converter="{StaticResource LateralErrorToOffsetConverter}">
|
||||||
|
<!-- Largura do trilho -->
|
||||||
|
<Binding ElementName="LateralTrack" Path="ActualWidth"/>
|
||||||
|
|
||||||
|
<!-- Erro normalizado (-1 a +1) -->
|
||||||
|
<Binding Path="LateralNormalized" RelativeSource="{RelativeSource AncestorType=UserControl}"/>
|
||||||
|
</MultiBinding>
|
||||||
|
</TranslateTransform.X>
|
||||||
|
</TranslateTransform>
|
||||||
|
</Rectangle.RenderTransform>
|
||||||
|
</Rectangle>
|
||||||
|
|
||||||
|
<!-- valor numérico opcional (no canto direito) -->
|
||||||
|
<TextBlock Text="{Binding LateralError, RelativeSource={RelativeSource AncestorType=UserControl}, StringFormat={}{0:0.00} cm}" Foreground="#AAA" FontSize="10" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,4,0"/>
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
using UserControl = System.Windows.Controls.UserControl;
|
||||||
|
using Color = System.Windows.Media.Color;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Windows.Data;
|
||||||
|
|
||||||
namespace OperationControl.Controls
|
namespace OperationControl.Controls
|
||||||
{
|
{
|
||||||
|
|
@ -81,6 +84,54 @@ namespace OperationControl.Controls
|
||||||
set => SetValue(CriticalLimitProperty, value);
|
set => SetValue(CriticalLimitProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// === LATERAL ERROR ===
|
||||||
|
public static readonly DependencyProperty LateralErrorProperty =
|
||||||
|
DependencyProperty.Register(
|
||||||
|
nameof(LateralError),
|
||||||
|
typeof(double),
|
||||||
|
typeof(AttitudeIndicator),
|
||||||
|
new PropertyMetadata(0.0, OnLateralChanged));
|
||||||
|
|
||||||
|
public static readonly DependencyProperty LateralMaxAbsProperty =
|
||||||
|
DependencyProperty.Register(
|
||||||
|
nameof(LateralMaxAbs),
|
||||||
|
typeof(double),
|
||||||
|
typeof(AttitudeIndicator),
|
||||||
|
new PropertyMetadata(50.0, OnLateralChanged)); // 0,5 m por padrão
|
||||||
|
|
||||||
|
private static readonly DependencyPropertyKey LateralNormalizedPropertyKey =
|
||||||
|
DependencyProperty.RegisterReadOnly(
|
||||||
|
nameof(LateralNormalized),
|
||||||
|
typeof(double),
|
||||||
|
typeof(AttitudeIndicator),
|
||||||
|
new PropertyMetadata(0.0));
|
||||||
|
|
||||||
|
public static readonly DependencyProperty LateralNormalizedProperty =
|
||||||
|
LateralNormalizedPropertyKey.DependencyProperty;
|
||||||
|
|
||||||
|
public double LateralError
|
||||||
|
{
|
||||||
|
get => (double)GetValue(LateralErrorProperty);
|
||||||
|
set => SetValue(LateralErrorProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double LateralMaxAbs
|
||||||
|
{
|
||||||
|
get => (double)GetValue(LateralMaxAbsProperty);
|
||||||
|
set => SetValue(LateralMaxAbsProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Erro lateral normalizado em [-1, 1]
|
||||||
|
/// -1 = limite à esquerda, 0 = centro, +1 = limite à direita
|
||||||
|
/// </summary>
|
||||||
|
public double LateralNormalized
|
||||||
|
{
|
||||||
|
get => (double)GetValue(LateralNormalizedProperty);
|
||||||
|
private set => SetValue(LateralNormalizedPropertyKey, value);
|
||||||
|
}
|
||||||
|
|
||||||
// Derivados
|
// Derivados
|
||||||
public double MaxAbsAngle => Math.Max(Math.Abs(RollDeg), Math.Abs(PitchDeg));
|
public double MaxAbsAngle => Math.Max(Math.Abs(RollDeg), Math.Abs(PitchDeg));
|
||||||
|
|
||||||
|
|
@ -108,5 +159,29 @@ namespace OperationControl.Controls
|
||||||
else
|
else
|
||||||
Chrome.BorderBrush = new SolidColorBrush(Color.FromRgb(0x2E, 0xCC, 0x71)); // verde
|
Chrome.BorderBrush = new SolidColorBrush(Color.FromRgb(0x2E, 0xCC, 0x71)); // verde
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void OnLateralChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var c = (AttitudeIndicator)d;
|
||||||
|
c.UpdateLateral();
|
||||||
|
c.Raise(nameof(LateralNormalized));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UpdateLateral()
|
||||||
|
{
|
||||||
|
var max = Math.Max(0.0001, LateralMaxAbs);
|
||||||
|
|
||||||
|
// normaliza para [-1, 1] e faz clamp
|
||||||
|
var n = LateralError / max;
|
||||||
|
if (n > 1) n = 1;
|
||||||
|
if (n < -1) n = -1;
|
||||||
|
|
||||||
|
LateralNormalized = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
using OpenTK.Wpf;
|
using OpenTK.Wpf;
|
||||||
using OpenTK.Graphics.OpenGL;
|
using OpenTK.Graphics.OpenGL;
|
||||||
using System.Windows.Controls;
|
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
using UserControl = System.Windows.Controls.UserControl;
|
||||||
|
|
||||||
namespace OperationControl.Controls
|
namespace OperationControl.Controls
|
||||||
{
|
{
|
||||||
|
|
@ -244,7 +244,7 @@ namespace OperationControl.Controls
|
||||||
if (e.ChangedButton == MouseButton.Middle) dragMid = false;
|
if (e.ChangedButton == MouseButton.Middle) dragMid = false;
|
||||||
if (!dragLeft && !dragMid) Mouse.Capture(null);
|
if (!dragLeft && !dragMid) Mouse.Capture(null);
|
||||||
}
|
}
|
||||||
void OnMouseMove(object s, MouseEventArgs e)
|
void OnMouseMove(object s, System.Windows.Input.MouseEventArgs e)
|
||||||
{
|
{
|
||||||
var p = e.GetPosition(GLHost);
|
var p = e.GetPosition(GLHost);
|
||||||
if (dragLeft)
|
if (dragLeft)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
<UserControl x:Class="OperationControl.Controls.GstVideoView"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="clr-namespace:OperationControl.Controls"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
|
||||||
|
xmlns:wfi="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
|
||||||
|
xmlns:ffme="clr-namespace:Unosquare.FFME;assembly=ffme.win"
|
||||||
|
Height="247" Width="420">
|
||||||
|
<Grid Background="Black">
|
||||||
|
<ffme:MediaElement x:Name="Media" Background="Gray" LoadedBehavior="Play" UnloadedBehavior="Manual" />
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
|
|
@ -0,0 +1,226 @@
|
||||||
|
using System.Windows;
|
||||||
|
using Gst;
|
||||||
|
using GstVideo;
|
||||||
|
using Unosquare.FFME;
|
||||||
|
using Task = System.Threading.Tasks.Task;
|
||||||
|
using UserControl = System.Windows.Controls.UserControl;
|
||||||
|
|
||||||
|
namespace OperationControl.Controls
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for GstVideoView.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class GstVideoView : UserControl
|
||||||
|
{
|
||||||
|
private Pipeline? _pipeline;
|
||||||
|
private Element? _videoSink;
|
||||||
|
private Bus? _bus;
|
||||||
|
|
||||||
|
#region DP: Host e Port
|
||||||
|
|
||||||
|
public string Host
|
||||||
|
{
|
||||||
|
get => (string)GetValue(HostProperty);
|
||||||
|
set => SetValue(HostProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty HostProperty =
|
||||||
|
DependencyProperty.Register(
|
||||||
|
nameof(Host),
|
||||||
|
typeof(string),
|
||||||
|
typeof(GstVideoView),
|
||||||
|
new PropertyMetadata("0.0.0.0", OnEndpointChanged));
|
||||||
|
|
||||||
|
public int Port
|
||||||
|
{
|
||||||
|
get => (int)GetValue(PortProperty);
|
||||||
|
set => SetValue(PortProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty PortProperty =
|
||||||
|
DependencyProperty.Register(
|
||||||
|
nameof(Port),
|
||||||
|
typeof(int),
|
||||||
|
typeof(GstVideoView),
|
||||||
|
new PropertyMetadata(5000, OnEndpointChanged));
|
||||||
|
|
||||||
|
private static void OnEndpointChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var view = (GstVideoView)d;
|
||||||
|
// Se já estiver carregado, reinicia o pipeline com IP/porta novos
|
||||||
|
if (view.IsLoaded)
|
||||||
|
{
|
||||||
|
//view.RestartPipeline();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
public string SourceUrl { get; set; } = "udp://0.0.0.0:5000";
|
||||||
|
|
||||||
|
public GstVideoView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
InitGStreamer();
|
||||||
|
|
||||||
|
Loaded += (_, _) =>
|
||||||
|
{
|
||||||
|
//if (VideoPanel.IsHandleCreated == false)
|
||||||
|
// VideoPanel.CreateControl();
|
||||||
|
};
|
||||||
|
Unloaded += (_, _) => Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitGStreamer()
|
||||||
|
{
|
||||||
|
//Gst.Application.Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StartPipeline()
|
||||||
|
{
|
||||||
|
if (_pipeline != null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// pipeline simples só pra testar: videotestsrc → videoconvert → autovideosink
|
||||||
|
_pipeline = new Pipeline();
|
||||||
|
|
||||||
|
var src = ElementFactory.Make("videotestsrc", "src");
|
||||||
|
var conv = ElementFactory.Make("videoconvert", "conv");
|
||||||
|
var sink = ElementFactory.Make("autovideosink", "sink");
|
||||||
|
|
||||||
|
if (src is null || conv is null || sink is null)
|
||||||
|
throw new Exception("Falha ao criar algum elemento do pipeline.");
|
||||||
|
|
||||||
|
_pipeline.Add(src);
|
||||||
|
_pipeline.Add(conv);
|
||||||
|
_pipeline.Add(sink);
|
||||||
|
|
||||||
|
if (!src.Link(conv) || !conv.Link(sink))
|
||||||
|
throw new Exception("Falha ao linkar o pipeline.");
|
||||||
|
|
||||||
|
// >>> AQUI entra a correção do Bus (ver seção 2) <<<
|
||||||
|
|
||||||
|
_pipeline.SetState(State.Playing);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Start2()
|
||||||
|
{
|
||||||
|
if (_pipeline != null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//if (!VideoPanel.IsHandleCreated)
|
||||||
|
// VideoPanel.CreateControl();
|
||||||
|
|
||||||
|
// Monta o pipeline de recepção (ajuste caps se precisar)
|
||||||
|
string pipeDesc =
|
||||||
|
$"udpsrc port={Port} " +
|
||||||
|
"caps = application/x-rtp, media=video, encoding-name=H264, payload=96 " +
|
||||||
|
"! rtph264depay ! h264parse ! avdec_h264 ! videoconvert " +
|
||||||
|
"! d3d11videosink name=vsink sync=false";
|
||||||
|
|
||||||
|
// Cria pipeline a partir da string
|
||||||
|
_pipeline = new Pipeline(new Gst.Internal.PipelineHandle(1, false));
|
||||||
|
|
||||||
|
if (_pipeline is null)
|
||||||
|
throw new InvalidOperationException("Falha ao criar pipeline GStreamer.");
|
||||||
|
|
||||||
|
// Pega o sink pelo nome
|
||||||
|
_videoSink = _pipeline.GetChildByName("vsink") as Element;
|
||||||
|
|
||||||
|
if (_videoSink is null)
|
||||||
|
throw new InvalidOperationException("Não foi possível encontrar o elemento 'vsink' no pipeline.");
|
||||||
|
|
||||||
|
// Faz o cast para VideoOverlay
|
||||||
|
var overlay = _videoSink as VideoOverlay;
|
||||||
|
|
||||||
|
if (overlay is null)
|
||||||
|
throw new InvalidOperationException("O sink não implementa VideoOverlay.");
|
||||||
|
|
||||||
|
// Passa o handle da janela do Panel para o sink
|
||||||
|
//var hwnd = VideoPanel.Handle;
|
||||||
|
//overlay.SetWindowHandle((nuint)hwnd);
|
||||||
|
|
||||||
|
// (Opcional) configurar bus para logar erros
|
||||||
|
_bus = _pipeline.GetBus();
|
||||||
|
_bus.AddSignalWatch();
|
||||||
|
_bus.OnMessage += OnBusMessage;
|
||||||
|
|
||||||
|
// Play!
|
||||||
|
_pipeline.SetState(State.Playing);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop2()
|
||||||
|
{
|
||||||
|
if (_pipeline == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_pipeline.SetState(State.Null);
|
||||||
|
|
||||||
|
if (_bus != null)
|
||||||
|
{
|
||||||
|
_bus.OnMessage -= OnBusMessage;
|
||||||
|
_bus.Dispose();
|
||||||
|
_bus = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
_pipeline.Dispose();
|
||||||
|
_pipeline = null;
|
||||||
|
_videoSink = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnBusMessage(object? sender, Bus.MessageSignalArgs e)
|
||||||
|
{
|
||||||
|
switch (e.Message.Type)
|
||||||
|
{
|
||||||
|
case MessageType.Error:
|
||||||
|
//e.Message.ParseError(out var err, out var debug);
|
||||||
|
//Console.WriteLine($"[GST ERROR] {err}: {debug}");
|
||||||
|
Console.WriteLine($"[GST ERROR] {e.Message}");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MessageType.Eos:
|
||||||
|
Console.WriteLine("[GST] End of stream");
|
||||||
|
// Se quiser, reinicia ou dá Stop();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task Start()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (Media.IsOpen)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Abre o stream (udp, rtsp, http…)
|
||||||
|
await Media.Open(new System.Uri(SourceUrl));
|
||||||
|
|
||||||
|
await Media.Play();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.WriteLine($"[FFME] Erro ao iniciar vídeo: {ex}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async void Stop()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (Media.IsOpen)
|
||||||
|
{
|
||||||
|
await Media.Stop();
|
||||||
|
await Media.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.WriteLine($"[FFME] Erro ao parar vídeo: {ex}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
using UserControl = System.Windows.Controls.UserControl;
|
||||||
|
using Color = System.Windows.Media.Color;
|
||||||
|
|
||||||
namespace OperationControl.Controls
|
namespace OperationControl.Controls
|
||||||
{
|
{
|
||||||
|
|
@ -101,7 +102,7 @@ namespace OperationControl.Controls
|
||||||
if (Chrome == null) return;
|
if (Chrome == null) return;
|
||||||
|
|
||||||
bool no_course = double.IsNaN(CourseHeading);
|
bool no_course = double.IsNaN(CourseHeading);
|
||||||
var a = no_course ? 0 : DifHeading;
|
var a = no_course ? 0 : Math.Abs(DifHeading);
|
||||||
var cor = new SolidColorBrush(Color.FromRgb(0x2E, 0xCC, 0x71)); // verde
|
var cor = new SolidColorBrush(Color.FromRgb(0x2E, 0xCC, 0x71)); // verde
|
||||||
if (a >= 10)
|
if (a >= 10)
|
||||||
cor = new SolidColorBrush(Color.FromRgb(0xE7, 0x4C, 0x3C)); // vermelho
|
cor = new SolidColorBrush(Color.FromRgb(0xE7, 0x4C, 0x3C)); // vermelho
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
using UserControl = System.Windows.Controls.UserControl;
|
||||||
|
using Brush = System.Windows.Media.Brush;
|
||||||
|
using Brushes = System.Windows.Media.Brushes;
|
||||||
|
using Color = System.Windows.Media.Color;
|
||||||
|
|
||||||
namespace OperationControl.Controls
|
namespace OperationControl.Controls
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
<UserControl x:Class="OperationControl.Controls.ManualControlPad"
|
<UserControl x:Class="OperationControl.Controls.ManualControlPad"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:local="clr-namespace:OperationControl.Controls"
|
||||||
x:Name="Root" Focusable="True" MinWidth="382">
|
x:Name="Root" Focusable="True" MinWidth="382">
|
||||||
|
|
||||||
<Border CornerRadius="8" Background="#111" BorderBrush="Black" BorderThickness="1" Width="382" MinHeight="66">
|
<Border CornerRadius="8" Background="#111" BorderBrush="Black" BorderThickness="1" Width="382" MinHeight="66">
|
||||||
|
|
@ -49,24 +50,72 @@
|
||||||
|
|
||||||
<!-- Botões + Modo Manual à direita -->
|
<!-- Botões + Modo Manual à direita -->
|
||||||
<Canvas Grid.Column="1" Margin="0,0,-184,0">
|
<Canvas Grid.Column="1" Margin="0,0,-184,0">
|
||||||
<!-- Emergência (ícone MDL2) -->
|
<Button x:Name="btnEmergencia" FontFamily="Segoe UI Emoji" Width="70" Height="20" Click="OnEmergencyClick" HorizontalAlignment="Center" VerticalAlignment="Top" Canvas.Top="1">
|
||||||
<Button Content="" FontFamily="Segoe MDL2 Assets" ToolTip="Parada de Emergência" Background="#E74C3C" Foreground="White" Width="70" Height="20" Click="OnEmergencyClick" HorizontalAlignment="Center" VerticalAlignment="Top" Canvas.Top="1"/>
|
<Button.Style>
|
||||||
<!-- Iniciar | Pausar -->
|
<Style TargetType="Button">
|
||||||
<ToggleButton x:Name="BtnRun" Width="108" Height="20" Checked="OnRunToggle" Unchecked="OnRunToggle" Canvas.Left="75" Canvas.Top="1" HorizontalAlignment="Left" VerticalAlignment="Top">
|
<!-- estado normal (desativado) -->
|
||||||
<ToggleButton.Style>
|
<Setter Property="Content" Value="🚨"/>
|
||||||
<Style TargetType="ToggleButton">
|
<Setter Property="Background" Value="#E74C3C"/>
|
||||||
<Setter Property="Content" Value="Iniciar"/>
|
<Setter Property="Foreground" Value="White"/>
|
||||||
|
<Setter Property="FontSize" Value="12"/>
|
||||||
|
<Setter Property="ToolTip" Value="Ativar Parada de Emergência"/>
|
||||||
|
|
||||||
<Style.Triggers>
|
<Style.Triggers>
|
||||||
<Trigger Property="IsChecked" Value="True">
|
<!-- quando a emergência estiver ATIVA -->
|
||||||
<Setter Property="Content" Value="Pausar"/>
|
<DataTrigger Value="True" Binding="{Binding EmergencyActivated, RelativeSource={RelativeSource AncestorType=local:ManualControlPad}}">
|
||||||
</Trigger>
|
<Setter Property="Background" Value="White"/>
|
||||||
|
<Setter Property="Foreground" Value="#E74C3C"/>
|
||||||
|
<Setter Property="Content" Value="⛔"/>
|
||||||
|
<Setter Property="ToolTip" Value="Desativar Parada de Emergência"/>
|
||||||
|
</DataTrigger>
|
||||||
</Style.Triggers>
|
</Style.Triggers>
|
||||||
</Style>
|
</Style>
|
||||||
</ToggleButton.Style>
|
</Button.Style>
|
||||||
</ToggleButton>
|
</Button>
|
||||||
<!-- Referenciar -->
|
|
||||||
<Button Content="Referenciar" Width="70" Height="20" Click="OnRefClick" Canvas.Top="23" HorizontalAlignment="Left" VerticalAlignment="Top"/>
|
<Button x:Name="BtnPausa" Width="70" Height="20" Click="OnPauseClick" Canvas.Top="23" HorizontalAlignment="Left" VerticalAlignment="Center">
|
||||||
<!-- Modo Manual (abre/fecha painel) -->
|
<Button.Style>
|
||||||
|
<Style TargetType="Button">
|
||||||
|
<!-- estado normal (desativado) -->
|
||||||
|
<Setter Property="Content" Value="⏸️"/>
|
||||||
|
<Setter Property="Background" Value="Yellow"/>
|
||||||
|
<Setter Property="Foreground" Value="Black"/>
|
||||||
|
<Setter Property="ToolTip" Value="Colocar Operação em Espera"/>
|
||||||
|
|
||||||
|
<Style.Triggers>
|
||||||
|
<!-- quando a emergência estiver ATIVA -->
|
||||||
|
<DataTrigger Value="True" Binding="{Binding PauseActivated, RelativeSource={RelativeSource AncestorType=local:ManualControlPad}}">
|
||||||
|
<Setter Property="Content" Value="▶️"/>
|
||||||
|
<Setter Property="Background" Value="#27AE60"/>
|
||||||
|
<Setter Property="Foreground" Value="White"/>
|
||||||
|
<Setter Property="ToolTip" Value="Retomar Operação"/>
|
||||||
|
</DataTrigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
</Button.Style>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button x:Name="BtnReferenciar" Width="108" Height="20" Click="OnRefClick" HorizontalAlignment="Center" VerticalAlignment="Top" Canvas.Left="75" Canvas.Top="1">
|
||||||
|
<Button.Style>
|
||||||
|
<Style TargetType="Button">
|
||||||
|
<Setter Property="IsEnabled" Value="True"/>
|
||||||
|
<Setter Property="Content" Value="⚙️ Recalibrar"/>
|
||||||
|
<Setter Property="Background" Value="White"/>
|
||||||
|
<Setter Property="Foreground" Value="Black"/>
|
||||||
|
<Setter Property="ToolTip" Value="Realizar processo de calibragem do equipamento"/>
|
||||||
|
|
||||||
|
<Style.Triggers>
|
||||||
|
<DataTrigger Value="True" Binding="{Binding RefActivated, RelativeSource={RelativeSource AncestorType=local:ManualControlPad}}">
|
||||||
|
<Setter Property="IsEnabled" Value="False"/>
|
||||||
|
<Setter Property="Content" Value="🔄 Calibrando"/>
|
||||||
|
<Setter Property="Foreground" Value="Black"/>
|
||||||
|
<Setter Property="ToolTip" Value="Calibragem em andamento"/>
|
||||||
|
</DataTrigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
</Button.Style>
|
||||||
|
</Button>
|
||||||
|
|
||||||
<ToggleButton x:Name="TgManual" Width="108" Height="20" Checked="OnManualToggle" Unchecked="OnManualToggle" Canvas.Left="75" Canvas.Top="23" HorizontalAlignment="Left" VerticalAlignment="Top">
|
<ToggleButton x:Name="TgManual" Width="108" Height="20" Checked="OnManualToggle" Unchecked="OnManualToggle" Canvas.Left="75" Canvas.Top="23" HorizontalAlignment="Left" VerticalAlignment="Top">
|
||||||
<ToggleButton.Style>
|
<ToggleButton.Style>
|
||||||
<Style TargetType="ToggleButton">
|
<Style TargetType="ToggleButton">
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,16 @@
|
||||||
using System.Collections.ObjectModel;
|
using OperationControl.Models;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
|
||||||
using System.Windows.Data;
|
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Media.Animation;
|
using System.Windows.Media.Animation;
|
||||||
|
using UserControl = System.Windows.Controls.UserControl;
|
||||||
|
using KeyEventArgs = System.Windows.Input.KeyEventArgs;
|
||||||
|
using Binding = System.Windows.Data.Binding;
|
||||||
|
using Application = System.Windows.Application;
|
||||||
|
using Point = System.Windows.Point;
|
||||||
|
using Size = System.Windows.Size;
|
||||||
|
using Mapsui;
|
||||||
|
|
||||||
namespace OperationControl.Controls
|
namespace OperationControl.Controls
|
||||||
{
|
{
|
||||||
|
|
@ -26,21 +32,38 @@ namespace OperationControl.Controls
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
MoveModes.Clear();
|
MoveModes.Clear();
|
||||||
MoveModes.Add("RodasDianteiras");
|
foreach (var t in Enum.GetNames(typeof(AgroBase.Models.Enums.TipoMovimentoDirecional)))
|
||||||
MoveModes.Add("RodasTraseiras");
|
{
|
||||||
MoveModes.Add("RotacionarNoEixo");
|
MoveModes.Add(t);
|
||||||
MoveModes.Add("MovimentoArco");
|
}
|
||||||
MoveModes.Add("MovimentoLateral");
|
|
||||||
MoveModes.Add("MovimentoDiagonal");
|
|
||||||
MoveModes.Add("Diagnostico");
|
|
||||||
|
|
||||||
SelectedMoveMode = MoveModes[0];
|
SelectedMoveMode = MoveModes[0];
|
||||||
|
|
||||||
Loaded += (_, __) => UpdateThumb();
|
Loaded += (_, __) => UpdateThumb();
|
||||||
SizeChanged += (_, __) => { if (ManualContainer.Height > 0) AnimateManual(true, instant: true); };
|
SizeChanged += (_, __) => { if (ManualContainer.Height > 0) AnimateManual(true, instant: true); };
|
||||||
|
|
||||||
|
EmergencyClicked += ManualControlPad_EmergencyClicked;
|
||||||
|
PauseClicked += ManualControlPad_PauseClicked;
|
||||||
|
ReferenceClicked += ManualControlPad_ReferenceClicked;
|
||||||
|
ModeChanged += ManualControlPad_ModeChanged;
|
||||||
|
CommandChanged += ManualControlPad_CommandChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ======= Header displays (bind do app) =======
|
// ======= Header displays (bind do app) =======
|
||||||
|
public bool EmergencyActivated { get => (bool)GetValue(EmergencyActivatedProperty); set => SetValue(EmergencyActivatedProperty, value); }
|
||||||
|
public static readonly DependencyProperty EmergencyActivatedProperty = DependencyProperty.Register(nameof(EmergencyActivated), typeof(bool), typeof(ManualControlPad), new PropertyMetadata(false));
|
||||||
|
public bool PauseActivated { get => (bool)GetValue(PauseActivatedProperty); set => SetValue(PauseActivatedProperty, value); }
|
||||||
|
public static readonly DependencyProperty PauseActivatedProperty = DependencyProperty.Register(nameof(PauseActivated), typeof(bool), typeof(ManualControlPad), new PropertyMetadata(false));
|
||||||
|
public bool RefActivated { get => (bool)GetValue(RefActivatedProperty); set => SetValue(RefActivatedProperty, value); }
|
||||||
|
public static readonly DependencyProperty RefActivatedProperty = DependencyProperty.Register(nameof(RefActivated), typeof(bool), typeof(ManualControlPad), new PropertyMetadata(false));
|
||||||
|
|
||||||
public double SpeedSpKmh { get => (double)GetValue(SpeedSpKmhProperty); set => SetValue(SpeedSpKmhProperty, value); }
|
public double SpeedSpKmh { get => (double)GetValue(SpeedSpKmhProperty); set => SetValue(SpeedSpKmhProperty, value); }
|
||||||
public static readonly DependencyProperty SpeedSpKmhProperty = DependencyProperty.Register(nameof(SpeedSpKmh), typeof(double), typeof(ManualControlPad), new PropertyMetadata(0d));
|
public static readonly DependencyProperty SpeedSpKmhProperty = DependencyProperty.Register(nameof(SpeedSpKmh), typeof(double), typeof(ManualControlPad), new PropertyMetadata(0d));
|
||||||
public double SpeedCurKmh { get => (double)GetValue(SpeedCurKmhProperty); set => SetValue(SpeedCurKmhProperty, value); }
|
public double SpeedCurKmh { get => (double)GetValue(SpeedCurKmhProperty); set => SetValue(SpeedCurKmhProperty, value); }
|
||||||
|
|
@ -51,8 +74,8 @@ namespace OperationControl.Controls
|
||||||
public double AngleCurDeg { get => (double)GetValue(AngleCurDegProperty); set => SetValue(AngleCurDegProperty, value); }
|
public double AngleCurDeg { get => (double)GetValue(AngleCurDegProperty); set => SetValue(AngleCurDegProperty, value); }
|
||||||
public static readonly DependencyProperty AngleCurDegProperty = DependencyProperty.Register(nameof(AngleCurDeg), typeof(double), typeof(ManualControlPad), new PropertyMetadata(0d));
|
public static readonly DependencyProperty AngleCurDegProperty = DependencyProperty.Register(nameof(AngleCurDeg), typeof(double), typeof(ManualControlPad), new PropertyMetadata(0d));
|
||||||
|
|
||||||
public string MoveType { get => (string)GetValue(MoveTypeProperty); set => SetValue(MoveTypeProperty, value); }
|
public AgroBase.Models.Enums.TipoMovimentoDirecional MoveType { get => (AgroBase.Models.Enums.TipoMovimentoDirecional)GetValue(MoveTypeProperty); set => SetValue(MoveTypeProperty, value); }
|
||||||
public static readonly DependencyProperty MoveTypeProperty = DependencyProperty.Register(nameof(MoveType), typeof(string), typeof(ManualControlPad), new PropertyMetadata("—"));
|
public static readonly DependencyProperty MoveTypeProperty = DependencyProperty.Register(nameof(MoveType), typeof(AgroBase.Models.Enums.TipoMovimentoDirecional), typeof(ManualControlPad), new PropertyMetadata(AgroBase.Models.Enums.TipoMovimentoDirecional.RodasDianteiras));
|
||||||
|
|
||||||
// ======= Ajustes (painel manual) =======
|
// ======= Ajustes (painel manual) =======
|
||||||
public double SpeedPercent { get => (double)GetValue(SpeedPercentProperty); set => SetValue(SpeedPercentProperty, value); }
|
public double SpeedPercent { get => (double)GetValue(SpeedPercentProperty); set => SetValue(SpeedPercentProperty, value); }
|
||||||
|
|
@ -69,7 +92,7 @@ namespace OperationControl.Controls
|
||||||
// ===== Eventos públicos =====
|
// ===== Eventos públicos =====
|
||||||
public event PropertyChangedEventHandler PropertyChanged; void Raise(string n) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(n));
|
public event PropertyChangedEventHandler PropertyChanged; void Raise(string n) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(n));
|
||||||
public event EventHandler EmergencyClicked;
|
public event EventHandler EmergencyClicked;
|
||||||
public event EventHandler RunToggled; // BtnRun.IsChecked
|
public event EventHandler PauseClicked;
|
||||||
public event EventHandler ReferenceClicked;
|
public event EventHandler ReferenceClicked;
|
||||||
public event EventHandler ModeChanged;
|
public event EventHandler ModeChanged;
|
||||||
public event EventHandler CommandChanged;
|
public event EventHandler CommandChanged;
|
||||||
|
|
@ -77,7 +100,7 @@ namespace OperationControl.Controls
|
||||||
// Botões
|
// Botões
|
||||||
void OnEmergencyClick(object s, RoutedEventArgs e) => EmergencyClicked?.Invoke(this, EventArgs.Empty);
|
void OnEmergencyClick(object s, RoutedEventArgs e) => EmergencyClicked?.Invoke(this, EventArgs.Empty);
|
||||||
void OnRefClick(object s, RoutedEventArgs e) => ReferenceClicked?.Invoke(this, EventArgs.Empty);
|
void OnRefClick(object s, RoutedEventArgs e) => ReferenceClicked?.Invoke(this, EventArgs.Empty);
|
||||||
void OnRunToggle(object s, RoutedEventArgs e) => RunToggled?.Invoke(this, EventArgs.Empty);
|
void OnPauseClick(object s, RoutedEventArgs e) => PauseClicked?.Invoke(this, EventArgs.Empty);
|
||||||
|
|
||||||
// Modo Manual → anima painel
|
// Modo Manual → anima painel
|
||||||
void OnManualToggle(object s, RoutedEventArgs e)
|
void OnManualToggle(object s, RoutedEventArgs e)
|
||||||
|
|
@ -201,8 +224,73 @@ namespace OperationControl.Controls
|
||||||
ThumbTT.Y = -ThrottleCmd * r; // cima +
|
ThumbTT.Y = -ThrottleCmd * r; // cima +
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helpers
|
|
||||||
public bool IsRunning => BtnRun.IsChecked == true;
|
|
||||||
|
public void AtualizarDadosControle(double? angMax = null, double? angSp = null, double? angCur = null, AgroBase.Models.Enums.TipoMovimentoDirecional? tipoMov = null, double? velPct = null, double? velSp = null, double? velKmh = null, bool? emg = null, bool? pause = null, bool? refing = null)
|
||||||
|
{
|
||||||
|
if (angMax != null) MaxSteerDeg = (double)angMax;
|
||||||
|
if (angSp != null) AngleSpDeg = (double)angSp;
|
||||||
|
if (angCur != null) AngleCurDeg = (double)angCur;
|
||||||
|
if (tipoMov != null) MoveType = (AgroBase.Models.Enums.TipoMovimentoDirecional)tipoMov;
|
||||||
|
if (velPct != null) SpeedPercent = (double)velPct;
|
||||||
|
if (velSp != null) SpeedSpKmh = (double)velSp;
|
||||||
|
if (velKmh != null) SpeedCurKmh = (double)velKmh;
|
||||||
|
if (emg != null) EmergencyActivated = (bool)emg;
|
||||||
|
if (pause != null) PauseActivated = (bool)pause;
|
||||||
|
if (refing != null) RefActivated = (bool)refing;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void ManualControlPad_EmergencyClicked(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
EmergencyActivated = !EmergencyActivated;
|
||||||
|
VariaveisControleOperacao.EnviarComandoParada(emergencia: EmergencyActivated);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ManualControlPad_PauseClicked(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (VariaveisControleOperacao.RoverEmFoco.DadosLeitura?.OperacaoIniciada ?? false)
|
||||||
|
{
|
||||||
|
//PauseActivated = !PauseActivated;
|
||||||
|
//VariaveisControleOperacao.EnviarComandoParada(pausa: PauseActivated);
|
||||||
|
|
||||||
|
if (System.Windows.MessageBox.Show("Deseja finalizar a operação em andamento?", "Finalizar Operação", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
|
||||||
|
{
|
||||||
|
VariaveisControleOperacao.EnviarComandoIniciarOperacao(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!(TgManual.IsChecked ?? false) && !(((App)Application.Current).Shell.Main?.MAP?.RuasMapaCarregado?.Any(x => x.Selected) ?? false))
|
||||||
|
{
|
||||||
|
System.Windows.MessageBox.Show("Para iniciar a operação automática, é necessário carregar um mapa e selecionar as ruas onde o equipamento irá operar!", "Parametrização", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (System.Windows.MessageBox.Show("Deseja iniciar a operação com os parâmetros atuais?", "Iniciar Operação", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
|
||||||
|
{
|
||||||
|
VariaveisControleOperacao.EnviarComandoIniciarOperacao(true, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ManualControlPad_ReferenceClicked(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
RefActivated = !RefActivated;
|
||||||
|
VariaveisControleOperacao.EnviarComandoReferenciamento();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ManualControlPad_CommandChanged(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ManualControlPad_ModeChanged(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== visuais
|
// ===== visuais
|
||||||
|
|
@ -213,4 +301,5 @@ namespace OperationControl.Controls
|
||||||
public object Convert(object v, Type t, object p, System.Globalization.CultureInfo c) => (v is bool b && b) ? EnabledOpacity : DisabledOpacity;
|
public object Convert(object v, Type t, object p, System.Globalization.CultureInfo c) => (v is bool b && b) ? EnabledOpacity : DisabledOpacity;
|
||||||
public object ConvertBack(object v, Type t, object p, System.Globalization.CultureInfo c) => Binding.DoNothing;
|
public object ConvertBack(object v, Type t, object p, System.Globalization.CultureInfo c) => Binding.DoNothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
|
||||||
using BruTile;
|
using BruTile;
|
||||||
using BruTile.MbTiles;
|
using BruTile.MbTiles;
|
||||||
using BruTile.Predefined;
|
using BruTile.Predefined;
|
||||||
using SQLite;
|
using SQLite;
|
||||||
using Microsoft.Win32;
|
|
||||||
|
|
||||||
using NetTopologySuite.IO;
|
using NetTopologySuite.IO;
|
||||||
using NetTopologySuite.Features;
|
using NetTopologySuite.Features;
|
||||||
|
|
@ -21,11 +19,18 @@ using Mapsui.Nts;
|
||||||
using Mapsui.UI.Wpf;
|
using Mapsui.UI.Wpf;
|
||||||
|
|
||||||
// Aliases para evitar conflito com NetTopologySuite.* (NTS)
|
// Aliases para evitar conflito com NetTopologySuite.* (NTS)
|
||||||
|
using UserControl = System.Windows.Controls.UserControl;
|
||||||
|
using OpenFileDialog = Microsoft.Win32.OpenFileDialog;
|
||||||
using MIFeature = Mapsui.IFeature;
|
using MIFeature = Mapsui.IFeature;
|
||||||
|
using Brush = Mapsui.Styles.Brush;
|
||||||
|
using Pen = Mapsui.Styles.Pen;
|
||||||
|
using Color = Mapsui.Styles.Color;
|
||||||
|
using Font = Mapsui.Styles.Font;
|
||||||
using NFeature = NetTopologySuite.Features.Feature;
|
using NFeature = NetTopologySuite.Features.Feature;
|
||||||
using Mapsui.Manipulations;
|
using Mapsui.Manipulations;
|
||||||
using Mapsui.Extensions;
|
using Mapsui.Extensions;
|
||||||
using OperationControl.Models;
|
using OperationControl.Models;
|
||||||
|
using static AgroBase.Models.Enums;
|
||||||
|
|
||||||
|
|
||||||
namespace OperationControl.Controls
|
namespace OperationControl.Controls
|
||||||
|
|
@ -67,6 +72,8 @@ namespace OperationControl.Controls
|
||||||
public event EventHandler<MapMarkerManager.MarkerClickedEventArgs>? MarkerClicked;
|
public event EventHandler<MapMarkerManager.MarkerClickedEventArgs>? MarkerClicked;
|
||||||
protected virtual void OnMarkerClicked(string markerId)
|
protected virtual void OnMarkerClicked(string markerId)
|
||||||
{
|
{
|
||||||
|
if (markerId == null) markers?.ClearMarkerFocused();
|
||||||
|
else markers?.SetMarkerFocused(markerId, true);
|
||||||
MarkerClicked?.Invoke(this, new MapMarkerManager.MarkerClickedEventArgs(markerId));
|
MarkerClicked?.Invoke(this, new MapMarkerManager.MarkerClickedEventArgs(markerId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,7 +85,7 @@ namespace OperationControl.Controls
|
||||||
#region RUAS PLANTACAO
|
#region RUAS PLANTACAO
|
||||||
|
|
||||||
private Layer MapaPlantacao_Layer;
|
private Layer MapaPlantacao_Layer;
|
||||||
private List<StreetMapDictionaryModel> RuasMapaCarregado;
|
public List<StreetMapDictionaryModel> RuasMapaCarregado;
|
||||||
|
|
||||||
public event EventHandler<StreetMapClickedEventArgs>? StreetMapClicked;
|
public event EventHandler<StreetMapClickedEventArgs>? StreetMapClicked;
|
||||||
protected virtual void OnStreetMapClicked(string streetId)
|
protected virtual void OnStreetMapClicked(string streetId)
|
||||||
|
|
@ -461,24 +468,18 @@ namespace OperationControl.Controls
|
||||||
var info = Mapa.GetMapInfo(sp, Mapa.Map.Layers /*, 18*/);
|
var info = Mapa.GetMapInfo(sp, Mapa.Map.Layers /*, 18*/);
|
||||||
var feat = info?.Feature;
|
var feat = info?.Feature;
|
||||||
|
|
||||||
if (info?.Layer == markers.Layer)
|
if (info?.Layer == markers.Layer && feat != null && markers != null && markers.TryGetIdFromFeature(feat, out var id))
|
||||||
{
|
{
|
||||||
if (feat != null && markers != null && markers.TryGetIdFromFeature(feat, out var id))
|
|
||||||
{
|
|
||||||
markers.SetMarkerFocused(id, true);
|
|
||||||
Mapa.Cursor = System.Windows.Input.Cursors.Hand;
|
|
||||||
OnMarkerClicked(id);
|
OnMarkerClicked(id);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
markers?.ClearMarkerFocused();
|
|
||||||
OnMarkerClicked(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (info?.Layer == MapaPlantacao_Layer && feat is MIFeature roadFeature)
|
else if (info?.Layer == MapaPlantacao_Layer && feat is MIFeature roadFeature)
|
||||||
{
|
{
|
||||||
HighlightRoad(roadFeature);
|
HighlightRoad(roadFeature);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OnMarkerClicked(null);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -492,7 +493,9 @@ namespace OperationControl.Controls
|
||||||
var info = Mapa.GetMapInfo(sp, Mapa.Map.Layers /*, 18*/);
|
var info = Mapa.GetMapInfo(sp, Mapa.Map.Layers /*, 18*/);
|
||||||
var feat = info?.Feature;
|
var feat = info?.Feature;
|
||||||
|
|
||||||
if ((feat != null && markers != null && markers.TryGetIdFromFeature(feat, out _)) || feat != null)
|
if (feat != null && markers != null && markers.TryGetIdFromFeature(feat, out _))
|
||||||
|
Mapa.Cursor = System.Windows.Input.Cursors.Hand;
|
||||||
|
else if (feat != null && info?.Layer == MapaPlantacao_Layer && feat is MIFeature roadFeature)
|
||||||
Mapa.Cursor = System.Windows.Input.Cursors.Hand;
|
Mapa.Cursor = System.Windows.Input.Cursors.Hand;
|
||||||
else
|
else
|
||||||
Mapa.Cursor = System.Windows.Input.Cursors.Arrow;
|
Mapa.Cursor = System.Windows.Input.Cursors.Arrow;
|
||||||
|
|
@ -777,6 +780,52 @@ namespace OperationControl.Controls
|
||||||
return dict.TryGetValue(fieldName, out var v) ? v : null;
|
return dict.TryGetValue(fieldName, out var v) ? v : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AgroBase.Models.MapaFeatureCollectionModel CriarDadosMapa()
|
||||||
|
{
|
||||||
|
AgroBase.Models.MapaFeatureCollectionModel _mapa = new AgroBase.Models.MapaFeatureCollectionModel() { type = "FeatureCollection", features = new List<AgroBase.Models.MapaFeatureModel>() };
|
||||||
|
foreach (var x in RuasMapaCarregado.Where(x => x.Selected))
|
||||||
|
{
|
||||||
|
string id = ((dynamic)x.Feature).Id.ToString();
|
||||||
|
string type = ((dynamic)x.Feature).Geometry.GeometryType;
|
||||||
|
string s = ((dynamic)x.Feature).Geometry.CoordinateSequence.ToString();
|
||||||
|
s = s.Trim().TrimStart('(').TrimEnd(')');
|
||||||
|
var pairs = s.Split("),", StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
var coordinates = new List<List<double>>();
|
||||||
|
foreach (var p in pairs)
|
||||||
|
{
|
||||||
|
var clean = p.Replace("(", "").Replace(")", "").Trim();
|
||||||
|
var parts = clean.Split(',', StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
if (parts.Length == 2 && double.TryParse(parts[0], System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out double lon) && double.TryParse(parts[1], System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out double lat))
|
||||||
|
{
|
||||||
|
coordinates.Add(new List<double> { lon, lat });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AgroBase.Models.MapaFeatureGeometryModel geometry = new AgroBase.Models.MapaFeatureGeometryModel()
|
||||||
|
{
|
||||||
|
id = GetAttr(x.Feature, "Id"),
|
||||||
|
type = type,
|
||||||
|
coordinates = coordinates
|
||||||
|
};
|
||||||
|
|
||||||
|
_mapa.features.Add(new AgroBase.Models.MapaFeatureModel()
|
||||||
|
{
|
||||||
|
type = "Feature",
|
||||||
|
geometry = geometry,
|
||||||
|
properties = new AgroBase.Models.MapaFeaturePropertiesModel()
|
||||||
|
{
|
||||||
|
Id = GetAttr(x.Feature, "Id"),
|
||||||
|
Dist1 = double.Parse(GetAttr(x.Feature, "Dist1")),
|
||||||
|
Dist2 = double.Parse(GetAttr(x.Feature, "Dist2")),
|
||||||
|
Length = double.Parse(GetAttr(x.Feature, "Length")),
|
||||||
|
Name = GetAttr(x.Feature, "Name")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return _mapa;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MapMarkerManager
|
public class MapMarkerManager
|
||||||
|
|
@ -805,6 +854,14 @@ namespace OperationControl.Controls
|
||||||
private readonly Layer _layer;
|
private readonly Layer _layer;
|
||||||
public Layer Layer { get { return _layer; } }
|
public Layer Layer { get { return _layer; } }
|
||||||
|
|
||||||
|
public enum MarkerStatus
|
||||||
|
{
|
||||||
|
Normal,
|
||||||
|
Warning,
|
||||||
|
Error,
|
||||||
|
Offline
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public bool Added(string id)
|
public bool Added(string id)
|
||||||
|
|
@ -826,6 +883,7 @@ namespace OperationControl.Controls
|
||||||
|
|
||||||
public void SetMarkerFocused(string id, bool focused)
|
public void SetMarkerFocused(string id, bool focused)
|
||||||
{
|
{
|
||||||
|
ClearMarkerFocused();
|
||||||
var f = _features.FirstOrDefault(x => x.Id == id);
|
var f = _features.FirstOrDefault(x => x.Id == id);
|
||||||
if (f != null) f.Focused = focused;
|
if (f != null) f.Focused = focused;
|
||||||
}
|
}
|
||||||
|
|
@ -856,7 +914,7 @@ namespace OperationControl.Controls
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddMarker(string id, double lat, double lon, double headingDeg, System.Windows.Media.Color color, string? label = null, bool center = false)
|
public void AddMarker(string id, bool isBase, double? lat = null, double? lon = null, double? heading = null, System.Windows.Media.Color? color = null, string? label = null, StatusOperacao? status = null, bool? pulv = null, bool center = false)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(id)) throw new ArgumentException("id inválido", nameof(id));
|
if (string.IsNullOrWhiteSpace(id)) throw new ArgumentException("id inválido", nameof(id));
|
||||||
|
|
||||||
|
|
@ -865,7 +923,7 @@ namespace OperationControl.Controls
|
||||||
var marker = _features.FirstOrDefault(x => x.Id == id);
|
var marker = _features.FirstOrDefault(x => x.Id == id);
|
||||||
if (marker != null)
|
if (marker != null)
|
||||||
{
|
{
|
||||||
marker.UpdateData(lat, lon, headingDeg, label, color);
|
marker.UpdateData(lat: lat, lon: lon, heading: heading, label: label, color: color, status: status, pulverizando: pulv);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -873,15 +931,18 @@ namespace OperationControl.Controls
|
||||||
{
|
{
|
||||||
Id = id,
|
Id = id,
|
||||||
Features = new List<MIFeature>(),
|
Features = new List<MIFeature>(),
|
||||||
Color = color,
|
Color = color ?? GetColorForMarker(id, isBase),
|
||||||
Heading = headingDeg,
|
Heading = heading ?? 0,
|
||||||
Lat = lat,
|
Lat = lat ?? 0,
|
||||||
Lon = lon,
|
Lon = lon ?? 0,
|
||||||
Label = lbl,
|
Label = lbl,
|
||||||
Seta = new List<GeometryFeature>(),
|
Seta = new List<GeometryFeature>(),
|
||||||
|
Status = status ?? StatusOperacao.NaoIniciado,
|
||||||
|
Pulverizando = pulv ?? false,
|
||||||
|
Focused = false
|
||||||
};
|
};
|
||||||
marker.CreateTrajectory(_map);
|
marker.CreateTrajectory(_map);
|
||||||
marker.UpdateData(lat, lon, headingDeg);
|
marker.UpdateData();
|
||||||
_features.Add(marker);
|
_features.Add(marker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -891,12 +952,26 @@ namespace OperationControl.Controls
|
||||||
_map.Map?.Navigator?.CenterOn(marker.Point.Point);
|
_map.Map?.Navigator?.CenterOn(marker.Point.Point);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateMarkerPosition(string id, double lat, double lon, double headingDeg, bool pulv = false)
|
public void UpdateMarkerPosition(string id, double? lat = null, double? lon = null, double? heading = null, List<double[]>? predict = null)
|
||||||
{
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(id)) throw new ArgumentException("id inválido", nameof(id));
|
||||||
|
|
||||||
var marker = _features.FirstOrDefault(x => x.Id == id);
|
var marker = _features.FirstOrDefault(x => x.Id == id);
|
||||||
if (marker == null) return;
|
if (marker == null) return;
|
||||||
|
|
||||||
marker.UpdateData(lat, lon, headingDeg, pulverizando: pulv);
|
marker.UpdateData(lat: lat, lon: lon, heading: heading, predict: predict);
|
||||||
|
|
||||||
|
UpdateFeatures();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateMarkerInfo(string id, StatusOperacao? status = null, bool? pulv = null)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(id)) throw new ArgumentException("id inválido", nameof(id));
|
||||||
|
|
||||||
|
var marker = _features.FirstOrDefault(x => x.Id == id);
|
||||||
|
if (marker == null) return;
|
||||||
|
|
||||||
|
marker.UpdateData(status: status, pulverizando: pulv);
|
||||||
|
|
||||||
UpdateFeatures();
|
UpdateFeatures();
|
||||||
}
|
}
|
||||||
|
|
@ -922,10 +997,19 @@ namespace OperationControl.Controls
|
||||||
Style = null
|
Style = null
|
||||||
};
|
};
|
||||||
_map.Map!.Layers.Add(_trajLayer);
|
_map.Map!.Layers.Add(_trajLayer);
|
||||||
|
_predProvider = new MemoryProvider(_predFeatures);
|
||||||
|
_predLayer = new Layer
|
||||||
|
{
|
||||||
|
Name = $"pred_{Id}",
|
||||||
|
DataSource = _predProvider,
|
||||||
|
Style = null
|
||||||
|
};
|
||||||
|
_map.Map!.Layers.Add(_predLayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
public bool Focused { get; set; }
|
public bool Focused { get; set; }
|
||||||
|
public bool Pulverizando { get; set; }
|
||||||
public PointFeature Point { get; set; }
|
public PointFeature Point { get; set; }
|
||||||
public List<MIFeature> Features { get; set; }
|
public List<MIFeature> Features { get; set; }
|
||||||
public double Lat { get; set; }
|
public double Lat { get; set; }
|
||||||
|
|
@ -933,18 +1017,23 @@ namespace OperationControl.Controls
|
||||||
public double Heading { get; set; }
|
public double Heading { get; set; }
|
||||||
public string Label { get; set; }
|
public string Label { get; set; }
|
||||||
public System.Windows.Media.Color Color { get; set; }
|
public System.Windows.Media.Color Color { get; set; }
|
||||||
|
public StatusOperacao Status { get; set; }
|
||||||
public List<GeometryFeature> Seta { get; set; }
|
public List<GeometryFeature> Seta { get; set; }
|
||||||
public Coordinate Position { get; set; }
|
public Coordinate Position { get; set; }
|
||||||
|
public List<double[]> Predict { get; set; }
|
||||||
|
|
||||||
public void UpdateData(double lat, double lon, double heading, string? label = null, System.Windows.Media.Color? color = null, bool pulverizando = false)
|
public void UpdateData(double? lat = null, double? lon = null, double? heading = null, string? label = null, System.Windows.Media.Color? color = null, bool? pulverizando = null, StatusOperacao? status = null, List<double[]>? predict = null)
|
||||||
{
|
{
|
||||||
Features.Clear();
|
Features.Clear();
|
||||||
|
|
||||||
Lat = lat;
|
if (lat != null) Lat = (double)lat;
|
||||||
Lon = lon;
|
if (lon != null) Lon = (double)lon;
|
||||||
Heading = heading;
|
if (heading != null) Heading = (double)heading;
|
||||||
if (label != null) Label = label;
|
if (label != null) Label = label;
|
||||||
if (color != null) Color = (System.Windows.Media.Color)color;
|
if (color != null) Color = (System.Windows.Media.Color)color;
|
||||||
|
if (status != null) Status = (StatusOperacao)status;
|
||||||
|
if (pulverizando != null) Pulverizando = (bool)pulverizando;
|
||||||
|
if (predict != null) Predict = predict;
|
||||||
|
|
||||||
var (x, y) = Mapsui.Projections.SphericalMercator.FromLonLat(Lon, Lat);
|
var (x, y) = Mapsui.Projections.SphericalMercator.FromLonLat(Lon, Lat);
|
||||||
var newPoint = new MPoint(x, y);
|
var newPoint = new MPoint(x, y);
|
||||||
|
|
@ -957,7 +1046,10 @@ namespace OperationControl.Controls
|
||||||
Features.Add(Point);
|
Features.Add(Point);
|
||||||
Seta.ForEach(f => Features.Add(f));
|
Seta.ForEach(f => Features.Add(f));
|
||||||
|
|
||||||
UpdateRoverPosition(pulverizando);
|
if (lat != null || lon != null)
|
||||||
|
UpdateRoverPosition();
|
||||||
|
if (predict != null)
|
||||||
|
UpdatePredictTrajectory();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpsertHeadingFeature(MPoint centerWorld, bool withArrowHead = true)
|
private void UpsertHeadingFeature(MPoint centerWorld, bool withArrowHead = true)
|
||||||
|
|
@ -1024,55 +1116,129 @@ namespace OperationControl.Controls
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetStyles()
|
private void SetStyles(double _pulseFactor = 1.0)
|
||||||
{
|
{
|
||||||
if (Point.Styles == null) Point.Styles = new List<IStyle>();
|
if (Point.Styles == null) Point.Styles = new List<IStyle>();
|
||||||
else Point.Styles.Clear();
|
else Point.Styles.Clear();
|
||||||
|
|
||||||
// cor base
|
// Pega o “visual” conforme o Status
|
||||||
var c = new Mapsui.Styles.Color(Color.R, Color.G, Color.B, Color.A);
|
var (baseColor, statusGlyph, labelBackColor) = GetStatusVisual();
|
||||||
|
|
||||||
// 1) Ponto central minúsculo (precisão)
|
// 1) Ponto central minúsculo (precisão)
|
||||||
Point.Styles.Add(new SymbolStyle
|
Point.Styles.Add(new SymbolStyle
|
||||||
{
|
{
|
||||||
SymbolScale = 0.22, // ponto bem pequeno
|
SymbolScale = 0.22,
|
||||||
Fill = new Brush(c),
|
Fill = new Brush(baseColor),
|
||||||
Outline = null
|
Outline = null
|
||||||
});
|
});
|
||||||
|
|
||||||
// 2) “Aura” simulando gradiente (3 círculos com alpha/escala crescentes)
|
// 2) “Aura” simulando gradiente (3 círculos com alpha/escala crescentes)
|
||||||
Point.Styles.Add(new SymbolStyle
|
Point.Styles.Add(new SymbolStyle
|
||||||
{
|
{
|
||||||
SymbolScale = 0.55,
|
SymbolScale = _pulseFactor * 0.55,
|
||||||
Fill = new Brush(new Mapsui.Styles.Color(c.R, c.G, c.B, 120)),
|
Fill = new Brush(new Color(baseColor.R, baseColor.G, baseColor.B, 120)),
|
||||||
Outline = null
|
Outline = null
|
||||||
});
|
});
|
||||||
Point.Styles.Add(new SymbolStyle
|
Point.Styles.Add(new SymbolStyle
|
||||||
{
|
{
|
||||||
SymbolScale = 0.95,
|
SymbolScale = _pulseFactor * 0.95,
|
||||||
Fill = new Brush(new Mapsui.Styles.Color(c.R, c.G, c.B, 70)),
|
Fill = new Brush(new Color(baseColor.R, baseColor.G, baseColor.B, 70)),
|
||||||
Outline = null
|
Outline = null
|
||||||
});
|
});
|
||||||
Point.Styles.Add(new SymbolStyle
|
Point.Styles.Add(new SymbolStyle
|
||||||
{
|
{
|
||||||
SymbolScale = 1.4,
|
SymbolScale = _pulseFactor * 1.4,
|
||||||
Fill = new Brush(new Mapsui.Styles.Color(c.R, c.G, c.B, 30)),
|
Fill = new Brush(new Color(baseColor.R, baseColor.G, baseColor.B, 30)),
|
||||||
Outline = null
|
Outline = null
|
||||||
});
|
});
|
||||||
|
|
||||||
// 3) Rótulo do id (pequeno, acima do ponto)
|
// 3) Rótulo do id (pequeno, acima do ponto)
|
||||||
if (!string.IsNullOrWhiteSpace(Label))
|
if (!string.IsNullOrWhiteSpace(Label))
|
||||||
{
|
{
|
||||||
|
// texto: se tiver glyph, coloca na frente
|
||||||
|
var texto = string.IsNullOrEmpty(statusGlyph)
|
||||||
|
? Label
|
||||||
|
: $"{Label} {statusGlyph}";
|
||||||
|
|
||||||
|
var backColor = labelBackColor ?? new Color(0, 0, 0, 140);
|
||||||
|
|
||||||
Point.Styles.Add(new LabelStyle
|
Point.Styles.Add(new LabelStyle
|
||||||
{
|
{
|
||||||
Text = Label,
|
Text = texto,
|
||||||
ForeColor = Mapsui.Styles.Color.White,
|
ForeColor = Mapsui.Styles.Color.White,
|
||||||
BackColor = new Brush(new Mapsui.Styles.Color(0, 0, 0, 140)),
|
BackColor = new Brush(backColor),
|
||||||
Offset = new Offset(0, -30)
|
Offset = new Offset(0, -30),
|
||||||
|
Font = new Font { FontFamily = "Segoe UI Emoji", Size = 18 }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private (Mapsui.Styles.Color baseColor, string statusGlyph, Mapsui.Styles.Color? labelBackColor) GetStatusVisual()
|
||||||
|
{
|
||||||
|
string glyph = "";
|
||||||
|
Mapsui.Styles.Color? back = null;
|
||||||
|
|
||||||
|
// Base default = cor do robô (personalizada)
|
||||||
|
var baseColor = new Mapsui.Styles.Color(Color.R, Color.G, Color.B, Color.A);
|
||||||
|
|
||||||
|
switch (Status)
|
||||||
|
{
|
||||||
|
case StatusOperacao.NaoIniciado:
|
||||||
|
glyph = "⏳";
|
||||||
|
baseColor = new Mapsui.Styles.Color(150, 150, 150, 255); // cinza médio
|
||||||
|
back = new Mapsui.Styles.Color(60, 60, 60, 160); // cinza escuro translúcido
|
||||||
|
break;
|
||||||
|
|
||||||
|
case StatusOperacao.Parametrizando:
|
||||||
|
glyph = "🔧";
|
||||||
|
baseColor = new Mapsui.Styles.Color(40, 120, 255, 255); // azul forte
|
||||||
|
back = new Mapsui.Styles.Color(100, 160, 255, 140); // azul claro translúcido
|
||||||
|
break;
|
||||||
|
|
||||||
|
case StatusOperacao.Calibrando:
|
||||||
|
glyph = "🎯";
|
||||||
|
baseColor = new Mapsui.Styles.Color(160, 70, 255, 255); // roxo vibrante
|
||||||
|
back = new Mapsui.Styles.Color(180, 120, 255, 140); // roxo suave
|
||||||
|
break;
|
||||||
|
|
||||||
|
case StatusOperacao.Aguardando:
|
||||||
|
glyph = "💤";
|
||||||
|
baseColor = new Mapsui.Styles.Color(0, 110, 140, 255); // azul petróleo
|
||||||
|
back = new Mapsui.Styles.Color(0, 150, 180, 140); // turquesa suave
|
||||||
|
break;
|
||||||
|
|
||||||
|
case StatusOperacao.EmAndamento:
|
||||||
|
glyph = "▶";
|
||||||
|
baseColor = new Mapsui.Styles.Color(0, 220, 40, 255); // verde limão
|
||||||
|
back = new Mapsui.Styles.Color(0, 200, 30, 140); // verde limão translúcido
|
||||||
|
break;
|
||||||
|
|
||||||
|
case StatusOperacao.Parado:
|
||||||
|
glyph = "⏸";
|
||||||
|
baseColor = new Mapsui.Styles.Color(255, 180, 0, 255); // amarelo dourado
|
||||||
|
back = new Mapsui.Styles.Color(255, 210, 80, 140); // amarelo claro suaaave
|
||||||
|
break;
|
||||||
|
|
||||||
|
case StatusOperacao.Concluido:
|
||||||
|
glyph = "✔";
|
||||||
|
baseColor = new Mapsui.Styles.Color(0, 150, 60, 255); // verde escuro
|
||||||
|
back = new Mapsui.Styles.Color(0, 130, 50, 140); // verde escuro suave
|
||||||
|
break;
|
||||||
|
|
||||||
|
case StatusOperacao.Erro:
|
||||||
|
glyph = "⛔";
|
||||||
|
baseColor = new Mapsui.Styles.Color(220, 40, 40, 255);
|
||||||
|
back = new Mapsui.Styles.Color(120, 0, 0, 190);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
glyph = "";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (baseColor, glyph, back);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#region TRAJETORIA
|
#region TRAJETORIA
|
||||||
|
|
||||||
|
|
@ -1080,9 +1246,9 @@ namespace OperationControl.Controls
|
||||||
private Layer _trajLayer;
|
private Layer _trajLayer;
|
||||||
private List<MIFeature> _trajFeatures { get; set; } = new List<MIFeature>();
|
private List<MIFeature> _trajFeatures { get; set; } = new List<MIFeature>();
|
||||||
|
|
||||||
private VectorStyle CreateTrajectoryStyle(string roverId, bool pulverizando)
|
private VectorStyle CreateTrajectoryStyle()
|
||||||
{
|
{
|
||||||
if (pulverizando)
|
if (Pulverizando)
|
||||||
{
|
{
|
||||||
return new VectorStyle
|
return new VectorStyle
|
||||||
{
|
{
|
||||||
|
|
@ -1098,7 +1264,7 @@ namespace OperationControl.Controls
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateRoverPosition(bool pulverizando)
|
public void UpdateRoverPosition()
|
||||||
{
|
{
|
||||||
var (x, y) = Mapsui.Projections.SphericalMercator.FromLonLat(Lon, Lat);
|
var (x, y) = Mapsui.Projections.SphericalMercator.FromLonLat(Lon, Lat);
|
||||||
var newCoord = new Coordinate(x, y);
|
var newCoord = new Coordinate(x, y);
|
||||||
|
|
@ -1109,8 +1275,8 @@ namespace OperationControl.Controls
|
||||||
Geometry = line
|
Geometry = line
|
||||||
};
|
};
|
||||||
gf["RoverId"] = Id;
|
gf["RoverId"] = Id;
|
||||||
gf["Pulverizando"] = pulverizando ? "1" : "0";
|
gf["Pulverizando"] = Pulverizando ? "1" : "0";
|
||||||
gf.Styles.Add(CreateTrajectoryStyle(Id, pulverizando));
|
gf.Styles.Add(CreateTrajectoryStyle());
|
||||||
_trajFeatures.Add(gf);
|
_trajFeatures.Add(gf);
|
||||||
_trajLayer.DataSource = new MemoryProvider(_trajFeatures);
|
_trajLayer.DataSource = new MemoryProvider(_trajFeatures);
|
||||||
_trajLayer.DataHasChanged();
|
_trajLayer.DataHasChanged();
|
||||||
|
|
@ -1118,6 +1284,67 @@ namespace OperationControl.Controls
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region SIMULACAO
|
||||||
|
|
||||||
|
private MemoryProvider _predProvider;
|
||||||
|
private Layer _predLayer;
|
||||||
|
private List<MIFeature> _predFeatures { get; set; } = new List<MIFeature>();
|
||||||
|
|
||||||
|
public void UpdatePredictTrajectory()
|
||||||
|
{
|
||||||
|
if (_predLayer == null || Predict == null || Predict.Count < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_predFeatures.Clear();
|
||||||
|
|
||||||
|
// Converte lista (lon, lat) -> coordenadas em SphericalMercator
|
||||||
|
var coords = new List<Coordinate>();
|
||||||
|
foreach (var lon_lat in Predict)
|
||||||
|
{
|
||||||
|
double lon = lon_lat[0];
|
||||||
|
double lat = lon_lat[1];
|
||||||
|
var (x, y) = Mapsui.Projections.SphericalMercator.FromLonLat(lon, lat);
|
||||||
|
coords.Add(new Coordinate(x, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Garante que tem pelo menos 2 pontos
|
||||||
|
if (coords.Count < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var line = new LineString(coords.ToArray());
|
||||||
|
|
||||||
|
var gf = new GeometryFeature
|
||||||
|
{
|
||||||
|
Geometry = line
|
||||||
|
};
|
||||||
|
|
||||||
|
gf["RoverId"] = Id;
|
||||||
|
gf["Tipo"] = "Predict";
|
||||||
|
|
||||||
|
gf.Styles.Add(CreatePredictStyle());
|
||||||
|
|
||||||
|
_predFeatures.Add(gf);
|
||||||
|
|
||||||
|
_predLayer.DataSource = new MemoryProvider(_predFeatures);
|
||||||
|
_predLayer.DataHasChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private IStyle CreatePredictStyle()
|
||||||
|
{
|
||||||
|
return new VectorStyle
|
||||||
|
{
|
||||||
|
Line = new Pen
|
||||||
|
{
|
||||||
|
Color = Mapsui.Styles.Color.Lime, // verde-limão
|
||||||
|
Width = 2,
|
||||||
|
PenStyle = PenStyle.Dash // linha tracejada
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MarkerClickedEventArgs : EventArgs
|
public class MarkerClickedEventArgs : EventArgs
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
using System;
|
using System.Windows;
|
||||||
using System.Windows;
|
|
||||||
using System.Windows.Controls;
|
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
using UserControl = System.Windows.Controls.UserControl;
|
||||||
|
using Brush = System.Windows.Media.Brush;
|
||||||
|
using Brushes = System.Windows.Media.Brushes;
|
||||||
|
using Color = System.Windows.Media.Color;
|
||||||
|
|
||||||
namespace OperationControl.Controls
|
namespace OperationControl.Controls
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using UserControl = System.Windows.Controls.UserControl;
|
||||||
using System.Windows.Media;
|
|
||||||
|
|
||||||
namespace OperationControl.Controls
|
namespace OperationControl.Controls
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
|
||||||
using System.Windows.Media.Animation;
|
using System.Windows.Media.Animation;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
using UserControl = System.Windows.Controls.UserControl;
|
||||||
|
using Color = System.Windows.Media.Color;
|
||||||
|
|
||||||
namespace OperationControl.Controls
|
namespace OperationControl.Controls
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
using Color = System.Windows.Media.Color;
|
||||||
|
using ColorConverter = System.Windows.Media.ColorConverter;
|
||||||
|
using Brushes = System.Windows.Media.Brushes;
|
||||||
|
using Brush = System.Windows.Media.Brush;
|
||||||
|
using Binding = System.Windows.Data.Binding;
|
||||||
|
|
||||||
namespace OperationControl.Converters
|
namespace OperationControl.Converters
|
||||||
{
|
{
|
||||||
|
|
@ -96,4 +101,27 @@ namespace OperationControl.Converters
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||||
=> Binding.DoNothing;
|
=> Binding.DoNothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class LateralErrorToOffsetConverter : IMultiValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object[] values, Type targetType,
|
||||||
|
object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
if (values.Length < 2) return 0;
|
||||||
|
|
||||||
|
double width = System.Convert.ToDouble(values[0], culture);
|
||||||
|
double errorN = System.Convert.ToDouble(values[1], culture);
|
||||||
|
|
||||||
|
// limite visual: 40% da meia largura
|
||||||
|
double maxFactor = 0.4;
|
||||||
|
|
||||||
|
return errorN * (width * 0.5 * maxFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public object[] ConvertBack(object value, Type[] targetTypes,
|
||||||
|
object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,13 @@ namespace OperationControl.Models
|
||||||
|
|
||||||
public void Inicializar()
|
public void Inicializar()
|
||||||
{
|
{
|
||||||
|
Show();
|
||||||
|
|
||||||
APIService.IniciarRotinas();
|
APIService.IniciarRotinas();
|
||||||
Variaveis.IniciarMQTT();
|
Variaveis.IniciarMQTT();
|
||||||
|
|
||||||
tmrComunicacao.Elapsed += (_, __) => tmrComunicacao_Elapsed();
|
tmrComunicacao.Elapsed += (_, __) => tmrComunicacao_Elapsed();
|
||||||
tmrComunicacao.Start();
|
tmrComunicacao.Start();
|
||||||
|
|
||||||
Show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Show()
|
private void Show()
|
||||||
|
|
@ -36,14 +36,21 @@ namespace OperationControl.Models
|
||||||
{
|
{
|
||||||
if (tmrComunicacaoTicking) return;
|
if (tmrComunicacaoTicking) return;
|
||||||
tmrComunicacaoTicking = true;
|
tmrComunicacaoTicking = true;
|
||||||
if (tmrComunicacaoTicks % VariaveisEquipamento.TempoEntrePingsConexao == 0 && Variaveis.GpsService != null)
|
try
|
||||||
|
{
|
||||||
|
if (tmrComunicacaoTicks % (VariaveisEquipamento.TempoEntrePingsConexao / 1000) == 0 && Variaveis.GpsService != null)
|
||||||
{
|
{
|
||||||
VariaveisControleOperacao.EnviarDadosPosicao(Variaveis.GpsService.UltimaLeitura);
|
VariaveisControleOperacao.EnviarDadosPosicao(Variaveis.GpsService.UltimaLeitura);
|
||||||
}
|
}
|
||||||
|
VariaveisControleOperacao.EnviarDadosHeartbeat();
|
||||||
VariaveisControleOperacao.AtualizarListaRoversNaRede();
|
VariaveisControleOperacao.AtualizarListaRoversNaRede();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
tmrComunicacaoTicks++;
|
tmrComunicacaoTicks++;
|
||||||
tmrComunicacaoTicking = false;
|
tmrComunicacaoTicking = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
using AgroBase.Models;
|
using AgroBase.Models;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Windows;
|
|
||||||
using OperationControl.Services;
|
using OperationControl.Services;
|
||||||
|
using AgroMonitor;
|
||||||
|
using Application = System.Windows.Application;
|
||||||
|
using AgroBase.Models.Operacoes;
|
||||||
|
using Mapsui;
|
||||||
|
|
||||||
namespace OperationControl.Models
|
namespace OperationControl.Models
|
||||||
{
|
{
|
||||||
|
|
@ -29,8 +32,9 @@ namespace OperationControl.Models
|
||||||
|
|
||||||
MqttService = new MqttService("localhost", 1883, "base", true, msg => MostrarLog($"[MQTT localhost:1883] - {msg}"));
|
MqttService = new MqttService("localhost", 1883, "base", true, msg => MostrarLog($"[MQTT localhost:1883] - {msg}"));
|
||||||
|
|
||||||
await MqttService.AdicionarNovoTopico(VariaveisControleOperacao.TopicoMqttRTCM);
|
await MqttService.AdicionarNovoTopico(VariaveisMonitoramento.TopicoMqttPosicao);
|
||||||
await MqttService.AdicionarNovoTopico(VariaveisControleOperacao.TopicoMqttDispositivos, true, 1, async (message) =>
|
await MqttService.AdicionarNovoTopico(VariaveisMonitoramento.TopicoMqttRTCM);
|
||||||
|
await MqttService.AdicionarNovoTopico(VariaveisMonitoramento.TopicoMqttDispositivos, true, 1, async (message) =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -50,18 +54,25 @@ namespace OperationControl.Models
|
||||||
|
|
||||||
public class VariaveisControleOperacao
|
public class VariaveisControleOperacao
|
||||||
{
|
{
|
||||||
public static double LeverArmFrontal { get; } = 0.0;
|
public static double LeverArmFrontal { get; } = 0.0; // cm
|
||||||
public static double LeverArmLateral { get; } = 0.0;
|
public static double LeverArmLateral { get; } = 0.0; // cm
|
||||||
|
|
||||||
public static readonly string BaseMarkerID = "BASE";
|
public static readonly string BaseMarkerID = "BASE";
|
||||||
public static string TopicoMqttDispositivos { get; } = $"agrobot/v1/base/devices";
|
|
||||||
public static string TopicoMqttPosicao { get; } = $"agrobot/v1/base/position";
|
|
||||||
public static string TopicoMqttRTCM { get; } = $"agrobot/v1/base/rtcm";
|
|
||||||
private static readonly object _RoversLock = new object();
|
private static readonly object _RoversLock = new object();
|
||||||
public static Dictionary<string, OperacaoSensoriamentoLogModel> RoversNaRede { get; set; } = new Dictionary<string, OperacaoSensoriamentoLogModel>();
|
private static double TempoRoverVivo = 5.0;
|
||||||
|
private static bool AdicionandoNovoRover = false;
|
||||||
|
private static bool AtualizandoListaRovers = false;
|
||||||
|
public static List<OperacaoParametrosModel> RoversNaRede { get; set; } = new List<OperacaoParametrosModel>();
|
||||||
public static string SelectedRoverId { get; set; } = BaseMarkerID;
|
public static string SelectedRoverId { get; set; } = BaseMarkerID;
|
||||||
|
public static OperacaoParametrosModel? RoverEmFoco => RoversNaRede.FirstOrDefault(x => x.RoverId == SelectedRoverId);
|
||||||
|
public static bool BaseEmFoco => SelectedRoverId == BaseMarkerID;
|
||||||
|
|
||||||
public static async void AdicionarNovoRoverNaRede(string device_id)
|
public static async void AdicionarNovoRoverNaRede(string device_id)
|
||||||
|
{
|
||||||
|
if (AdicionandoNovoRover) return;
|
||||||
|
AdicionandoNovoRover = true;
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(device_id))
|
if (string.IsNullOrEmpty(device_id))
|
||||||
return;
|
return;
|
||||||
|
|
@ -69,89 +80,133 @@ namespace OperationControl.Models
|
||||||
bool rover_ja_adicionado = false;
|
bool rover_ja_adicionado = false;
|
||||||
lock (_RoversLock)
|
lock (_RoversLock)
|
||||||
{
|
{
|
||||||
rover_ja_adicionado = RoversNaRede.ContainsKey(device_id);
|
rover_ja_adicionado = RoversNaRede.Any(x => x.RoverId == device_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rover_ja_adicionado)
|
if (!rover_ja_adicionado)
|
||||||
{
|
{
|
||||||
lock (_RoversLock)
|
lock (_RoversLock)
|
||||||
{
|
{
|
||||||
RoversNaRede.Add(device_id, new OperacaoSensoriamentoLogModel() { Momento = DateTime.Now });
|
RoversNaRede.Add(new OperacaoParametrosModel()
|
||||||
|
{
|
||||||
|
RoverId = device_id,
|
||||||
|
Configurado = false,
|
||||||
|
Alive = true,
|
||||||
|
DadosLeitura = new OperacaoSensoriamentoLogModel()
|
||||||
|
{
|
||||||
|
Momento = DateTime.Now
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool t_hbt_added = Variaveis.MqttService.Topicos.Any(x => x.Topico == VariaveisEquipamento.TopicoMqttHeartbeat.Replace("<id>", device_id));
|
||||||
|
if (!t_hbt_added)
|
||||||
|
await Variaveis.MqttService.AdicionarNovoTopico(VariaveisEquipamento.TopicoMqttHeartbeat.Replace("<id>", device_id));
|
||||||
|
bool t_cmd_added = Variaveis.MqttService.Topicos.Any(x => x.Topico == VariaveisEquipamento.TopicoMqttComandos.Replace("<id>", device_id));
|
||||||
|
if (!t_cmd_added)
|
||||||
await Variaveis.MqttService.AdicionarNovoTopico(VariaveisEquipamento.TopicoMqttComandos.Replace("<id>", device_id));
|
await Variaveis.MqttService.AdicionarNovoTopico(VariaveisEquipamento.TopicoMqttComandos.Replace("<id>", device_id));
|
||||||
|
bool t_tel_added = Variaveis.MqttService.Topicos.Any(x => x.Topico == VariaveisEquipamento.TopicoMqttTelemetria.Replace("<id>", device_id));
|
||||||
|
if (!t_tel_added)
|
||||||
await Variaveis.MqttService.AdicionarNovoTopico(VariaveisEquipamento.TopicoMqttTelemetria.Replace("<id>", device_id), true, 1, async (message) =>
|
await Variaveis.MqttService.AdicionarNovoTopico(VariaveisEquipamento.TopicoMqttTelemetria.Replace("<id>", device_id), true, 1, async (message) =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string json = message.Mensagem;
|
string json = message.Mensagem;
|
||||||
|
if (string.IsNullOrEmpty(json)) return;
|
||||||
var obj = JsonConvert.DeserializeObject<OperacaoSensoriamentoLogModel>(json);
|
var obj = JsonConvert.DeserializeObject<OperacaoSensoriamentoLogModel>(json);
|
||||||
lock (_RoversLock)
|
lock (_RoversLock)
|
||||||
{
|
{
|
||||||
RoversNaRede[device_id] = obj;
|
var rover = RoversNaRede.FirstOrDefault(x => x.RoverId == device_id);
|
||||||
|
if (rover != null)
|
||||||
((App)Application.Current).Shell.Main.AtualizarDadosTela_Telemetria(device_id);
|
{
|
||||||
|
obj.Momento = DateTime.Now;
|
||||||
|
rover.DadosLeitura = obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
((App)Application.Current).Shell.Main?.AtualizarDadosTela_Telemetria(device_id);
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Variaveis.MostrarLog($"Erro ao deserializar dados de telemetria do rover {device_id}: {ex.Message}");
|
Variaveis.MostrarLog($"Erro ao deserializar dados de telemetria do rover {device_id}: {ex.Message}");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
bool t_par_added = Variaveis.MqttService.Topicos.Any(x => x.Topico == VariaveisEquipamento.TopicoMqttParametros.Replace("<id>", device_id));
|
||||||
await Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
if (!t_par_added)
|
||||||
|
await Variaveis.MqttService.AdicionarNovoTopico(VariaveisEquipamento.TopicoMqttParametros.Replace("<id>", device_id), true, 1, async (message) =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
List<string> dispositivos_ids = new List<string>() { "BASE" };
|
string json = message.Mensagem;
|
||||||
dispositivos_ids.Union(RoversNaRede.Select(x => x.Key).ToList());
|
if (string.IsNullOrEmpty(json)) return;
|
||||||
((App)Application.Current).Shell.Main.AtualizarListaDispositivos(dispositivos_ids);
|
var obj = JsonConvert.DeserializeObject<OperacaoParametrosModel>(json);
|
||||||
}
|
lock (_RoversLock)
|
||||||
catch (Exception exUi)
|
|
||||||
{
|
{
|
||||||
Variaveis.MostrarLog($"Erro ao atualizar UI lista dispositivos: {exUi.Message}");
|
var rover = RoversNaRede.FirstOrDefault(x => x.RoverId == device_id);
|
||||||
|
if (rover != null)
|
||||||
|
{
|
||||||
|
rover = obj;
|
||||||
}
|
}
|
||||||
}));
|
}
|
||||||
|
((App)Application.Current).Shell.Main?.AtualizarDadosTela_Telemetria(device_id);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Variaveis.MostrarLog($"Erro ao deserializar dados de parametros do rover {device_id}: {ex.Message}");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
List<string> dispositivos_ids = new List<string>() { "BASE" };
|
||||||
|
lock (_RoversLock)
|
||||||
|
{
|
||||||
|
dispositivos_ids = dispositivos_ids.Union(RoversNaRede.Select(x => x.RoverId).ToList()).ToList();
|
||||||
|
}
|
||||||
|
((App)Application.Current).Shell.Main?.AtualizarListaDispositivos(dispositivos_ids);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
AdicionandoNovoRover = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async void AtualizarListaRoversNaRede()
|
public static async void AtualizarListaRoversNaRede()
|
||||||
{
|
{
|
||||||
List<string> rovers_desconectados = new List<string>();
|
if (AtualizandoListaRovers) return;
|
||||||
var rovers_atual = new Dictionary<string, OperacaoSensoriamentoLogModel>();
|
AtualizandoListaRovers = true;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var rovers_atual = new List<OperacaoParametrosModel>();
|
||||||
lock (_RoversLock)
|
lock (_RoversLock)
|
||||||
{
|
{
|
||||||
rovers_atual = new Dictionary<string, OperacaoSensoriamentoLogModel>(RoversNaRede);
|
rovers_atual = new List<OperacaoParametrosModel>(RoversNaRede);
|
||||||
}
|
}
|
||||||
foreach (var rover in rovers_atual)
|
foreach (var rover in rovers_atual)
|
||||||
{
|
{
|
||||||
double tempo_sem_resposta = (DateTime.Now - rover.Value.Momento).TotalSeconds;
|
rover.Alive = (DateTime.Now - rover.DadosLeitura.Momento).TotalSeconds < TempoRoverVivo;
|
||||||
if (tempo_sem_resposta > 5.0)
|
if (!rover.Alive)
|
||||||
{
|
{
|
||||||
rovers_desconectados.Add(rover.Key);
|
((App)Application.Current).Shell.Main?.MAP?.markers?.UpdateMarkerInfo(rover.RoverId, status: AgroBase.Models.Enums.StatusOperacao.Erro);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (var device_id in rovers_desconectados)
|
|
||||||
{
|
|
||||||
lock (_RoversLock)
|
|
||||||
{
|
|
||||||
RoversNaRede.Remove(device_id);
|
|
||||||
|
|
||||||
if (SelectedRoverId == device_id)
|
|
||||||
{
|
|
||||||
((App)Application.Current).Shell.Main.LimparDadosTela_Telemetria();
|
|
||||||
}
|
}
|
||||||
}
|
finally
|
||||||
var topicos_rover = Variaveis.MqttService.Topicos.Where(x => x.Topico.Contains(device_id)).ToList();
|
|
||||||
foreach (var topico in topicos_rover)
|
|
||||||
{
|
{
|
||||||
await Variaveis.MqttService.UnsubscribeAsync(topico);
|
AtualizandoListaRovers = false;
|
||||||
Variaveis.MqttService.Topicos.Remove(topico);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async void EnviarDadosControle(string rover_id, OperacaoControleBaseModel controle)
|
public static async void EnviarDadosHeartbeat()
|
||||||
|
{
|
||||||
|
var topicos = Variaveis.MqttService.Topicos.Where(x => x.Topico.Contains(VariaveisEquipamento.TopicoMqttHeartbeat.Split("/")[VariaveisEquipamento.TopicoMqttHeartbeat.Split("/").Length - 1]));
|
||||||
|
foreach (var topico in topicos)
|
||||||
|
{
|
||||||
|
await Variaveis.MqttService.PublishAsync(topico, "0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async void EnviarDadosControle(string rover_id, OperacaoComandoBaseModel controle)
|
||||||
{
|
{
|
||||||
var topico = Variaveis.MqttService.Topicos.FirstOrDefault(x => x.Topico == VariaveisEquipamento.TopicoMqttComandos.Replace("<id>", rover_id));
|
var topico = Variaveis.MqttService.Topicos.FirstOrDefault(x => x.Topico == VariaveisEquipamento.TopicoMqttComandos.Replace("<id>", rover_id));
|
||||||
if (topico != null)
|
if (topico != null)
|
||||||
|
|
@ -163,7 +218,7 @@ namespace OperationControl.Models
|
||||||
|
|
||||||
public static async void EnviarDadosPosicao(GPSModel posicao)
|
public static async void EnviarDadosPosicao(GPSModel posicao)
|
||||||
{
|
{
|
||||||
var topico = Variaveis.MqttService.Topicos.FirstOrDefault(x => x.Topico == TopicoMqttPosicao);
|
var topico = Variaveis.MqttService.Topicos.FirstOrDefault(x => x.Topico == VariaveisMonitoramento.TopicoMqttPosicao);
|
||||||
if (topico != null)
|
if (topico != null)
|
||||||
{
|
{
|
||||||
string json = JsonConvert.SerializeObject(posicao);
|
string json = JsonConvert.SerializeObject(posicao);
|
||||||
|
|
@ -173,12 +228,74 @@ namespace OperationControl.Models
|
||||||
|
|
||||||
public static async void EnviarDadosCorrecaoRTCM(byte[] correcao)
|
public static async void EnviarDadosCorrecaoRTCM(byte[] correcao)
|
||||||
{
|
{
|
||||||
var topico = Variaveis.MqttService.Topicos.FirstOrDefault(x => x.Topico == TopicoMqttRTCM);
|
var topico = Variaveis.MqttService.Topicos.FirstOrDefault(x => x.Topico == VariaveisMonitoramento.TopicoMqttRTCM);
|
||||||
if (topico != null)
|
if (topico != null)
|
||||||
{
|
{
|
||||||
await Variaveis.MqttService.PublishAsync(topico, correcao);
|
await Variaveis.MqttService.PublishAsync(topico, correcao);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Controle
|
||||||
|
|
||||||
|
public static void EnviarComandoIniciarOperacao(bool iniciar, bool simulador = false)
|
||||||
|
{
|
||||||
|
EnviarDadosControle(SelectedRoverId, new OperacaoComandoBaseModel()
|
||||||
|
{
|
||||||
|
Momento = DateTime.Now,
|
||||||
|
Dispositivo = AgroBase.Models.Enums.T_Code.Mod,
|
||||||
|
Tecla = simulador ? AgroBase.Models.Enums.BotoesJoystick.Share : iniciar ? AgroBase.Models.Enums.BotoesJoystick.PS : AgroBase.Models.Enums.BotoesJoystick.Vazio
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void EnviarComandoTransmissaoVideo(AgroBase.Models.Enums.T_Code disp, bool ligar)
|
||||||
|
{
|
||||||
|
EnviarDadosControle(SelectedRoverId, new OperacaoComandoBaseModel()
|
||||||
|
{
|
||||||
|
Momento = DateTime.Now,
|
||||||
|
Dispositivo = disp,
|
||||||
|
Tecla = ligar ? AgroBase.Models.Enums.BotoesJoystick.L1 : AgroBase.Models.Enums.BotoesJoystick.Vazio
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void EnviarComandoParada(bool? emergencia = null, bool? pausa = null)
|
||||||
|
{
|
||||||
|
var cmd = new OperacaoComandoBaseModel() { Momento = DateTime.Now };
|
||||||
|
if (emergencia != null) cmd.Emergencia = (bool)emergencia;
|
||||||
|
if (pausa != null) cmd.Pausa = (bool)pausa;
|
||||||
|
if (emergencia != null || pausa != null)
|
||||||
|
EnviarDadosControle(SelectedRoverId, cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void EnviarComandoReferenciamento()
|
||||||
|
{
|
||||||
|
EnviarDadosControle(SelectedRoverId, new OperacaoComandoBaseModel()
|
||||||
|
{
|
||||||
|
Momento = DateTime.Now,
|
||||||
|
Tecla = AgroBase.Models.Enums.BotoesJoystick.R3
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void EnviarComandoLeverArm(double valorCm)
|
||||||
|
{
|
||||||
|
EnviarDadosControle(SelectedRoverId, new OperacaoComandoBaseModel()
|
||||||
|
{
|
||||||
|
Momento = DateTime.Now,
|
||||||
|
Dispositivo = AgroBase.Models.Enums.T_Code.Gps,
|
||||||
|
LeverArmLateral = Math.Round(valorCm, 0),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void EnviarParametrosOperacao(OperacaoParametrosModel parametros)
|
||||||
|
{
|
||||||
|
EnviarDadosControle(SelectedRoverId, new OperacaoComandoBaseModel()
|
||||||
|
{
|
||||||
|
Momento = DateTime.Now,
|
||||||
|
Parametros = parametros,
|
||||||
|
Tecla = (!(RoverEmFoco.DadosLeitura?.OperacaoIniciada ?? false) ? AgroBase.Models.Enums.BotoesJoystick.Options : AgroBase.Models.Enums.BotoesJoystick.Vazio)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<UseWPF>true</UseWPF>
|
<UseWPF>true</UseWPF>
|
||||||
|
<UseWindowsForms>True</UseWindowsForms>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
@ -21,6 +22,12 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="BruTile" Version="6.0.0" />
|
<PackageReference Include="BruTile" Version="6.0.0" />
|
||||||
<PackageReference Include="BruTile.MbTiles" Version="6.0.0" />
|
<PackageReference Include="BruTile.MbTiles" Version="6.0.0" />
|
||||||
|
<PackageReference Include="Extended.Wpf.Toolkit" Version="5.0.0" />
|
||||||
|
<PackageReference Include="FFME.Windows" Version="7.0.361-beta.1" />
|
||||||
|
<PackageReference Include="GirCore.Gst-1.0" Version="0.7.0-preview.3" />
|
||||||
|
<PackageReference Include="GirCore.GstVideo-1.0" Version="0.7.0-preview.3" />
|
||||||
|
<PackageReference Include="LibVLCSharp" Version="3.9.4" />
|
||||||
|
<PackageReference Include="LibVLCSharp.WPF" Version="3.9.4" />
|
||||||
<PackageReference Include="Mapsui" Version="5.0.0" />
|
<PackageReference Include="Mapsui" Version="5.0.0" />
|
||||||
<PackageReference Include="Mapsui.Extensions" Version="5.0.0" />
|
<PackageReference Include="Mapsui.Extensions" Version="5.0.0" />
|
||||||
<PackageReference Include="Mapsui.Wpf" Version="5.0.0" />
|
<PackageReference Include="Mapsui.Wpf" Version="5.0.0" />
|
||||||
|
|
@ -31,6 +38,7 @@
|
||||||
<PackageReference Include="OpenTK" Version="4.9.4" />
|
<PackageReference Include="OpenTK" Version="4.9.4" />
|
||||||
<PackageReference Include="ScottPlot.WPF" Version="5.1.57" />
|
<PackageReference Include="ScottPlot.WPF" Version="5.1.57" />
|
||||||
<PackageReference Include="System.IO.Ports" Version="10.0.0" />
|
<PackageReference Include="System.IO.Ports" Version="10.0.0" />
|
||||||
|
<PackageReference Include="VideoLAN.LibVLC.Windows" Version="3.0.21" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,9 @@
|
||||||
<Compile Update="Controls\Bbox3DViewer.xaml.cs">
|
<Compile Update="Controls\Bbox3DViewer.xaml.cs">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Update="Controls\GstVideoView.xaml.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
<Compile Update="Controls\HeadingIndicator.xaml.cs">
|
<Compile Update="Controls\HeadingIndicator.xaml.cs">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|
@ -42,6 +45,9 @@
|
||||||
<Page Update="Controls\Bbox3DViewer.xaml">
|
<Page Update="Controls\Bbox3DViewer.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
|
<Page Update="Controls\GstVideoView.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
<Page Update="Controls\HeadingIndicator.xaml">
|
<Page Update="Controls\HeadingIndicator.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ using AgroBase.Models;
|
||||||
using static AgroBase.Models.Enums;
|
using static AgroBase.Models.Enums;
|
||||||
using OperationControl.Models;
|
using OperationControl.Models;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using Application = System.Windows.Application;
|
||||||
|
|
||||||
namespace OperationControl.Services
|
namespace OperationControl.Services
|
||||||
{
|
{
|
||||||
|
|
@ -1199,6 +1200,7 @@ namespace OperationControl.Services
|
||||||
{
|
{
|
||||||
Models.Variaveis.MostrarLog("Poucas amostras de RTK FIX coletadas. Tente aumentar o tempo ou verificar sinais.");
|
Models.Variaveis.MostrarLog("Poucas amostras de RTK FIX coletadas. Tente aumentar o tempo ou verificar sinais.");
|
||||||
CorrecaoAbsoluta = false;
|
CorrecaoAbsoluta = false;
|
||||||
|
FixLiberado = false;
|
||||||
return CorrecaoAbsoluta;
|
return CorrecaoAbsoluta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1211,6 +1213,7 @@ namespace OperationControl.Services
|
||||||
Models.Variaveis.MostrarLog($"[BASE/FIX] Coordenadas aplicadas (n={nAmostras}):");
|
Models.Variaveis.MostrarLog($"[BASE/FIX] Coordenadas aplicadas (n={nAmostras}):");
|
||||||
Models.Variaveis.MostrarLog($" lat = {lat:0.000000000}, lon = {lon:0.000000000}, h = {h:0.000}");
|
Models.Variaveis.MostrarLog($" lat = {lat:0.000000000}, lon = {lon:0.000000000}, h = {h:0.000}");
|
||||||
CorrecaoAbsoluta = true;
|
CorrecaoAbsoluta = true;
|
||||||
|
FixLiberado = false;
|
||||||
return CorrecaoAbsoluta;
|
return CorrecaoAbsoluta;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:scott="clr-namespace:ScottPlot.WPF;assembly=ScottPlot.WPF"
|
xmlns:scott="clr-namespace:ScottPlot.WPF;assembly=ScottPlot.WPF"
|
||||||
|
xmlns:vlc="clr-namespace:LibVLCSharp.WPF;assembly=LibVLCSharp.WPF"
|
||||||
xmlns:controls="clr-namespace:OperationControl.Controls"
|
xmlns:controls="clr-namespace:OperationControl.Controls"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="Controle da Opearação Agrobot" Height="1025" Width="1920" WindowStartupLocation="CenterScreen" WindowState="Maximized">
|
Title="Controle da Opearação Agrobot" Height="1025" Width="1920" WindowStartupLocation="CenterScreen" WindowState="Maximized">
|
||||||
|
|
@ -26,30 +27,30 @@
|
||||||
<Canvas>
|
<Canvas>
|
||||||
<Label Content="Resumo Operacional" FontWeight="Bold" FontSize="10" HorizontalAlignment="Left" Canvas.Top="-4" VerticalAlignment="Center" Canvas.Left="-2"/>
|
<Label Content="Resumo Operacional" FontWeight="Bold" FontSize="10" HorizontalAlignment="Left" Canvas.Top="-4" VerticalAlignment="Center" Canvas.Left="-2"/>
|
||||||
<Label Content="Rua Atual" FontSize="10" HorizontalAlignment="Center" Canvas.Top="12" VerticalAlignment="Top" RenderTransformOrigin="0.756,0.502"/>
|
<Label Content="Rua Atual" FontSize="10" HorizontalAlignment="Center" Canvas.Top="12" VerticalAlignment="Top" RenderTransformOrigin="0.756,0.502"/>
|
||||||
<controls:ProgressBarText Height="10" Canvas.Left="57" Canvas.Top="19" Width="92" HorizontalAlignment="Left" VerticalAlignment="Center" Value="63"/>
|
<controls:ProgressBarText x:Name="pgbResumo_RuaAtual" Height="10" Canvas.Left="57" Canvas.Top="19" Width="92" HorizontalAlignment="Left" VerticalAlignment="Center" Value="63"/>
|
||||||
<Label Content="74,17 m / 135,84 m (1)" FontSize="10" Canvas.Top="12" HorizontalAlignment="Center" VerticalAlignment="Center" Canvas.Left="154"/>
|
<Label x:Name="lblResumo_RuaAtual" Content="74,17 m / 135,84 m (1)" FontSize="10" Canvas.Top="12" HorizontalAlignment="Center" VerticalAlignment="Center" Canvas.Left="154"/>
|
||||||
<Label Content="Área Total" FontSize="10" HorizontalAlignment="Center" Canvas.Top="28" VerticalAlignment="Top"/>
|
<Label Content="Área Total" FontSize="10" HorizontalAlignment="Center" Canvas.Top="28" VerticalAlignment="Top"/>
|
||||||
<controls:ProgressBarText Height="10" Canvas.Left="57" Canvas.Top="34" Width="92" HorizontalAlignment="Left" VerticalAlignment="Top" Value="78"/>
|
<controls:ProgressBarText x:Name="pgbResumo_AreaTotal" Height="10" Canvas.Left="57" Canvas.Top="34" Width="92" HorizontalAlignment="Left" VerticalAlignment="Top" Value="78"/>
|
||||||
<Label Content="365,32 m / 1.366,10 m" FontSize="10" Canvas.Top="28" HorizontalAlignment="Center" VerticalAlignment="Top" Canvas.Left="154"/>
|
<Label x:Name="lblResumo_AreaTotal" Content="365,32 m / 1.366,10 m" FontSize="10" Canvas.Top="28" HorizontalAlignment="Center" VerticalAlignment="Top" Canvas.Left="154"/>
|
||||||
<Label Content="Bateria" FontSize="10" HorizontalAlignment="Center" Canvas.Top="44" VerticalAlignment="Top"/>
|
<Label Content="Bateria" FontSize="10" HorizontalAlignment="Center" Canvas.Top="44" VerticalAlignment="Top"/>
|
||||||
<controls:ProgressBarText Height="10" Canvas.Left="57" Canvas.Top="51" Width="92" HorizontalAlignment="Left" VerticalAlignment="Top" Value="84"/>
|
<controls:ProgressBarText x:Name="pgbResumo_Bateria" Height="10" Canvas.Left="57" Canvas.Top="51" Width="92" HorizontalAlignment="Left" VerticalAlignment="Top" Value="84"/>
|
||||||
<Label Content="40,85 V (01:36:45)" FontSize="9" HorizontalAlignment="Center" Canvas.Top="44" VerticalAlignment="Center" Canvas.Left="154"/>
|
<Label x:Name="lblResumo_Bateria" Content="40,85 V (01:36:45)" FontSize="9" HorizontalAlignment="Center" Canvas.Top="44" VerticalAlignment="Center" Canvas.Left="154"/>
|
||||||
<Label Content="Herbicida" FontSize="10" HorizontalAlignment="Center" Canvas.Top="60" VerticalAlignment="Top"/>
|
<Label Content="Herbicida" FontSize="10" HorizontalAlignment="Center" Canvas.Top="60" VerticalAlignment="Top"/>
|
||||||
<controls:ProgressBarText Height="10" Canvas.Left="57" Canvas.Top="67" Width="92" HorizontalAlignment="Left" VerticalAlignment="Top" Value="73"/>
|
<controls:ProgressBarText x:Name="pgbResumo_Herbicida" Height="10" Canvas.Left="57" Canvas.Top="67" Width="92" HorizontalAlignment="Left" VerticalAlignment="Top" Value="73"/>
|
||||||
<Label Content="21,90 L (584,32 m)" FontSize="9" HorizontalAlignment="Left" Canvas.Top="60" VerticalAlignment="Center" Canvas.Left="154"/>
|
<Label x:Name="lblResumo_Herbicida" Content="21,90 L (584,32 m)" FontSize="9" HorizontalAlignment="Left" Canvas.Top="60" VerticalAlignment="Center" Canvas.Left="154"/>
|
||||||
<Label Content="Infestação" FontSize="10" Canvas.Top="76" HorizontalAlignment="Center" VerticalAlignment="Top"/>
|
<Label Content="Infestação" FontSize="10" Canvas.Top="76" HorizontalAlignment="Center" VerticalAlignment="Top"/>
|
||||||
<controls:ProgressBarText Height="10" Canvas.Left="57" Canvas.Top="83" Width="92" HorizontalAlignment="Center" VerticalAlignment="Top" Value="23"/>
|
<controls:ProgressBarText x:Name="pgbResumo_Infestacao" Height="10" Canvas.Left="57" Canvas.Top="83" Width="92" HorizontalAlignment="Center" VerticalAlignment="Top" Value="23"/>
|
||||||
<Label Content="234,51 mL/erva" FontSize="9" HorizontalAlignment="Center" Canvas.Top="76" VerticalAlignment="Top" Canvas.Left="154"/>
|
<Label x:Name="lblResumo_Infestacao" Content="234,51 mL/erva" FontSize="9" HorizontalAlignment="Center" Canvas.Top="76" VerticalAlignment="Top" Canvas.Left="154"/>
|
||||||
<Label Content="Conexão" FontSize="10" Canvas.Top="92" HorizontalAlignment="Center" VerticalAlignment="Top"/>
|
<Label Content="Conexão" FontSize="10" Canvas.Top="92" HorizontalAlignment="Center" VerticalAlignment="Top"/>
|
||||||
<controls:ProgressBarText Height="10" Canvas.Left="57" Canvas.Top="99" Width="92" HorizontalAlignment="Center" VerticalAlignment="Top" Value="97"/>
|
<controls:ProgressBarText x:Name="pgbResumo_Conexao" Height="10" Canvas.Left="57" Canvas.Top="99" Width="92" HorizontalAlignment="Center" VerticalAlignment="Top" Value="97"/>
|
||||||
<Label Content="4,9 dBi (574,65 m)" FontSize="9" HorizontalAlignment="Center" Canvas.Top="92" VerticalAlignment="Top" Canvas.Left="154"/>
|
<Label x:Name="lblResumo_Conexao" Content="4,9 dBi (574,65 m)" FontSize="9" HorizontalAlignment="Center" Canvas.Top="92" VerticalAlignment="Top" Canvas.Left="154"/>
|
||||||
|
|
||||||
<Label Content="Operação Liberado" FontSize="10" Canvas.Top="12" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="286"/>
|
<Label x:Name="lblResumo_OperacaoLiberada" Content="Operação Liberado" FontFamily="Segoe UI Emoji" FontSize="10" Canvas.Top="12" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="286"/>
|
||||||
<Label Content="Modo Automático" FontSize="10" Canvas.Top="28" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="286"/>
|
<Label x:Name="lblResumo_OperacaoModo" Content="Modo Automático" FontSize="10" Canvas.Top="28" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="286"/>
|
||||||
<Label Content="Status EmAndamento" FontSize="10" Canvas.Top="44" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="286"/>
|
<Label x:Name="lblResumo_OperacaoStatus" Content="Status EmAndamento" FontSize="10" Canvas.Top="44" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="286"/>
|
||||||
<Label Content="Carro CaminhandoRua" FontSize="10" Canvas.Top="60" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="286"/>
|
<Label x:Name="lblResumo_StatusCarro" Content="Carro CaminhandoRua" FontSize="10" Canvas.Top="60" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="286"/>
|
||||||
<Label Content="Temperatura 45,32°C" FontSize="10" Canvas.Top="76" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="286"/>
|
<Label x:Name="lblResumo_TemperaturaGeral" Content="Temperatura 45,32°C" FontSize="10" Canvas.Top="76" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="286"/>
|
||||||
<Label Content="Duração 00:23:15 / 00:54:15" FontSize="10" Canvas.Top="92" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="286"/>
|
<Label x:Name="lblResumo_OperacaoDuracao" Content="Duração 00:23:15 / 00:54:15" FontSize="10" Canvas.Top="92" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="286"/>
|
||||||
|
|
||||||
|
|
||||||
</Canvas>
|
</Canvas>
|
||||||
|
|
@ -143,8 +144,13 @@
|
||||||
<Label x:Name="lblGNSS_Correcao" Content="Correção RTKFixo B 1,3 s" HorizontalAlignment="Center" VerticalAlignment="Top" Canvas.Top="16" FontSize="9"/>
|
<Label x:Name="lblGNSS_Correcao" Content="Correção RTKFixo B 1,3 s" HorizontalAlignment="Center" VerticalAlignment="Top" Canvas.Top="16" FontSize="9"/>
|
||||||
<Label x:Name="lblGNSS_Satelites" Content="Satélites 29 (0,60 cm)" HorizontalAlignment="Center" VerticalAlignment="Top" Canvas.Top="29" FontSize="9"/>
|
<Label x:Name="lblGNSS_Satelites" Content="Satélites 29 (0,60 cm)" HorizontalAlignment="Center" VerticalAlignment="Top" Canvas.Top="29" FontSize="9"/>
|
||||||
<Label x:Name="lblGNSS_Altitude" Content="Altitude 634,21 m" HorizontalAlignment="Left" VerticalAlignment="Top" Canvas.Left="-1" Canvas.Top="42" FontSize="9"/>
|
<Label x:Name="lblGNSS_Altitude" Content="Altitude 634,21 m" HorizontalAlignment="Left" VerticalAlignment="Top" Canvas.Left="-1" Canvas.Top="42" FontSize="9"/>
|
||||||
<Button x:Name="btnGNSS_FixarBase" Content="Fixar" Canvas.Left="127" Canvas.Top="17" Click="btnGNSS_FixarBase_Click" HorizontalAlignment="Left" VerticalAlignment="Center" Width="50"/>
|
|
||||||
<Label x:Name="lblGNSS_Progresso" Content="0,00%" HorizontalAlignment="Right" VerticalAlignment="Center" Canvas.Left="143" Canvas.Top="42" FontSize="9"/>
|
<Slider x:Name="sldGNSS_LeverArm" Canvas.Left="67" Canvas.Top="1" Width="116" HorizontalAlignment="Center" Height="18" VerticalAlignment="Center" Maximum="5" Minimum="-5" TickFrequency="1" Value="0" ValueChanged="sldGNSS_LeverArm_ValueChanged"/>
|
||||||
|
<Label x:Name="lblGNSS_Progresso" Content="0,00%" HorizontalAlignment="Center" VerticalAlignment="Top" Canvas.Left="143" Canvas.Top="16" FontSize="9"/>
|
||||||
|
<Button x:Name="btnGNSS_FixarBase" Content="Fixar" Canvas.Left="127" Canvas.Top="42" Click="btnGNSS_FixarBase_Click" HorizontalAlignment="Center" VerticalAlignment="Center" Width="50"/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</Canvas>
|
</Canvas>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
|
|
@ -154,25 +160,28 @@
|
||||||
<Canvas Height="64" VerticalAlignment="Bottom">
|
<Canvas Height="64" VerticalAlignment="Bottom">
|
||||||
<Label Content="Parâmetros da Operação" FontWeight="Bold" FontSize="11" Canvas.Top="-3" HorizontalAlignment="Center" VerticalAlignment="Top"/>
|
<Label Content="Parâmetros da Operação" FontWeight="Bold" FontSize="11" Canvas.Top="-3" HorizontalAlignment="Center" VerticalAlignment="Top"/>
|
||||||
<Label Content="Vel. com Ervas" FontSize="9" Canvas.Top="15" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
<Label Content="Vel. com Ervas" FontSize="9" Canvas.Top="15" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||||
<Label Content="Vel. sem Ervas" FontSize="9" Canvas.Top="30" HorizontalAlignment="Center" VerticalAlignment="Top" Canvas.Left="1"/>
|
<Label Content="Vel. sem Ervas" FontSize="9" Canvas.Top="30" HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
||||||
<Label Content="Angulo Máximo" FontSize="9" Canvas.Top="45" HorizontalAlignment="Center" VerticalAlignment="Top" Canvas.Left="1"/>
|
<Label Content="Angulo Máx" FontSize="9" Canvas.Top="45" HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
||||||
<TextBox Canvas.Left="73" TextWrapping="Wrap" Text="1,5" Canvas.Top="19" Width="30" FontSize="9" HorizontalAlignment="Left" VerticalAlignment="Center" TextAlignment="Center" ToolTip="Velocidade que o equipamento se move quando há presença de ervas no radar, em km/h"/>
|
<TextBox x:Name="txtParametros_VelCErvas" Canvas.Left="64" TextWrapping="Wrap" Text="1,5" Canvas.Top="19" Width="25" FontSize="9" HorizontalAlignment="Left" VerticalAlignment="Center" TextAlignment="Center" ToolTip="Velocidade que o equipamento se move quando há presença de ervas no radar, em km/h"/>
|
||||||
<TextBox Canvas.Left="73" TextWrapping="Wrap" Text="3,5" Canvas.Top="34" Width="30" FontSize="9" HorizontalAlignment="Left" VerticalAlignment="Center" TextAlignment="Center" ToolTip="Velocidade que o equipamento se move quando não há presença de ervas no radar, em km/h"/>
|
<TextBox x:Name="txtParametros_VelSErvas" Canvas.Left="64" TextWrapping="Wrap" Text="3,5" Canvas.Top="34" Width="25" FontSize="9" HorizontalAlignment="Left" VerticalAlignment="Center" TextAlignment="Center" ToolTip="Velocidade que o equipamento se move quando não há presença de ervas no radar, em km/h"/>
|
||||||
<TextBox Canvas.Left="73" TextWrapping="Wrap" Text="30" Canvas.Top="49" Width="30" FontSize="9" HorizontalAlignment="Left" VerticalAlignment="Center" TextAlignment="Center" ToolTip="Angulo máximo de controle direcional, em graus"/>
|
<TextBox x:Name="txtParametros_AngMax" Canvas.Left="64" TextWrapping="Wrap" Text="30" Canvas.Top="49" Width="25" FontSize="9" HorizontalAlignment="Left" VerticalAlignment="Center" TextAlignment="Center" ToolTip="Angulo máximo de controle direcional, em graus"/>
|
||||||
<Label Content="km/h" FontSize="9" Canvas.Top="15" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="100"/>
|
<Label Content="Início Atuação" FontSize="9" Canvas.Top="15" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="93"/>
|
||||||
<Label Content="km/h" FontSize="9" Canvas.Top="30" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="100"/>
|
<Label Content="Area Atuação" FontSize="9" Canvas.Top="30" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="93"/>
|
||||||
<Label Content="°" FontSize="9" Canvas.Top="45" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="100"/>
|
<Label Content="Pressão Linha" FontSize="9" Canvas.Top="45" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="93"/>
|
||||||
<Label Content="Ervas % ROI" FontSize="9" Canvas.Top="15" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="130"/>
|
<TextBox x:Name="txtParametros_RoiAtuacao" Canvas.Left="156" TextWrapping="Wrap" Text="70" Canvas.Top="19" Width="25" FontSize="9" HorizontalAlignment="Left" VerticalAlignment="Center" TextAlignment="Center" ToolTip="Percentual da imagem onde a erva detectada envia o comando para atuação dos bicos pulverizadores, onde 100% em cima e 0% em baixo"/>
|
||||||
<Label Content="Ervas % Area" FontSize="9" Canvas.Top="30" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="130"/>
|
<TextBox x:Name="txtParametros_AreaAtuacao" Canvas.Left="156" TextWrapping="Wrap" Text="10" Canvas.Top="34" Width="25" FontSize="9" HorizontalAlignment="Left" VerticalAlignment="Center" TextAlignment="Center" ToolTip="Percentual de altura da imagem para atuação dos bicos quando as ervas entrarem nessa região"/>
|
||||||
<Label Content="Pressão Linha" FontSize="9" Canvas.Top="45" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="130"/>
|
<TextBox x:Name="txtParametros_PressaoLiha" Canvas.Left="156" TextWrapping="Wrap" Text="85" Canvas.Top="49" Width="25" FontSize="9" HorizontalAlignment="Left" VerticalAlignment="Center" TextAlignment="Center" ToolTip="Pressão da linha, em psi"/>
|
||||||
<TextBox Canvas.Left="194" TextWrapping="Wrap" Text="70" Canvas.Top="19" Width="30" FontSize="9" HorizontalAlignment="Left" VerticalAlignment="Center" TextAlignment="Center" ToolTip="Percentual da imagem onde a erva detectada envia o comando para atuação dos bicos pulverizadores, onde 100% em cima e 0% em baixo"/>
|
<Label Content="Erva % On" FontSize="9" Canvas.Top="15" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="185"/>
|
||||||
<TextBox Canvas.Left="194" TextWrapping="Wrap" Text="10" Canvas.Top="34" Width="30" FontSize="9" HorizontalAlignment="Left" VerticalAlignment="Center" TextAlignment="Center" ToolTip="Percentual de ervas detectada sobre a região de um bico para ligar e desligar o bico pulverizador"/>
|
<Label Content="Erva % Off" FontSize="9" Canvas.Top="30" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="185"/>
|
||||||
<TextBox Canvas.Left="194" TextWrapping="Wrap" Text="85" Canvas.Top="49" Width="30" FontSize="9" HorizontalAlignment="Left" VerticalAlignment="Center" TextAlignment="Center" ToolTip="Pressão da linha, em psi"/>
|
<Label Content="Tempo On" FontSize="9" Canvas.Top="45" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="185"/>
|
||||||
<Label Content="psi" FontSize="9" Canvas.Top="45" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="224"/>
|
<TextBox x:Name="txtParametros_PctErvaOn" Canvas.Left="234" TextWrapping="Wrap" Text="2" Canvas.Top="19" Width="25" FontSize="9" HorizontalAlignment="Left" VerticalAlignment="Center" TextAlignment="Center" ToolTip="Percentual de ervas detectado na região de um bico para ligar o bico pulverizador"/>
|
||||||
<CheckBox Content="Modo Manual" Canvas.Left="249" Canvas.Top="2" FontSize="9" VerticalAlignment="Top" ToolTip="Ativa controle manual do equipamento selecionado" HorizontalAlignment="Left"/>
|
<TextBox x:Name="txtParametros_PctErvaOff" Canvas.Left="234" TextWrapping="Wrap" Text="1" Canvas.Top="34" Width="25" FontSize="9" HorizontalAlignment="Left" VerticalAlignment="Center" TextAlignment="Center" ToolTip="Percentual de ervas detectado na região de um bico para desligar o bico pulverizador"/>
|
||||||
<CheckBox Content="Pulverizador Automático" Canvas.Left="249" Canvas.Top="18" FontSize="10" HorizontalAlignment="Center" VerticalAlignment="Top" ToolTip="Atuação automática do pulverizador ao detectar ervas no radar sobre a área de um bico"/>
|
<TextBox x:Name="txtParametros_TempoOn" Canvas.Left="234" TextWrapping="Wrap" Text="200" Canvas.Top="49" Width="25" FontSize="9" HorizontalAlignment="Left" VerticalAlignment="Center" TextAlignment="Center" ToolTip="Tempo em que o bico pulverizador fica atuado após detectar a erva, em milissegundos"/>
|
||||||
<CheckBox Content="Frenagem Automática" Canvas.Left="249" Canvas.Top="33" FontSize="10" HorizontalAlignment="Left" VerticalAlignment="Center" ToolTip="Acionamento automático dos freios ao detectar obstáculos próximos"/>
|
<CheckBox x:Name="chbParametros_Sonar" Content="Sonar Ativado" Canvas.Left="265" Canvas.Top="18" FontSize="10" HorizontalAlignment="Center" VerticalAlignment="Top" ToolTip="Utilizar dados do sonar na tomada de decisão de controle direcional automático"/>
|
||||||
<CheckBox Content="Sonar Ativado" Canvas.Left="249" Canvas.Top="48" FontSize="10" HorizontalAlignment="Left" VerticalAlignment="Center" ToolTip="Utilizar dados do sonar na tomada de decisão de controle direcional automático"/>
|
<CheckBox x:Name="chbParametros_Frenagem" Content="Frenagem Automática" Canvas.Left="265" Canvas.Top="33" FontSize="10" HorizontalAlignment="Center" VerticalAlignment="Top" ToolTip="Acionamento automático dos freios ao detectar obstáculos próximos"/>
|
||||||
|
<CheckBox x:Name="chbParametros_Pulverizador" Content="Pulverizador Automático" Canvas.Left="265" Canvas.Top="48" FontSize="10" HorizontalAlignment="Center" VerticalAlignment="Top" ToolTip="Atuação automática do pulverizador ao detectar ervas no radar sobre a área de um bico"/>
|
||||||
|
<Button x:Name="btnParametros_Salvar" Content="💾" FontSize="10" Canvas.Left="372" Canvas.Top="3" Click="btnParametros_Salvar_Click" HorizontalAlignment="Left" VerticalAlignment="Center" ToolTip="Salva os ajustes realizados nos parâmetros da operação, e envia para o equipamento em foco"/>
|
||||||
|
<Button x:Name="btnParametros_Atualizar" Content="🔄" FontSize="10" Canvas.Left="351" Canvas.Top="3" Click="btnParametros_Atualizar_Click" HorizontalAlignment="Left" VerticalAlignment="Center" ToolTip="Atualiza os dados de parâmetros da operação do equipaento em foco"/>
|
||||||
</Canvas>
|
</Canvas>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
|
|
@ -186,27 +195,27 @@
|
||||||
|
|
||||||
<Border x:Name="brdControle" Margin="659,0,877,943">
|
<Border x:Name="brdControle" Margin="659,0,877,943">
|
||||||
<Canvas>
|
<Canvas>
|
||||||
<controls:ManualControlPad x:Name="PadCtl" MaxSteerDeg="90" SpeedSpKmh="3.2" SpeedCurKmh="3.31" AngleSpDeg="2.92" AngleCurDeg="2.4" MoveType="MovimentoDiagonal"/>
|
<controls:ManualControlPad x:Name="CTRL"/>
|
||||||
</Canvas>
|
</Canvas>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<Border Name="brdMapaInfo" BorderBrush="Black" BorderThickness="1" Height="26" Width="980" Canvas.Top="878" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="465,951,0,0">
|
<Border Name="brdMapaInfo" BorderBrush="Black" BorderThickness="1" Height="26" Width="980" Canvas.Top="878" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="465,951,0,0">
|
||||||
<Canvas>
|
<Canvas>
|
||||||
<Label Content="Próximo Ponto: 15 | Aproximando | Distância próximo ponto: 1,32 m | Distância ponto anterior: 0,74 m | Corredor: Dentro | Margem: Não | Disância Esquerda: 34 cm | Distância Direita: 36 cm | Status: CaminhandoRua" FontSize="9" HorizontalAlignment="Center" VerticalAlignment="Top" Canvas.Top="1"/>
|
<Label x:Name="lblMapaInfo_Debug" Content="Próximo Ponto: 15 | Aproximando | Distância próximo ponto: 1,32 m | Distância ponto anterior: 0,74 m | Corredor: Dentro | Margem: Não | Disância Esquerda: 34 cm | Distância Direita: 36 cm | Status: CaminhandoRua" FontSize="9" HorizontalAlignment="Center" VerticalAlignment="Top" Canvas.Top="1"/>
|
||||||
</Canvas>
|
</Canvas>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<Border x:Name="brdCameraFrontal" BorderBrush="Black" BorderThickness="1" CornerRadius="8" Margin="1453,0,7,735">
|
<Border x:Name="brdCameraFrontal" BorderBrush="Black" BorderThickness="1" CornerRadius="8" Margin="1453,0,7,735">
|
||||||
<Canvas>
|
<Canvas>
|
||||||
<Label Content="Câmera frontal | 12 fps | 230 kbps | 0,00% cana | 43 cm - 27 cm | 12,95° | CaminhandoRua" FontSize="10" HorizontalAlignment="Center" VerticalAlignment="Top" Canvas.Top="-3"/>
|
<Label Content="Câmera frontal | 12 fps | 230 kbps | 0,00% cana | 43 cm - 27 cm | 12,95° | CaminhandoRua" FontSize="10" HorizontalAlignment="Center" VerticalAlignment="Top" Canvas.Top="-3"/>
|
||||||
<Image HorizontalAlignment="Center" Height="243" VerticalAlignment="Top" Width="438" Source="/Resources/caminho.jpeg" Stretch="UniformToFill" Canvas.Top="21" Canvas.Left="10"/>
|
<vlc:VideoView x:Name="VideoFront" Background="Black" Height="237" Width="438" HorizontalAlignment="Center" Canvas.Top="25" VerticalAlignment="Top" Canvas.Left="10"/>
|
||||||
</Canvas>
|
</Canvas>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<Border x:Name="brdCameraTraseira" BorderBrush="Black" BorderThickness="1" CornerRadius="8" Margin="1453,281,7,491">
|
<Border x:Name="brdCameraTraseira" BorderBrush="Black" BorderThickness="1" CornerRadius="8" Margin="1453,281,7,491">
|
||||||
<Canvas>
|
<Canvas>
|
||||||
<Label Content="Câmera traseira | 10 fps | 193 kbps | 5,41% erva | 0,00% cana" FontSize="10" HorizontalAlignment="Center" VerticalAlignment="Top" Canvas.Top="-3"/>
|
<Label Content="Câmera traseira | 10 fps | 193 kbps | 5,41% erva | 0,00% cana" FontSize="10" HorizontalAlignment="Center" VerticalAlignment="Top" Canvas.Top="-3"/>
|
||||||
<Image HorizontalAlignment="Left" Height="201" VerticalAlignment="Center" Width="438" Source="/Resources/solo.jpeg" Stretch="UniformToFill" Canvas.Top="21" Canvas.Left="10"/>
|
<vlc:VideoView x:Name="VideoWeed" Background="Black" Height="200" Width="438" HorizontalAlignment="Center" Canvas.Top="25" VerticalAlignment="Top" Canvas.Left="10"/>
|
||||||
</Canvas>
|
</Canvas>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,14 @@ using OperationControl.Services;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
using DotSpatial.Projections.Transforms;
|
||||||
|
using System;
|
||||||
|
using LibVLCSharp.Shared;
|
||||||
|
using MediaPlayer = LibVLCSharp.Shared.MediaPlayer;
|
||||||
|
using System.IO;
|
||||||
|
using ComboBox = System.Windows.Controls.ComboBox;
|
||||||
|
using Application = System.Windows.Application;
|
||||||
|
using MessageBox = System.Windows.MessageBox;
|
||||||
|
|
||||||
namespace OperationControl.Windows
|
namespace OperationControl.Windows
|
||||||
{
|
{
|
||||||
|
|
@ -36,6 +44,11 @@ namespace OperationControl.Windows
|
||||||
DispatcherTimer _clock = new DispatcherTimer();
|
DispatcherTimer _clock = new DispatcherTimer();
|
||||||
Random _rand = new Random();
|
Random _rand = new Random();
|
||||||
|
|
||||||
|
private LibVLC _libVLC;
|
||||||
|
private MediaPlayer _playerFront;
|
||||||
|
private MediaPlayer _playerWeed;
|
||||||
|
private Media _mediaFront;
|
||||||
|
private Media _mediaWeed;
|
||||||
|
|
||||||
public MainWindow()
|
public MainWindow()
|
||||||
{
|
{
|
||||||
|
|
@ -71,6 +84,36 @@ namespace OperationControl.Windows
|
||||||
// new AgroBase.Models.LivoxBboxModel{ cx=3.0, cy=-0.7, cz=0.6, d=0.8, w=0.5, h=1.2 },
|
// new AgroBase.Models.LivoxBboxModel{ cx=3.0, cy=-0.7, cz=0.6, d=0.8, w=0.5, h=1.2 },
|
||||||
//});
|
//});
|
||||||
|
|
||||||
|
|
||||||
|
// Opções focadas em baixa latência
|
||||||
|
_libVLC = new LibVLC(
|
||||||
|
"--network-caching=1000", // ms (ajusta depois)
|
||||||
|
"--clock-jitter=0",
|
||||||
|
"--clock-synchro=0"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Player da câmera frontal
|
||||||
|
_playerFront = new MediaPlayer(_libVLC);
|
||||||
|
VideoFront.MediaPlayer = _playerFront;
|
||||||
|
_playerWeed = new MediaPlayer(_libVLC);
|
||||||
|
VideoWeed.MediaPlayer = _playerWeed;
|
||||||
|
|
||||||
|
|
||||||
|
Loaded += MainWindow_Loaded;
|
||||||
|
Closed += MainWindow_Closed;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MainWindow_Closed(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
PararStreamCameraFrontal(true);
|
||||||
|
PararStreamCameraErvas(true);
|
||||||
|
_libVLC?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PushSample(bool initial = false)
|
private void PushSample(bool initial = false)
|
||||||
|
|
@ -150,6 +193,10 @@ namespace OperationControl.Windows
|
||||||
#region DISPOSITIVOS
|
#region DISPOSITIVOS
|
||||||
|
|
||||||
public void AtualizarListaDispositivos(List<string> dispositivos)
|
public void AtualizarListaDispositivos(List<string> dispositivos)
|
||||||
|
{
|
||||||
|
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
cmbDispositivo.Items.Clear();
|
cmbDispositivo.Items.Clear();
|
||||||
foreach (var d in dispositivos)
|
foreach (var d in dispositivos)
|
||||||
|
|
@ -161,25 +208,24 @@ namespace OperationControl.Windows
|
||||||
{
|
{
|
||||||
MAP.markers.AddMarker(
|
MAP.markers.AddMarker(
|
||||||
d,
|
d,
|
||||||
Variaveis.GpsService?.UltimaLeitura?.Latitude ?? 0,
|
true,
|
||||||
Variaveis.GpsService?.UltimaLeitura?.Longitude ?? 0,
|
lat: Variaveis.GpsService?.UltimaLeitura?.Latitude ?? 0,
|
||||||
Variaveis.GpsService?.UltimaLeitura?.OrientacaoReal ?? 0,
|
lon: Variaveis.GpsService?.UltimaLeitura?.Longitude ?? 0,
|
||||||
MAP.markers.GetColorForMarker(d, isBase: true),
|
heading: Variaveis.GpsService?.UltimaLeitura?.OrientacaoReal ?? 0,
|
||||||
"Base"
|
label: "Base"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var rover = VariaveisControleOperacao.RoversNaRede.FirstOrDefault(x => x.Key == d);
|
var rover = VariaveisControleOperacao.RoversNaRede.FirstOrDefault(x => x.RoverId == d);
|
||||||
if (rover.Value != null)
|
if (rover != null)
|
||||||
{
|
{
|
||||||
MAP.markers.AddMarker(
|
MAP.markers.AddMarker(
|
||||||
d,
|
d,
|
||||||
rover.Value.Gps?.Latitude ?? 0,
|
false,
|
||||||
rover.Value.Gps?.Longitude ?? 0,
|
lat: rover.DadosLeitura?.Gps?.Latitude ?? 0,
|
||||||
rover.Value.Gps?.AnguloCarroDefinido ?? 0,
|
lon: rover.DadosLeitura?.Gps?.Longitude ?? 0,
|
||||||
MAP.markers.GetColorForMarker(d, isBase: false),
|
heading: rover.DadosLeitura?.Gps?.AnguloCarroDefinido ?? 0
|
||||||
rover.Key
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -189,104 +235,175 @@ namespace OperationControl.Windows
|
||||||
if (idx_selected > -1)
|
if (idx_selected > -1)
|
||||||
cmbDispositivo.SelectedIndex = idx_selected;
|
cmbDispositivo.SelectedIndex = idx_selected;
|
||||||
}
|
}
|
||||||
|
catch (Exception exUi)
|
||||||
|
{
|
||||||
|
Variaveis.MostrarLog($"Erro ao atualizar UI lista dispositivos: {exUi.Message}");
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
private void cmbDispositivo_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
|
private void cmbDispositivo_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
AtualizarDadosTela_Telemetria(((ComboBox)sender).SelectedValue.ToString());
|
var selecionado = ((ComboBox)sender).SelectedItem;
|
||||||
|
if (selecionado == null) return;
|
||||||
|
bool dados_base = selecionado == VariaveisControleOperacao.BaseMarkerID;
|
||||||
|
if (dados_base && !VariaveisControleOperacao.BaseEmFoco)
|
||||||
|
{
|
||||||
|
PararStreamCameraFrontal();
|
||||||
|
PararStreamCameraErvas();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LimparDadosTela_Telemetria()
|
VariaveisControleOperacao.SelectedRoverId = selecionado.ToString();
|
||||||
|
MAP.markers.SetMarkerFocused(selecionado.ToString(), true);
|
||||||
|
AtualizarDadosTela_Telemetria(selecionado.ToString());
|
||||||
|
|
||||||
|
brdResumo.IsEnabled = !dados_base;
|
||||||
|
brdDiagnostico.IsEnabled = !dados_base;
|
||||||
|
brdControle.IsEnabled = !dados_base;
|
||||||
|
brdAjustesOperacao.IsEnabled = !dados_base;
|
||||||
|
if (!dados_base)
|
||||||
{
|
{
|
||||||
VariaveisControleOperacao.SelectedRoverId = "";
|
sldGNSS_LeverArm.Value = VariaveisControleOperacao.RoverEmFoco.DadosLeitura?.Gps?.LeverArmLateral ?? 0;
|
||||||
|
btnParametros_Atualizar_Click(sender, e);
|
||||||
|
IniciarStreamCameraFrontal();
|
||||||
|
IniciarStreamCameraErvas();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LimparDadosTela_Telemetria(string rover_id)
|
||||||
|
{
|
||||||
|
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(rover_id))
|
||||||
|
{
|
||||||
|
//MAP.markers.RemoveMarker(rover_id);
|
||||||
|
//cmbDispositivo.Items.Remove(rover_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//cmbDispositivo.SelectedIndex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception exUi)
|
||||||
|
{
|
||||||
|
Variaveis.MostrarLog($"Erro ao atualizar UI telemetria (clear): {exUi.Message}");
|
||||||
|
}
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AtualizarDadosTela_Telemetria(string rover_id)
|
public void AtualizarDadosTela_Telemetria(string rover_id)
|
||||||
{
|
{
|
||||||
|
bool dados_base = rover_id == VariaveisControleOperacao.BaseMarkerID;
|
||||||
|
var rover = VariaveisControleOperacao.RoversNaRede.FirstOrDefault(x => x.RoverId == rover_id)?.DadosLeitura;
|
||||||
|
if (dados_base)
|
||||||
|
{
|
||||||
|
MAP.markers.UpdateMarkerPosition(rover_id, lat: Variaveis.GpsService?.UltimaLeitura?.Latitude, lon: Variaveis.GpsService?.UltimaLeitura?.Longitude, heading: Variaveis.GpsService?.UltimaLeitura?.OrientacaoReal);
|
||||||
|
}
|
||||||
|
else if (rover != null)
|
||||||
|
{
|
||||||
|
var simulacao = rover.Controle?.SimulacaoMPC?.Select(x => new double[] { x.longitude, x.latitude })?.ToList();
|
||||||
|
MAP.markers.UpdateMarkerPosition(rover_id, lat: rover?.Gps?.Latitude, lon: rover?.Gps?.Longitude, heading: rover?.Gps?.OrientacaoReal, predict: simulacao);
|
||||||
|
MAP.markers.UpdateMarkerInfo(rover_id, status: rover.StatusOperacao);
|
||||||
|
}
|
||||||
|
|
||||||
if (rover_id != VariaveisControleOperacao.SelectedRoverId) return;
|
if (rover_id != VariaveisControleOperacao.SelectedRoverId) return;
|
||||||
|
|
||||||
|
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
if (rover_id == VariaveisControleOperacao.BaseMarkerID)
|
if (rover_id == VariaveisControleOperacao.BaseMarkerID)
|
||||||
{
|
{
|
||||||
Variaveis.MostrarLog($"Atualizando dados da tela para a base");
|
Variaveis.MostrarLog($"Atualizando dados da tela para a base");
|
||||||
|
|
||||||
AtualizarDadosTela_GNSS(Variaveis.GpsService?.UltimaLeitura ?? new AgroBase.Models.GPSModel());
|
AtualizarDadosTela_GNSS(Variaveis.GpsService?.UltimaLeitura ?? new AgroBase.Models.GPSModel(), marker_id: VariaveisControleOperacao.BaseMarkerID);
|
||||||
AtualizarDadosTela_Heading(Variaveis.GpsService?.UltimaLeitura?.AnguloCarroDefinido ?? 0);
|
AtualizarDadosTela_Heading(Variaveis.GpsService?.UltimaLeitura?.AnguloCarroDefinido ?? 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var rover = VariaveisControleOperacao.RoversNaRede.FirstOrDefault(x => x.Key == rover_id);
|
if (rover == null) return;
|
||||||
if (rover.Value == null) return;
|
|
||||||
|
|
||||||
Variaveis.MostrarLog($"Atualizando dados da tela para o dispositivo {rover_id}");
|
Variaveis.MostrarLog($"Atualizando dados da tela para o dispositivo {rover_id}");
|
||||||
|
|
||||||
AtualizarDadosTela_GNSS(rover.Value.Gps);
|
if (rover.Trajetoria != null)
|
||||||
AtualizarDadosTela_Heading(rover.Value.Gps.AnguloCarroDefinido, rover.Value.Modo == AgroBase.Models.Enums.ModoOperacao.Manual ? double.NaN : rover.Value.Trajetoria.AnguloCaminho);
|
AtualizarDadosTela_Resumo(rover);
|
||||||
AtualizarDadosTela_IMU(rover.Value.IMU.InclinacaoLateral, rover.Value.IMU.InclinacaoFrontal);
|
if (rover.Gps != null)
|
||||||
AtualizarDadostela_LIDAR(rover.Value.LivoxLidar.bboxes);
|
AtualizarDadosTela_GNSS(rover.Gps, marker_id: rover_id);
|
||||||
|
if (rover.Controle != null)
|
||||||
|
AtualizarDadosTela_Controle(rover.Controle, rover.Movimentacao.AnguloMedio, rover.Movimentacao.VelocidadeMedia, rover.Emergencia, !rover.OperacaoIniciada, rover.StatusOperacao == AgroBase.Models.Enums.StatusOperacao.Calibrando);
|
||||||
|
//if (rover.Value.Controle != null)
|
||||||
|
// AtualizarDadosTela_ParametrosOperacao(rover.Value.Controle);
|
||||||
|
if (rover.Trajetoria != null)
|
||||||
|
AtualizarDadosTela_Mapa(rover.Trajetoria);
|
||||||
|
if (rover.Gps != null)
|
||||||
|
AtualizarDadosTela_Heading(rover.Gps.AnguloCarroDefinido, rover.Modo == AgroBase.Models.Enums.ModoOperacao.Manual ? double.NaN : rover.Trajetoria.AnguloCaminho);
|
||||||
|
if (rover.IMU != null)
|
||||||
|
AtualizarDadosTela_IMU(rover.IMU.InclinacaoLateral, rover.IMU.InclinacaoFrontal);
|
||||||
|
if (rover.LivoxLidar != null)
|
||||||
|
AtualizarDadostela_LIDAR(rover.LivoxLidar.bboxes);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
catch (Exception exUi)
|
||||||
|
{
|
||||||
|
Variaveis.MostrarLog($"Erro ao atualizar UI telemetria (set): {exUi.Message}");
|
||||||
|
}
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region IMU
|
#region RESUMO OPERACIONAL
|
||||||
|
|
||||||
public void AtualizarDadosTela_IMU(double roll, double pitch)
|
public void AtualizarDadosTela_Resumo(AgroBase.Models.OperacaoSensoriamentoLogModel dados)
|
||||||
{
|
{
|
||||||
IMU.RollDeg = roll;
|
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||||
IMU.PitchDeg = pitch;
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pgbResumo_RuaAtual.Value = dados.Trajetoria.PercentualRuaAtual;
|
||||||
|
lblResumo_RuaAtual.Content = $"{dados.Trajetoria.CorredorAtual.DistanciaPercorridaCorredor.ToString("0.00")} / {dados.Trajetoria.CorredorAtual.DistanciaTotal.ToString("0.00")}";
|
||||||
|
pgbResumo_AreaTotal.Value = dados.Trajetoria.PercentualOperacao;
|
||||||
|
lblResumo_AreaTotal.Content = $"{dados.Trajetoria.DistanciaPercorrida.ToString("0.00")} / {dados.Trajetoria.DistanciaTotal.ToString("0.00")}";
|
||||||
|
pgbResumo_Bateria.Value = dados.Bateria.PorcentagemBateria;
|
||||||
|
lblResumo_Bateria.Content = $"{dados.Bateria.TensaoInstantanea.ToString("0.00")} V ({dados.Bateria.TempoEstimadoRestanteMinutos})";
|
||||||
|
pgbResumo_Herbicida.Value = dados.Atuador.PercentualReservatorio;
|
||||||
|
lblResumo_Herbicida.Content = $"{dados.Atuador.VolumeReservatorio.ToString("0.00")} L ({0.ToString("0.00")})";
|
||||||
|
pgbResumo_Infestacao.Value = dados.Atuador.PercentualErvasTerreno;
|
||||||
|
lblResumo_Infestacao.Content = $"{dados.Atuador.VazaoMedia.ToString("0.00")}";
|
||||||
|
pgbResumo_Conexao.Value = 0;
|
||||||
|
lblResumo_Conexao.Content = $"0,0 dBi (0,00 m)";
|
||||||
|
|
||||||
|
lblResumo_OperacaoLiberada.Content = $"Operação " + (dados.OperacaoLiberada ? "🔓 Liberada" : "🔒 Bloqueada");
|
||||||
|
lblResumo_OperacaoModo.Content = $"Modo {dados.Modo}";
|
||||||
|
lblResumo_OperacaoStatus.Content = $"Status {dados.StatusOperacao}" + (dados.StatusOperacao == AgroBase.Models.Enums.StatusOperacao.Aguardando ? $" ({dados.TempoAguardandoSeg.ToString("0")})" : "");
|
||||||
|
lblResumo_StatusCarro.Content = $"Carro {dados.Trajetoria.StatusCarro}";
|
||||||
|
lblResumo_TemperaturaGeral.Content = $"Temperatura {(dados.DadosPerformance.CPU_temp ?? 0).ToString("0.00")} °C";
|
||||||
|
lblResumo_OperacaoDuracao.Content = $"Duração {dados.TempoDecorrido.ToString("HH:mm:ss")} / {dados.Trajetoria.TempoEstimadoOperacao}";
|
||||||
}
|
}
|
||||||
|
catch (Exception exUi)
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region HEADING
|
|
||||||
|
|
||||||
public void AtualizarDadosTela_Heading(double headingRover, double headingCourse = double.NaN)
|
|
||||||
{
|
{
|
||||||
HDG.Heading = headingRover;
|
Variaveis.MostrarLog($"Erro ao atualizar UI Resumo: {exUi.Message}");
|
||||||
HDG.CourseHeading = headingCourse;
|
|
||||||
}
|
}
|
||||||
|
}));
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region MAPA
|
|
||||||
|
|
||||||
private void MAP_MarkerClicked(object? sender, MapMarkerManager.MarkerClickedEventArgs e)
|
|
||||||
{
|
|
||||||
Variaveis.MostrarLog($"Rover em foco: {e.MarkerId}");
|
|
||||||
if (string.IsNullOrEmpty(e.MarkerId))
|
|
||||||
{
|
|
||||||
LimparDadosTela_Telemetria();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
VariaveisControleOperacao.SelectedRoverId = e.MarkerId;
|
|
||||||
AtualizarDadosTela_Telemetria(e.MarkerId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MAP_StreetMapClicked(object? sender, MapViewControl.StreetMapClickedEventArgs e)
|
|
||||||
{
|
|
||||||
Variaveis.MostrarLog($"Rua clicada: {e.StreetId}. Ruas selecionadas: {string.Join(",", e.SelectedStreetsIds)}");
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region PULVERIZADOR
|
|
||||||
|
|
||||||
private void btnB0_Click(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
btnB0.Content = (btnB0.Content.ToString() == "Ligar") ? "Desligar" : "Ligar";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region POSICAO
|
#region POSICAO
|
||||||
|
|
||||||
public void AtualizarDadosTela_GNSS(AgroBase.Models.GPSModel dados, string marker_id = null, double progresso = double.NaN)
|
public void AtualizarDadosTela_GNSS(AgroBase.Models.GPSModel dados, string? marker_id = null, double progresso = double.NaN)
|
||||||
{
|
{
|
||||||
lblGNSS_Posicao.Foreground = dados.Inicializado ? new SolidColorBrush(System.Windows.Media.Colors.Green) : new SolidColorBrush(System.Windows.Media.Colors.Red);
|
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bool dados_base = marker_id == VariaveisControleOperacao.BaseMarkerID;
|
||||||
|
|
||||||
|
lblGNSS_Posicao.Foreground = new SolidColorBrush(dados.Inicializado ? System.Windows.Media.Colors.Green : System.Windows.Media.Colors.Red);
|
||||||
lblGNSS_Correcao.Content = $"Correção {dados.QualidadeFix} " +
|
lblGNSS_Correcao.Content = $"Correção {dados.QualidadeFix} " +
|
||||||
(dados.QualidadeFix == AgroBase.Models.Enums.TiposCorrecaoGPS.BaseFix ?
|
(dados.QualidadeFix == AgroBase.Models.Enums.TiposCorrecaoGPS.BaseFix ?
|
||||||
(dados.OrientacaoReal.ToString("0.00") + "°") :
|
(dados.OrientacaoReal.ToString("0.00") + "°") :
|
||||||
|
|
@ -294,30 +411,46 @@ namespace OperationControl.Windows
|
||||||
lblGNSS_Satelites.Content = $"Satélites {dados.NumeroSatelites} ({dados.PrecisaoCm.ToString("0.00")} cm)";
|
lblGNSS_Satelites.Content = $"Satélites {dados.NumeroSatelites} ({dados.PrecisaoCm.ToString("0.00")} cm)";
|
||||||
lblGNSS_Altitude.Content = $"Altitude {dados.Altitude.ToString("0.00")} m";
|
lblGNSS_Altitude.Content = $"Altitude {dados.Altitude.ToString("0.00")} m";
|
||||||
|
|
||||||
|
if (dados_base)
|
||||||
|
{
|
||||||
|
sldGNSS_LeverArm.Visibility = Visibility.Hidden;
|
||||||
if (double.IsNaN(progresso))
|
if (double.IsNaN(progresso))
|
||||||
{
|
{
|
||||||
lblGNSS_Progresso.Visibility = Visibility.Hidden;
|
lblGNSS_Progresso.Visibility = Visibility.Hidden;
|
||||||
btnGNSS_FixarBase.Visibility = Visibility.Hidden;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lblGNSS_Progresso.Visibility = Visibility.Visible;
|
lblGNSS_Progresso.Visibility = Visibility.Visible;
|
||||||
btnGNSS_FixarBase.Visibility = Visibility.Visible;
|
|
||||||
|
|
||||||
lblGNSS_Progresso.Content = $"{progresso.ToString("0.00")}%";
|
lblGNSS_Progresso.Content = $"{progresso.ToString("0.00")}%";
|
||||||
if ((Variaveis.GpsService?.BaseFix?.CorrecaoAbsoluta ?? false) && Variaveis.GpsService.BaseFix.FixLiberado && btnGNSS_FixarBase.Content.ToString() == "Parar")
|
}
|
||||||
|
|
||||||
|
bool gnss_fix_preciso = new List<AgroBase.Models.Enums.TiposCorrecaoGPS>() { AgroBase.Models.Enums.TiposCorrecaoGPS.RTKFixo, AgroBase.Models.Enums.TiposCorrecaoGPS.RTKFlutuante }.Contains(Variaveis.GpsService?.UltimaLeitura?.QualidadeFix ?? AgroBase.Models.Enums.TiposCorrecaoGPS.SemCorrecao);
|
||||||
|
bool gnss_fixado = Variaveis.GpsService?.BaseFix?.CorrecaoAbsoluta ?? false;
|
||||||
|
bool gnss_fixando = btnGNSS_FixarBase.Content.ToString() == "Parar";
|
||||||
|
|
||||||
|
btnGNSS_FixarBase.IsEnabled = (gnss_fix_preciso && !gnss_fixado) || gnss_fixando || gnss_fixado;
|
||||||
|
btnGNSS_FixarBase.Content = gnss_fixado || !gnss_fixando ? "Fixar" : "Parar";
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
Variaveis.GpsService.BaseFix.FixLiberado = false;
|
btnGNSS_FixarBase.IsEnabled = true;
|
||||||
btnGNSS_FixarBase.Content = "Fixar";
|
sldGNSS_LeverArm.Visibility = Visibility.Visible;
|
||||||
|
lblGNSS_Progresso.Visibility = Visibility.Visible;
|
||||||
|
lblGNSS_Progresso.Content = $"{(sldGNSS_LeverArm.Value * 10.0).ToString("0")} cm";
|
||||||
|
lblGNSS_Progresso.Foreground = new SolidColorBrush(Math.Round(sldGNSS_LeverArm.Value * 10.0, 0) == Math.Round(dados.LeverArmLateral, 0) ? System.Windows.Media.Colors.Black : System.Windows.Media.Colors.Red);
|
||||||
|
btnGNSS_FixarBase.Content = "Aplicar";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception exUi)
|
||||||
if (!string.IsNullOrEmpty(marker_id))
|
{
|
||||||
MAP.markers.UpdateMarkerPosition(marker_id, dados.Latitude, dados.Longitude, dados.OrientacaoReal);
|
Variaveis.MostrarLog($"Erro ao atualizar UI GNSS: {exUi.Message}");
|
||||||
|
}
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void btnGNSS_FixarBase_Click(object sender, RoutedEventArgs e)
|
private void btnGNSS_FixarBase_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (VariaveisControleOperacao.BaseEmFoco)
|
||||||
{
|
{
|
||||||
if (!Variaveis.GpsService.BaseFix.FixLiberado)
|
if (!Variaveis.GpsService.BaseFix.FixLiberado)
|
||||||
{
|
{
|
||||||
|
|
@ -344,23 +477,328 @@ namespace OperationControl.Windows
|
||||||
Variaveis.GpsService.BaseFix.FixLiberado = false;
|
Variaveis.GpsService.BaseFix.FixLiberado = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VariaveisControleOperacao.EnviarComandoLeverArm(sldGNSS_LeverArm.Value * 10.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sldGNSS_LeverArm_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
|
||||||
|
{
|
||||||
|
lblGNSS_Progresso.Content = $"{(sldGNSS_LeverArm.Value * 10.0).ToString("0")} cm";
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region CONTROLE
|
||||||
|
|
||||||
|
public void AtualizarDadosTela_Controle(AgroBase.Models.OperacaoControleModel controle, double angulo, double velocidade, bool emergencia, bool pausa, bool refing)
|
||||||
|
{
|
||||||
|
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CTRL.AtualizarDadosControle(
|
||||||
|
angSp: controle.Angulo,
|
||||||
|
angCur: angulo,
|
||||||
|
tipoMov: controle.TipoMovimento,
|
||||||
|
velPct: controle.PercentualVelocidadeSP,
|
||||||
|
velSp: controle.PercentualVelocidadeSPKmh,
|
||||||
|
velKmh: velocidade,
|
||||||
|
emg: emergencia,
|
||||||
|
pause: pausa,
|
||||||
|
refing: refing
|
||||||
|
);
|
||||||
|
}
|
||||||
|
catch (Exception exUi)
|
||||||
|
{
|
||||||
|
Variaveis.MostrarLog($"Erro ao atualizar UI Controle: {exUi.Message}");
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region PARAMETROS DA OPERACAO
|
||||||
|
|
||||||
|
public void AtualizarDadosTela_ParametrosOperacao(AgroBase.Models.Operacoes.OperacaoParametrosControleModel? controle)
|
||||||
|
{
|
||||||
|
if (controle == null) return;
|
||||||
|
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
txtParametros_VelCErvas.Text = controle.MovVelocidadeCErvasPercent.ToString();
|
||||||
|
txtParametros_VelSErvas.Text = controle.MovVelocidadeSErvasPercent.ToString();
|
||||||
|
txtParametros_AngMax.Text = controle.DirAnguloMaximo.ToString();
|
||||||
|
txtParametros_RoiAtuacao.Text = controle.AtuPercentualInicioPulverizacao.ToString();
|
||||||
|
txtParametros_AreaAtuacao.Text = controle.AtuAlturaAreaPulverizacao.ToString();
|
||||||
|
txtParametros_PressaoLiha.Text = controle.AtuPressaoLinha.ToString();
|
||||||
|
txtParametros_PctErvaOn.Text = controle.AtuPercentualErvasBicoOn.ToString();
|
||||||
|
txtParametros_PctErvaOff.Text = controle.AtuPercentualErvasBicoOff.ToString();
|
||||||
|
txtParametros_TempoOn.Text = controle.AtuDuracaoAtuacao.ToString();
|
||||||
|
chbParametros_Pulverizador.IsChecked = controle.PulverizadorAutomatico;
|
||||||
|
chbParametros_Frenagem.IsChecked = controle.FrenagemAutomatica;
|
||||||
|
chbParametros_Sonar.IsChecked = controle.SonarAtivado;
|
||||||
|
}
|
||||||
|
catch (Exception exUi)
|
||||||
|
{
|
||||||
|
Variaveis.MostrarLog($"Erro ao atualizar UI Parametros da Operacao: {exUi.Message}");
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnParametros_Salvar_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var modo = (CTRL.TgManual.IsChecked ?? false) ? AgroBase.Models.Enums.ModoOperacao.Manual : AgroBase.Models.Enums.ModoOperacao.MapaGPS;
|
||||||
|
|
||||||
|
VariaveisControleOperacao.EnviarParametrosOperacao(new AgroBase.Models.Operacoes.OperacaoParametrosModel()
|
||||||
|
{
|
||||||
|
Modo = modo,
|
||||||
|
Descricao = "Operacao da base",
|
||||||
|
QtdCamerasSolo = 1,
|
||||||
|
QtdBicos = 3,
|
||||||
|
CapacidadeReservatorio = 45,
|
||||||
|
|
||||||
|
Controle = new AgroBase.Models.Operacoes.OperacaoParametrosControleModel()
|
||||||
|
{
|
||||||
|
MovimentoAutomatico = modo != AgroBase.Models.Enums.ModoOperacao.Manual,
|
||||||
|
SonarAtivado = chbParametros_Sonar.IsChecked ?? false,
|
||||||
|
FrenagemAutomatica = chbParametros_Frenagem.IsChecked ?? false,
|
||||||
|
MovVelocidadeCErvasPercent = int.Parse(txtParametros_VelCErvas.Text),
|
||||||
|
MovVelocidadeSErvasPercent = int.Parse(txtParametros_VelSErvas.Text),
|
||||||
|
|
||||||
|
DirAnguloMaximo = int.Parse(txtParametros_AngMax.Text),
|
||||||
|
DirTipoMovimento = AgroBase.Models.Enums.TiposControladorDirecional.MPC,
|
||||||
|
DirVelocidadeMovimento = 50,
|
||||||
|
|
||||||
|
PulverizadorAutomatico = chbParametros_Pulverizador.IsChecked ?? false,
|
||||||
|
AtuPercentualErvasBicoOn = double.Parse(txtParametros_PctErvaOn.Text),
|
||||||
|
AtuPercentualErvasBicoOff = double.Parse(txtParametros_PctErvaOff.Text),
|
||||||
|
AtuDuracaoAtuacao = int.Parse(txtParametros_TempoOn.Text),
|
||||||
|
AtuAlturaAreaPulverizacao = double.Parse(txtParametros_AreaAtuacao.Text),
|
||||||
|
AtuPercentualInicioPulverizacao = double.Parse(txtParametros_RoiAtuacao.Text),
|
||||||
|
AtuPressaoLinha = double.Parse(txtParametros_PressaoLiha.Text),
|
||||||
|
},
|
||||||
|
|
||||||
|
ModulosMandatorios = new List<AgroBase.Models.OperacaoModulosMandatoriosModel>(),
|
||||||
|
ParametrosMandatorios = new List<AgroBase.Models.OperacaoParametrosMandatoriosModel>(),
|
||||||
|
|
||||||
|
RuasPercorrer = MAP.RuasMapaCarregado.Where(x => x.Selected).Select(x => x.Id).ToList(),
|
||||||
|
Mapa = MAP.CriarDadosMapa()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnParametros_Atualizar_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
AtualizarDadosTela_ParametrosOperacao(VariaveisControleOperacao.RoverEmFoco?.Controle);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region MAPA
|
||||||
|
|
||||||
|
private void MAP_MarkerClicked(object? sender, MapMarkerManager.MarkerClickedEventArgs e)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(e.MarkerId))
|
||||||
|
{
|
||||||
|
Variaveis.MostrarLog($"Sem rover em foco");
|
||||||
|
LimparDadosTela_Telemetria(e.MarkerId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Variaveis.MostrarLog($"Rover em foco: {e.MarkerId}");
|
||||||
|
int idx = cmbDispositivo.Items.IndexOf(e.MarkerId);
|
||||||
|
cmbDispositivo.SelectedIndex = idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MAP_StreetMapClicked(object? sender, MapViewControl.StreetMapClickedEventArgs e)
|
||||||
|
{
|
||||||
|
Variaveis.MostrarLog($"Rua clicada: {e.StreetId}. Ruas selecionadas: {string.Join(",", e.SelectedStreetsIds)}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AtualizarDadosTela_Mapa(AgroBase.Models.OperacaoSensoriamentoLogTrajetoriaModel Trajetoria)
|
||||||
|
{
|
||||||
|
lblMapaInfo_Debug.Content = $"" +
|
||||||
|
$"Próximo Ponto: {Trajetoria.ProximoPonto.idxPonto} | " +
|
||||||
|
(Trajetoria.ProximoPonto.Aproximando ? "Aproximando" : "Afastando") + " | " +
|
||||||
|
$"Distância próximo ponto: {Trajetoria.ProximoPonto.DistanciaAtual.ToString("0.00")} m | " +
|
||||||
|
$"Distância ponto anterior: {Trajetoria.PontoAtual.DistanciaAtual.ToString("0.00")} m | " +
|
||||||
|
$"Corredor: " + (Trajetoria.CorredorAtual.Dentro ? "Dentro" : "Fora") + " | " +
|
||||||
|
$"Margem: " + (Trajetoria.NaMargemDoCorredor ? "Sim" : "Não") + " | " +
|
||||||
|
$"Disância Esquerda: {(Trajetoria.DistanciaEsquerda * 100.0).ToString("0.00")} cm | " +
|
||||||
|
$"Distância Direita: {(Trajetoria.DistanciaDireita * 100.0).ToString("0.00")} cm | " +
|
||||||
|
$"Status: {Trajetoria.StatusCarro}";
|
||||||
|
|
||||||
|
double erroLateral = (Trajetoria.DistanciaEsquerda - Trajetoria.DistanciaDireita) / 2.0 * 100.0;
|
||||||
|
AtualizarDadosTela_IMU(erro_lateral: erroLateral);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region HEADING
|
||||||
|
|
||||||
|
public void AtualizarDadosTela_Heading(double headingRover, double headingCourse = double.NaN)
|
||||||
|
{
|
||||||
|
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
HDG.Heading = headingRover;
|
||||||
|
HDG.CourseHeading = headingCourse;
|
||||||
|
}
|
||||||
|
catch (Exception exUi)
|
||||||
|
{
|
||||||
|
Variaveis.MostrarLog($"Erro ao atualizar UI Heading: {exUi.Message}");
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IMU
|
||||||
|
|
||||||
|
public void AtualizarDadosTela_IMU(double? roll = null, double? pitch = null, double? erro_lateral = null)
|
||||||
|
{
|
||||||
|
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (roll != null) IMU.RollDeg = (double)roll;
|
||||||
|
if (pitch != null) IMU.PitchDeg = (double)pitch;
|
||||||
|
if (erro_lateral != null) IMU.LateralError = (double)erro_lateral;
|
||||||
|
}
|
||||||
|
catch (Exception exUi)
|
||||||
|
{
|
||||||
|
Variaveis.MostrarLog($"Erro ao atualizar UI IMU: {exUi.Message}");
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region CAMERA FRONTAL
|
||||||
|
|
||||||
|
private void IniciarStreamCameraFrontal()
|
||||||
|
{
|
||||||
|
var path = @"streams\camera_frontal.sdp";
|
||||||
|
|
||||||
|
if (!File.Exists(path))
|
||||||
|
{
|
||||||
|
string stream =
|
||||||
|
"v=0\r\n" +
|
||||||
|
"o=- 0 0 IN IP4 0.0.0.0\r\n" +
|
||||||
|
"s=OAK H264\r\n" +
|
||||||
|
"c=IN IP4 0.0.0.0\r\n" +
|
||||||
|
"t=0 0\r\n" +
|
||||||
|
"m=video 5000 RTP/AVP 96\r\n" +
|
||||||
|
"a=rtpmap:96 H264/90000\r\n" +
|
||||||
|
"a=fmtp:96 packetization-mode=1\r\n";
|
||||||
|
File.WriteAllText(path, stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
_mediaFront?.Dispose(); // limpa antigo, se existir
|
||||||
|
_mediaFront = new Media(_libVLC, path, FromType.FromPath);
|
||||||
|
// _mediaFront.AddOption(":network-caching=150"); // se quiser por arquivo
|
||||||
|
|
||||||
|
_playerFront.Play(_mediaFront);
|
||||||
|
|
||||||
|
VariaveisControleOperacao.EnviarComandoTransmissaoVideo(AgroBase.Models.Enums.T_Code.Snr, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PararStreamCameraFrontal(bool finalizar = false)
|
||||||
|
{
|
||||||
|
_playerFront?.Stop();
|
||||||
|
|
||||||
|
if (finalizar)
|
||||||
|
{
|
||||||
|
_mediaFront?.Dispose();
|
||||||
|
_mediaFront = null;
|
||||||
|
_playerFront?.Dispose();
|
||||||
|
_playerFront = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
VariaveisControleOperacao.EnviarComandoTransmissaoVideo(AgroBase.Models.Enums.T_Code.Snr, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region CAMERA ERVAS
|
||||||
|
|
||||||
|
private void IniciarStreamCameraErvas()
|
||||||
|
{
|
||||||
|
var path = @"streams\camera_ervas.sdp";
|
||||||
|
|
||||||
|
if (!File.Exists(path))
|
||||||
|
{
|
||||||
|
string stream =
|
||||||
|
"v=0\r\n" +
|
||||||
|
"o=- 0 0 IN IP4 0.0.0.0\r\n" +
|
||||||
|
"s=OAK H264\r\n" +
|
||||||
|
"c=IN IP4 0.0.0.0\r\n" +
|
||||||
|
"t=0 0\r\n" +
|
||||||
|
"m=video 5002 RTP/AVP 96\r\n" + // <- porta 5001
|
||||||
|
"a=rtpmap:96 H264/90000\r\n" +
|
||||||
|
"a=fmtp:96 packetization-mode=1\r\n";
|
||||||
|
File.WriteAllText(path, stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
_mediaWeed?.Dispose();
|
||||||
|
_mediaWeed = new Media(_libVLC, path, FromType.FromPath);
|
||||||
|
// _mediaWeed.AddOption(":network-caching=150");
|
||||||
|
|
||||||
|
_playerWeed.Play(_mediaWeed);
|
||||||
|
|
||||||
|
VariaveisControleOperacao.EnviarComandoTransmissaoVideo(AgroBase.Models.Enums.T_Code.Cam, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PararStreamCameraErvas(bool finalizar = false)
|
||||||
|
{
|
||||||
|
_playerWeed?.Stop();
|
||||||
|
|
||||||
|
if (finalizar)
|
||||||
|
{
|
||||||
|
_mediaWeed?.Dispose();
|
||||||
|
_mediaWeed = null;
|
||||||
|
_playerWeed?.Dispose();
|
||||||
|
_playerWeed = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
VariaveisControleOperacao.EnviarComandoTransmissaoVideo(AgroBase.Models.Enums.T_Code.Cam, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region PULVERIZADOR
|
||||||
|
|
||||||
|
private void btnB0_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
btnB0.Content = (btnB0.Content.ToString() == "Ligar") ? "Desligar" : "Ligar";
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region LIDAR
|
#region LIDAR
|
||||||
|
|
||||||
public void AtualizarDadostela_LIDAR(List<AgroBase.Models.LivoxBboxModel> bboxes)
|
public void AtualizarDadostela_LIDAR(List<AgroBase.Models.LivoxBboxModel> bboxes)
|
||||||
|
{
|
||||||
|
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
BBoxes3D.SetBboxes(bboxes);
|
BBoxes3D.SetBboxes(bboxes);
|
||||||
}
|
}
|
||||||
|
catch (Exception exUi)
|
||||||
|
{
|
||||||
|
Variaveis.MostrarLog($"Erro ao atualizar UI Lidar: {exUi.Message}");
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
BIN
AgroBase/OperationControl/bin/Debug/net8.0-windows7.0/FFmpeg.AutoGen.dll (Stored with Git LFS)
Normal file
BIN
AgroBase/OperationControl/bin/Debug/net8.0-windows7.0/FFmpeg.AutoGen.dll (Stored with Git LFS)
Normal file
Binary file not shown.
BIN
AgroBase/OperationControl/bin/Debug/net8.0-windows7.0/GLib-2.0.dll (Stored with Git LFS)
Normal file
BIN
AgroBase/OperationControl/bin/Debug/net8.0-windows7.0/GLib-2.0.dll (Stored with Git LFS)
Normal file
Binary file not shown.
BIN
AgroBase/OperationControl/bin/Debug/net8.0-windows7.0/GObject-2.0.dll (Stored with Git LFS)
Normal file
BIN
AgroBase/OperationControl/bin/Debug/net8.0-windows7.0/GObject-2.0.dll (Stored with Git LFS)
Normal file
Binary file not shown.
BIN
AgroBase/OperationControl/bin/Debug/net8.0-windows7.0/Gst-1.0.dll (Stored with Git LFS)
Normal file
BIN
AgroBase/OperationControl/bin/Debug/net8.0-windows7.0/Gst-1.0.dll (Stored with Git LFS)
Normal file
Binary file not shown.
BIN
AgroBase/OperationControl/bin/Debug/net8.0-windows7.0/GstBase-1.0.dll (Stored with Git LFS)
Normal file
BIN
AgroBase/OperationControl/bin/Debug/net8.0-windows7.0/GstBase-1.0.dll (Stored with Git LFS)
Normal file
Binary file not shown.
BIN
AgroBase/OperationControl/bin/Debug/net8.0-windows7.0/GstVideo-1.0.dll (Stored with Git LFS)
Normal file
BIN
AgroBase/OperationControl/bin/Debug/net8.0-windows7.0/GstVideo-1.0.dll (Stored with Git LFS)
Normal file
Binary file not shown.
BIN
AgroBase/OperationControl/bin/Debug/net8.0-windows7.0/LibVLCSharp.WPF.dll (Stored with Git LFS)
Normal file
BIN
AgroBase/OperationControl/bin/Debug/net8.0-windows7.0/LibVLCSharp.WPF.dll (Stored with Git LFS)
Normal file
Binary file not shown.
BIN
AgroBase/OperationControl/bin/Debug/net8.0-windows7.0/LibVLCSharp.dll (Stored with Git LFS)
Normal file
BIN
AgroBase/OperationControl/bin/Debug/net8.0-windows7.0/LibVLCSharp.dll (Stored with Git LFS)
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
AgroBase/OperationControl/bin/Debug/net8.0-windows7.0/OperationControl.dll (Stored with Git LFS)
BIN
AgroBase/OperationControl/bin/Debug/net8.0-windows7.0/OperationControl.dll (Stored with Git LFS)
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,2 +0,0 @@
|
||||||
from .modeling import *
|
|
||||||
from ._deeplab import convert_to_separable_conv
|
|
||||||
|
|
@ -1,178 +0,0 @@
|
||||||
import torch
|
|
||||||
from torch import nn
|
|
||||||
from torch.nn import functional as F
|
|
||||||
|
|
||||||
from .utils import _SimpleSegmentationModel
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = ["DeepLabV3"]
|
|
||||||
|
|
||||||
|
|
||||||
class DeepLabV3(_SimpleSegmentationModel):
|
|
||||||
"""
|
|
||||||
Implements DeepLabV3 model from
|
|
||||||
`"Rethinking Atrous Convolution for Semantic Image Segmentation"
|
|
||||||
<https://arxiv.org/abs/1706.05587>`_.
|
|
||||||
|
|
||||||
Arguments:
|
|
||||||
backbone (nn.Module): the network used to compute the features for the model.
|
|
||||||
The backbone should return an OrderedDict[Tensor], with the key being
|
|
||||||
"out" for the last feature map used, and "aux" if an auxiliary classifier
|
|
||||||
is used.
|
|
||||||
classifier (nn.Module): module that takes the "out" element returned from
|
|
||||||
the backbone and returns a dense prediction.
|
|
||||||
aux_classifier (nn.Module, optional): auxiliary classifier used during training
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
class DeepLabHeadV3Plus(nn.Module):
|
|
||||||
def __init__(self, in_channels, low_level_channels, num_classes, aspp_dilate=[12, 24, 36]):
|
|
||||||
super(DeepLabHeadV3Plus, self).__init__()
|
|
||||||
self.project = nn.Sequential(
|
|
||||||
nn.Conv2d(low_level_channels, 48, 1, bias=False),
|
|
||||||
nn.BatchNorm2d(48),
|
|
||||||
nn.ReLU(inplace=True),
|
|
||||||
)
|
|
||||||
|
|
||||||
self.aspp = ASPP(in_channels, aspp_dilate)
|
|
||||||
|
|
||||||
self.classifier = nn.Sequential(
|
|
||||||
nn.Conv2d(304, 256, 3, padding=1, bias=False),
|
|
||||||
nn.BatchNorm2d(256),
|
|
||||||
nn.ReLU(inplace=True),
|
|
||||||
nn.Conv2d(256, num_classes, 1)
|
|
||||||
)
|
|
||||||
self._init_weight()
|
|
||||||
|
|
||||||
def forward(self, feature):
|
|
||||||
low_level_feature = self.project( feature['low_level'] )
|
|
||||||
output_feature = self.aspp(feature['out'])
|
|
||||||
output_feature = F.interpolate(output_feature, size=low_level_feature.shape[2:], mode='bilinear', align_corners=False)
|
|
||||||
return self.classifier( torch.cat( [ low_level_feature, output_feature ], dim=1 ) )
|
|
||||||
|
|
||||||
def _init_weight(self):
|
|
||||||
for m in self.modules():
|
|
||||||
if isinstance(m, nn.Conv2d):
|
|
||||||
nn.init.kaiming_normal_(m.weight)
|
|
||||||
elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)):
|
|
||||||
nn.init.constant_(m.weight, 1)
|
|
||||||
nn.init.constant_(m.bias, 0)
|
|
||||||
|
|
||||||
class DeepLabHead(nn.Module):
|
|
||||||
def __init__(self, in_channels, num_classes, aspp_dilate=[12, 24, 36]):
|
|
||||||
super(DeepLabHead, self).__init__()
|
|
||||||
|
|
||||||
self.classifier = nn.Sequential(
|
|
||||||
ASPP(in_channels, aspp_dilate),
|
|
||||||
nn.Conv2d(256, 256, 3, padding=1, bias=False),
|
|
||||||
nn.BatchNorm2d(256),
|
|
||||||
nn.ReLU(inplace=True),
|
|
||||||
nn.Conv2d(256, num_classes, 1)
|
|
||||||
)
|
|
||||||
self._init_weight()
|
|
||||||
|
|
||||||
def forward(self, feature):
|
|
||||||
return self.classifier( feature['out'] )
|
|
||||||
|
|
||||||
def _init_weight(self):
|
|
||||||
for m in self.modules():
|
|
||||||
if isinstance(m, nn.Conv2d):
|
|
||||||
nn.init.kaiming_normal_(m.weight)
|
|
||||||
elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)):
|
|
||||||
nn.init.constant_(m.weight, 1)
|
|
||||||
nn.init.constant_(m.bias, 0)
|
|
||||||
|
|
||||||
class AtrousSeparableConvolution(nn.Module):
|
|
||||||
""" Atrous Separable Convolution
|
|
||||||
"""
|
|
||||||
def __init__(self, in_channels, out_channels, kernel_size,
|
|
||||||
stride=1, padding=0, dilation=1, bias=True):
|
|
||||||
super(AtrousSeparableConvolution, self).__init__()
|
|
||||||
self.body = nn.Sequential(
|
|
||||||
# Separable Conv
|
|
||||||
nn.Conv2d( in_channels, in_channels, kernel_size=kernel_size, stride=stride, padding=padding, dilation=dilation, bias=bias, groups=in_channels ),
|
|
||||||
# PointWise Conv
|
|
||||||
nn.Conv2d( in_channels, out_channels, kernel_size=1, stride=1, padding=0, bias=bias),
|
|
||||||
)
|
|
||||||
|
|
||||||
self._init_weight()
|
|
||||||
|
|
||||||
def forward(self, x):
|
|
||||||
return self.body(x)
|
|
||||||
|
|
||||||
def _init_weight(self):
|
|
||||||
for m in self.modules():
|
|
||||||
if isinstance(m, nn.Conv2d):
|
|
||||||
nn.init.kaiming_normal_(m.weight)
|
|
||||||
elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)):
|
|
||||||
nn.init.constant_(m.weight, 1)
|
|
||||||
nn.init.constant_(m.bias, 0)
|
|
||||||
|
|
||||||
class ASPPConv(nn.Sequential):
|
|
||||||
def __init__(self, in_channels, out_channels, dilation):
|
|
||||||
modules = [
|
|
||||||
nn.Conv2d(in_channels, out_channels, 3, padding=dilation, dilation=dilation, bias=False),
|
|
||||||
nn.BatchNorm2d(out_channels),
|
|
||||||
nn.ReLU(inplace=True)
|
|
||||||
]
|
|
||||||
super(ASPPConv, self).__init__(*modules)
|
|
||||||
|
|
||||||
class ASPPPooling(nn.Sequential):
|
|
||||||
def __init__(self, in_channels, out_channels):
|
|
||||||
super(ASPPPooling, self).__init__(
|
|
||||||
nn.AdaptiveAvgPool2d(1),
|
|
||||||
nn.Conv2d(in_channels, out_channels, 1, bias=False),
|
|
||||||
nn.BatchNorm2d(out_channels),
|
|
||||||
nn.ReLU(inplace=True))
|
|
||||||
|
|
||||||
def forward(self, x):
|
|
||||||
size = x.shape[-2:]
|
|
||||||
x = super(ASPPPooling, self).forward(x)
|
|
||||||
return F.interpolate(x, size=size, mode='bilinear', align_corners=False)
|
|
||||||
|
|
||||||
class ASPP(nn.Module):
|
|
||||||
def __init__(self, in_channels, atrous_rates):
|
|
||||||
super(ASPP, self).__init__()
|
|
||||||
out_channels = 256
|
|
||||||
modules = []
|
|
||||||
modules.append(nn.Sequential(
|
|
||||||
nn.Conv2d(in_channels, out_channels, 1, bias=False),
|
|
||||||
nn.BatchNorm2d(out_channels),
|
|
||||||
nn.ReLU(inplace=True)))
|
|
||||||
|
|
||||||
rate1, rate2, rate3 = tuple(atrous_rates)
|
|
||||||
modules.append(ASPPConv(in_channels, out_channels, rate1))
|
|
||||||
modules.append(ASPPConv(in_channels, out_channels, rate2))
|
|
||||||
modules.append(ASPPConv(in_channels, out_channels, rate3))
|
|
||||||
modules.append(ASPPPooling(in_channels, out_channels))
|
|
||||||
|
|
||||||
self.convs = nn.ModuleList(modules)
|
|
||||||
|
|
||||||
self.project = nn.Sequential(
|
|
||||||
nn.Conv2d(5 * out_channels, out_channels, 1, bias=False),
|
|
||||||
nn.BatchNorm2d(out_channels),
|
|
||||||
nn.ReLU(inplace=True),
|
|
||||||
nn.Dropout(0.1),)
|
|
||||||
|
|
||||||
def forward(self, x):
|
|
||||||
res = []
|
|
||||||
for conv in self.convs:
|
|
||||||
res.append(conv(x))
|
|
||||||
res = torch.cat(res, dim=1)
|
|
||||||
return self.project(res)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def convert_to_separable_conv(module):
|
|
||||||
new_module = module
|
|
||||||
if isinstance(module, nn.Conv2d) and module.kernel_size[0]>1:
|
|
||||||
new_module = AtrousSeparableConvolution(module.in_channels,
|
|
||||||
module.out_channels,
|
|
||||||
module.kernel_size,
|
|
||||||
module.stride,
|
|
||||||
module.padding,
|
|
||||||
module.dilation,
|
|
||||||
module.bias)
|
|
||||||
for name, child in module.named_children():
|
|
||||||
new_module.add_module(name, convert_to_separable_conv(child))
|
|
||||||
return new_module
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
from . import resnet
|
|
||||||
from . import mobilenetv2
|
|
||||||
from . import hrnetv2
|
|
||||||
from . import xception
|
|
||||||
|
|
@ -1,345 +0,0 @@
|
||||||
import torch
|
|
||||||
from torch import nn
|
|
||||||
import torch.nn.functional as F
|
|
||||||
import os
|
|
||||||
|
|
||||||
__all__ = ['HRNet', 'hrnetv2_48', 'hrnetv2_32']
|
|
||||||
|
|
||||||
# Checkpoint path of pre-trained backbone (edit to your path). Download backbone pretrained model hrnetv2-32 @
|
|
||||||
# https://drive.google.com/file/d/1NxCK7Zgn5PmeS7W1jYLt5J9E0RRZ2oyF/view?usp=sharing .Personally, I added the backbone
|
|
||||||
# weights to the folder /checkpoints
|
|
||||||
|
|
||||||
model_urls = {
|
|
||||||
'hrnetv2_32': './checkpoints/model_best_epoch96_edit.pth',
|
|
||||||
'hrnetv2_48': None
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def check_pth(arch):
|
|
||||||
CKPT_PATH = model_urls[arch]
|
|
||||||
if os.path.exists(CKPT_PATH):
|
|
||||||
print(f"Backbone HRNet Pretrained weights at: {CKPT_PATH}, only usable for HRNetv2-32")
|
|
||||||
else:
|
|
||||||
print("No backbone checkpoint found for HRNetv2, please set pretrained=False when calling model")
|
|
||||||
return CKPT_PATH
|
|
||||||
# HRNetv2-48 not available yet, but you can train the whole model from scratch.
|
|
||||||
|
|
||||||
|
|
||||||
class Bottleneck(nn.Module):
|
|
||||||
expansion = 4
|
|
||||||
|
|
||||||
def __init__(self, inplanes, planes, stride=1, downsample=None):
|
|
||||||
super(Bottleneck, self).__init__()
|
|
||||||
self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False)
|
|
||||||
self.bn1 = nn.BatchNorm2d(planes)
|
|
||||||
self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride, padding=1, bias=False)
|
|
||||||
self.bn2 = nn.BatchNorm2d(planes)
|
|
||||||
self.conv3 = nn.Conv2d(planes, planes * self.expansion, kernel_size=1, bias=False)
|
|
||||||
self.bn3 = nn.BatchNorm2d(planes * self.expansion)
|
|
||||||
self.relu = nn.ReLU(inplace=True)
|
|
||||||
self.downsample = downsample
|
|
||||||
|
|
||||||
def forward(self, x):
|
|
||||||
identity = x
|
|
||||||
|
|
||||||
out = self.conv1(x)
|
|
||||||
out = self.bn1(out)
|
|
||||||
out = self.relu(out)
|
|
||||||
out = self.conv2(out)
|
|
||||||
out = self.bn2(out)
|
|
||||||
out = self.relu(out)
|
|
||||||
out = self.conv3(out)
|
|
||||||
out = self.bn3(out)
|
|
||||||
|
|
||||||
if self.downsample is not None:
|
|
||||||
identity = self.downsample(x)
|
|
||||||
|
|
||||||
out += identity
|
|
||||||
out = self.relu(out)
|
|
||||||
|
|
||||||
return out
|
|
||||||
|
|
||||||
|
|
||||||
class BasicBlock(nn.Module):
|
|
||||||
expansion = 1
|
|
||||||
|
|
||||||
def __init__(self, inplanes, planes, stride=1, downsample=None):
|
|
||||||
super(BasicBlock, self).__init__()
|
|
||||||
self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=3, stride=stride, padding=1, bias=False)
|
|
||||||
self.bn1 = nn.BatchNorm2d(planes)
|
|
||||||
self.relu = nn.ReLU(inplace=True)
|
|
||||||
self.conv2 = nn.Conv2d(inplanes, planes, kernel_size=3, stride=1, padding=1, bias=False)
|
|
||||||
self.bn2 = nn.BatchNorm2d(planes)
|
|
||||||
self.downsample = downsample
|
|
||||||
|
|
||||||
def forward(self, x):
|
|
||||||
identity = x
|
|
||||||
|
|
||||||
out = self.conv1(x)
|
|
||||||
out = self.bn1(out)
|
|
||||||
out = self.relu(out)
|
|
||||||
out = self.conv2(out)
|
|
||||||
out = self.bn2(out)
|
|
||||||
|
|
||||||
if self.downsample is not None:
|
|
||||||
identity = self.downsample(x)
|
|
||||||
|
|
||||||
out += identity
|
|
||||||
out = self.relu(out)
|
|
||||||
|
|
||||||
return out
|
|
||||||
|
|
||||||
|
|
||||||
class StageModule(nn.Module):
|
|
||||||
def __init__(self, stage, output_branches, c):
|
|
||||||
super(StageModule, self).__init__()
|
|
||||||
|
|
||||||
self.number_of_branches = stage # number of branches is equivalent to the stage configuration.
|
|
||||||
self.output_branches = output_branches
|
|
||||||
|
|
||||||
self.branches = nn.ModuleList()
|
|
||||||
|
|
||||||
# Note: Resolution + Number of channels maintains the same throughout respective branch.
|
|
||||||
for i in range(self.number_of_branches): # Stage scales with the number of branches. Ex: Stage 2 -> 2 branch
|
|
||||||
channels = c * (2 ** i) # Scale channels by 2x for branch with lower resolution,
|
|
||||||
|
|
||||||
# Paper does x4 basic block for each forward sequence in each branch (x4 basic block considered as a block)
|
|
||||||
branch = nn.Sequential(*[BasicBlock(channels, channels) for _ in range(4)])
|
|
||||||
|
|
||||||
self.branches.append(branch) # list containing all forward sequence of individual branches.
|
|
||||||
|
|
||||||
# For each branch requires repeated fusion with all other branches after passing through x4 basic blocks.
|
|
||||||
self.fuse_layers = nn.ModuleList()
|
|
||||||
|
|
||||||
for branch_output_number in range(self.output_branches):
|
|
||||||
|
|
||||||
self.fuse_layers.append(nn.ModuleList())
|
|
||||||
|
|
||||||
for branch_number in range(self.number_of_branches):
|
|
||||||
if branch_number == branch_output_number:
|
|
||||||
self.fuse_layers[-1].append(nn.Sequential()) # Used in place of "None" because it is callable
|
|
||||||
elif branch_number > branch_output_number:
|
|
||||||
self.fuse_layers[-1].append(nn.Sequential(
|
|
||||||
nn.Conv2d(c * (2 ** branch_number), c * (2 ** branch_output_number), kernel_size=1, stride=1,
|
|
||||||
bias=False),
|
|
||||||
nn.BatchNorm2d(c * (2 ** branch_output_number), eps=1e-05, momentum=0.1, affine=True,
|
|
||||||
track_running_stats=True),
|
|
||||||
nn.Upsample(scale_factor=(2.0 ** (branch_number - branch_output_number)), mode='nearest'),
|
|
||||||
))
|
|
||||||
elif branch_number < branch_output_number:
|
|
||||||
downsampling_fusion = []
|
|
||||||
for _ in range(branch_output_number - branch_number - 1):
|
|
||||||
downsampling_fusion.append(nn.Sequential(
|
|
||||||
nn.Conv2d(c * (2 ** branch_number), c * (2 ** branch_number), kernel_size=3, stride=2,
|
|
||||||
padding=1,
|
|
||||||
bias=False),
|
|
||||||
nn.BatchNorm2d(c * (2 ** branch_number), eps=1e-05, momentum=0.1, affine=True,
|
|
||||||
track_running_stats=True),
|
|
||||||
nn.ReLU(inplace=True),
|
|
||||||
))
|
|
||||||
downsampling_fusion.append(nn.Sequential(
|
|
||||||
nn.Conv2d(c * (2 ** branch_number), c * (2 ** branch_output_number), kernel_size=3,
|
|
||||||
stride=2, padding=1,
|
|
||||||
bias=False),
|
|
||||||
nn.BatchNorm2d(c * (2 ** branch_output_number), eps=1e-05, momentum=0.1, affine=True,
|
|
||||||
track_running_stats=True),
|
|
||||||
))
|
|
||||||
self.fuse_layers[-1].append(nn.Sequential(*downsampling_fusion))
|
|
||||||
|
|
||||||
self.relu = nn.ReLU(inplace=True)
|
|
||||||
|
|
||||||
def forward(self, x):
|
|
||||||
|
|
||||||
# input to each stage is a list of inputs for each branch
|
|
||||||
x = [branch(branch_input) for branch, branch_input in zip(self.branches, x)]
|
|
||||||
|
|
||||||
x_fused = []
|
|
||||||
for branch_output_index in range(
|
|
||||||
self.output_branches): # Amount of output branches == total length of fusion layers
|
|
||||||
for input_index in range(self.number_of_branches): # The inputs of other branches to be fused.
|
|
||||||
if input_index == 0:
|
|
||||||
x_fused.append(self.fuse_layers[branch_output_index][input_index](x[input_index]))
|
|
||||||
else:
|
|
||||||
x_fused[branch_output_index] = x_fused[branch_output_index] + self.fuse_layers[branch_output_index][
|
|
||||||
input_index](x[input_index])
|
|
||||||
|
|
||||||
# After fusing all streams together, you will need to pass the fused layers
|
|
||||||
for i in range(self.output_branches):
|
|
||||||
x_fused[i] = self.relu(x_fused[i])
|
|
||||||
|
|
||||||
return x_fused # returning a list of fused outputs
|
|
||||||
|
|
||||||
|
|
||||||
class HRNet(nn.Module):
|
|
||||||
def __init__(self, c=48, num_blocks=[1, 4, 3], num_classes=1000):
|
|
||||||
super(HRNet, self).__init__()
|
|
||||||
|
|
||||||
# Stem:
|
|
||||||
self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=2, padding=1, bias=False)
|
|
||||||
self.bn1 = nn.BatchNorm2d(64, eps=1e-05, affine=True, track_running_stats=True)
|
|
||||||
self.conv2 = nn.Conv2d(64, 64, kernel_size=3, stride=2, padding=1, bias=False)
|
|
||||||
self.bn2 = nn.BatchNorm2d(64, eps=1e-05, affine=True, track_running_stats=True)
|
|
||||||
self.relu = nn.ReLU(inplace=True)
|
|
||||||
|
|
||||||
# Stage 1:
|
|
||||||
downsample = nn.Sequential(
|
|
||||||
nn.Conv2d(64, 256, kernel_size=1, stride=1, bias=False),
|
|
||||||
nn.BatchNorm2d(256, eps=1e-05, affine=True, track_running_stats=True),
|
|
||||||
)
|
|
||||||
# Note that bottleneck module will expand the output channels according to the output channels*block.expansion
|
|
||||||
bn_expansion = Bottleneck.expansion # The channel expansion is set in the bottleneck class.
|
|
||||||
self.layer1 = nn.Sequential(
|
|
||||||
Bottleneck(64, 64, downsample=downsample), # Input is 64 for first module connection
|
|
||||||
Bottleneck(bn_expansion * 64, 64),
|
|
||||||
Bottleneck(bn_expansion * 64, 64),
|
|
||||||
Bottleneck(bn_expansion * 64, 64),
|
|
||||||
)
|
|
||||||
|
|
||||||
# Transition 1 - Creation of the first two branches (one full and one half resolution)
|
|
||||||
# Need to transition into high resolution stream and mid resolution stream
|
|
||||||
self.transition1 = nn.ModuleList([
|
|
||||||
nn.Sequential(
|
|
||||||
nn.Conv2d(256, c, kernel_size=3, stride=1, padding=1, bias=False),
|
|
||||||
nn.BatchNorm2d(c, eps=1e-05, affine=True, track_running_stats=True),
|
|
||||||
nn.ReLU(inplace=True),
|
|
||||||
),
|
|
||||||
nn.Sequential(nn.Sequential( # Double Sequential to fit with official pretrained weights
|
|
||||||
nn.Conv2d(256, c * 2, kernel_size=3, stride=2, padding=1, bias=False),
|
|
||||||
nn.BatchNorm2d(c * 2, eps=1e-05, affine=True, track_running_stats=True),
|
|
||||||
nn.ReLU(inplace=True),
|
|
||||||
)),
|
|
||||||
])
|
|
||||||
|
|
||||||
# Stage 2:
|
|
||||||
number_blocks_stage2 = num_blocks[0]
|
|
||||||
self.stage2 = nn.Sequential(
|
|
||||||
*[StageModule(stage=2, output_branches=2, c=c) for _ in range(number_blocks_stage2)])
|
|
||||||
|
|
||||||
# Transition 2 - Creation of the third branch (1/4 resolution)
|
|
||||||
self.transition2 = self._make_transition_layers(c, transition_number=2)
|
|
||||||
|
|
||||||
# Stage 3:
|
|
||||||
number_blocks_stage3 = num_blocks[1] # number blocks you want to create before fusion
|
|
||||||
self.stage3 = nn.Sequential(
|
|
||||||
*[StageModule(stage=3, output_branches=3, c=c) for _ in range(number_blocks_stage3)])
|
|
||||||
|
|
||||||
# Transition - Creation of the fourth branch (1/8 resolution)
|
|
||||||
self.transition3 = self._make_transition_layers(c, transition_number=3)
|
|
||||||
|
|
||||||
# Stage 4:
|
|
||||||
number_blocks_stage4 = num_blocks[2] # number blocks you want to create before fusion
|
|
||||||
self.stage4 = nn.Sequential(
|
|
||||||
*[StageModule(stage=4, output_branches=4, c=c) for _ in range(number_blocks_stage4)])
|
|
||||||
|
|
||||||
# Classifier (extra module if want to use for classification):
|
|
||||||
# pool, reduce dimensionality, flatten, connect to linear layer for classification:
|
|
||||||
out_channels = sum([c * 2 ** i for i in range(len(num_blocks)+1)]) # total output channels of HRNetV2
|
|
||||||
pool_feature_map = 8
|
|
||||||
self.bn_classifier = nn.Sequential(
|
|
||||||
nn.Conv2d(out_channels, out_channels // 4, kernel_size=1, bias=False),
|
|
||||||
nn.BatchNorm2d(out_channels // 4, eps=1e-05, affine=True, track_running_stats=True),
|
|
||||||
nn.ReLU(inplace=True),
|
|
||||||
nn.AdaptiveAvgPool2d(pool_feature_map),
|
|
||||||
nn.Flatten(),
|
|
||||||
nn.Linear(pool_feature_map * pool_feature_map * (out_channels // 4), num_classes),
|
|
||||||
)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _make_transition_layers(c, transition_number):
|
|
||||||
return nn.Sequential(
|
|
||||||
nn.Conv2d(c * (2 ** (transition_number - 1)), c * (2 ** transition_number), kernel_size=3, stride=2,
|
|
||||||
padding=1, bias=False),
|
|
||||||
nn.BatchNorm2d(c * (2 ** transition_number), eps=1e-05, affine=True,
|
|
||||||
track_running_stats=True),
|
|
||||||
nn.ReLU(inplace=True),
|
|
||||||
)
|
|
||||||
|
|
||||||
def forward(self, x):
|
|
||||||
# Stem:
|
|
||||||
x = self.conv1(x)
|
|
||||||
x = self.bn1(x)
|
|
||||||
x = self.relu(x)
|
|
||||||
x = self.conv2(x)
|
|
||||||
x = self.bn2(x)
|
|
||||||
x = self.relu(x)
|
|
||||||
|
|
||||||
# Stage 1
|
|
||||||
x = self.layer1(x)
|
|
||||||
x = [trans(x) for trans in self.transition1] # split to 2 branches, form a list.
|
|
||||||
|
|
||||||
# Stage 2
|
|
||||||
x = self.stage2(x)
|
|
||||||
x.append(self.transition2(x[-1]))
|
|
||||||
|
|
||||||
# Stage 3
|
|
||||||
x = self.stage3(x)
|
|
||||||
x.append(self.transition3(x[-1]))
|
|
||||||
|
|
||||||
# Stage 4
|
|
||||||
x = self.stage4(x)
|
|
||||||
|
|
||||||
# HRNetV2 Example: (follow paper, upsample via bilinear interpolation and to highest resolution size)
|
|
||||||
output_h, output_w = x[0].size(2), x[0].size(3) # Upsample to size of highest resolution stream
|
|
||||||
x1 = F.interpolate(x[1], size=(output_h, output_w), mode='bilinear', align_corners=False)
|
|
||||||
x2 = F.interpolate(x[2], size=(output_h, output_w), mode='bilinear', align_corners=False)
|
|
||||||
x3 = F.interpolate(x[3], size=(output_h, output_w), mode='bilinear', align_corners=False)
|
|
||||||
|
|
||||||
# Upsampling all the other resolution streams and then concatenate all (rather than adding/fusing like HRNetV1)
|
|
||||||
x = torch.cat([x[0], x1, x2, x3], dim=1)
|
|
||||||
x = self.bn_classifier(x)
|
|
||||||
return x
|
|
||||||
|
|
||||||
|
|
||||||
def _hrnet(arch, channels, num_blocks, pretrained, progress, **kwargs):
|
|
||||||
model = HRNet(channels, num_blocks, **kwargs)
|
|
||||||
if pretrained:
|
|
||||||
CKPT_PATH = check_pth(arch)
|
|
||||||
checkpoint = torch.load(CKPT_PATH)
|
|
||||||
model.load_state_dict(checkpoint['state_dict'])
|
|
||||||
return model
|
|
||||||
|
|
||||||
|
|
||||||
def hrnetv2_48(pretrained=False, progress=True, number_blocks=[1, 4, 3], **kwargs):
|
|
||||||
w_channels = 48
|
|
||||||
return _hrnet('hrnetv2_48', w_channels, number_blocks, pretrained, progress,
|
|
||||||
**kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def hrnetv2_32(pretrained=False, progress=True, number_blocks=[1, 4, 3], **kwargs):
|
|
||||||
w_channels = 32
|
|
||||||
return _hrnet('hrnetv2_32', w_channels, number_blocks, pretrained, progress,
|
|
||||||
**kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
|
||||||
try:
|
|
||||||
CKPT_PATH = os.path.join(os.path.abspath("."), '../../checkpoints/hrnetv2_32_model_best_epoch96.pth')
|
|
||||||
print("--- Running file as MAIN ---")
|
|
||||||
print(f"Backbone HRNET Pretrained weights as __main__ at: {CKPT_PATH}")
|
|
||||||
except:
|
|
||||||
print("No backbone checkpoint found for HRNetv2, please set pretrained=False when calling model")
|
|
||||||
|
|
||||||
# Models
|
|
||||||
model = hrnetv2_32(pretrained=True)
|
|
||||||
#model = hrnetv2_48(pretrained=False)
|
|
||||||
|
|
||||||
if torch.cuda.is_available():
|
|
||||||
torch.backends.cudnn.deterministic = True
|
|
||||||
device = torch.device('cuda')
|
|
||||||
else:
|
|
||||||
device = torch.device('cpu')
|
|
||||||
model.to(device)
|
|
||||||
in_ = torch.ones(1, 3, 768, 768).to(device)
|
|
||||||
y = model(in_)
|
|
||||||
print(y.shape)
|
|
||||||
|
|
||||||
# Calculate total number of parameters:
|
|
||||||
# pytorch_total_params = sum(p.numel() for p in model.parameters() if p.requires_grad)
|
|
||||||
# print(pytorch_total_params)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,190 +0,0 @@
|
||||||
from torch import nn
|
|
||||||
try: # for torchvision<0.4
|
|
||||||
from torchvision.models.utils import load_state_dict_from_url
|
|
||||||
except: # for torchvision>=0.4
|
|
||||||
from torch.hub import load_state_dict_from_url
|
|
||||||
import torch.nn.functional as F
|
|
||||||
|
|
||||||
__all__ = ['MobileNetV2', 'mobilenet_v2']
|
|
||||||
|
|
||||||
|
|
||||||
model_urls = {
|
|
||||||
'mobilenet_v2': 'https://download.pytorch.org/models/mobilenet_v2-b0353104.pth',
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def _make_divisible(v, divisor, min_value=None):
|
|
||||||
"""
|
|
||||||
This function is taken from the original tf repo.
|
|
||||||
It ensures that all layers have a channel number that is divisible by 8
|
|
||||||
It can be seen here:
|
|
||||||
https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet.py
|
|
||||||
:param v:
|
|
||||||
:param divisor:
|
|
||||||
:param min_value:
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
if min_value is None:
|
|
||||||
min_value = divisor
|
|
||||||
new_v = max(min_value, int(v + divisor / 2) // divisor * divisor)
|
|
||||||
# Make sure that round down does not go down by more than 10%.
|
|
||||||
if new_v < 0.9 * v:
|
|
||||||
new_v += divisor
|
|
||||||
return new_v
|
|
||||||
|
|
||||||
|
|
||||||
class ConvBNReLU(nn.Sequential):
|
|
||||||
def __init__(self, in_planes, out_planes, kernel_size=3, stride=1, dilation=1, groups=1):
|
|
||||||
#padding = (kernel_size - 1) // 2
|
|
||||||
super(ConvBNReLU, self).__init__(
|
|
||||||
nn.Conv2d(in_planes, out_planes, kernel_size, stride, 0, dilation=dilation, groups=groups, bias=False),
|
|
||||||
nn.BatchNorm2d(out_planes),
|
|
||||||
nn.ReLU6(inplace=True)
|
|
||||||
)
|
|
||||||
|
|
||||||
def fixed_padding(kernel_size, dilation):
|
|
||||||
kernel_size_effective = kernel_size + (kernel_size - 1) * (dilation - 1)
|
|
||||||
pad_total = kernel_size_effective - 1
|
|
||||||
pad_beg = pad_total // 2
|
|
||||||
pad_end = pad_total - pad_beg
|
|
||||||
return (pad_beg, pad_end, pad_beg, pad_end)
|
|
||||||
|
|
||||||
class InvertedResidual(nn.Module):
|
|
||||||
def __init__(self, inp, oup, stride, dilation, expand_ratio):
|
|
||||||
super(InvertedResidual, self).__init__()
|
|
||||||
self.stride = stride
|
|
||||||
assert stride in [1, 2]
|
|
||||||
|
|
||||||
hidden_dim = int(round(inp * expand_ratio))
|
|
||||||
self.use_res_connect = self.stride == 1 and inp == oup
|
|
||||||
|
|
||||||
layers = []
|
|
||||||
if expand_ratio != 1:
|
|
||||||
# pw
|
|
||||||
layers.append(ConvBNReLU(inp, hidden_dim, kernel_size=1))
|
|
||||||
|
|
||||||
layers.extend([
|
|
||||||
# dw
|
|
||||||
ConvBNReLU(hidden_dim, hidden_dim, stride=stride, dilation=dilation, groups=hidden_dim),
|
|
||||||
# pw-linear
|
|
||||||
nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False),
|
|
||||||
nn.BatchNorm2d(oup),
|
|
||||||
])
|
|
||||||
self.conv = nn.Sequential(*layers)
|
|
||||||
|
|
||||||
self.input_padding = fixed_padding( 3, dilation )
|
|
||||||
|
|
||||||
def forward(self, x):
|
|
||||||
x_pad = F.pad(x, self.input_padding)
|
|
||||||
if self.use_res_connect:
|
|
||||||
return x + self.conv(x_pad)
|
|
||||||
else:
|
|
||||||
return self.conv(x_pad)
|
|
||||||
|
|
||||||
class MobileNetV2(nn.Module):
|
|
||||||
def __init__(self, num_classes=1000, output_stride=8, width_mult=1.0, inverted_residual_setting=None, round_nearest=8):
|
|
||||||
"""
|
|
||||||
MobileNet V2 main class
|
|
||||||
|
|
||||||
Args:
|
|
||||||
num_classes (int): Number of classes
|
|
||||||
width_mult (float): Width multiplier - adjusts number of channels in each layer by this amount
|
|
||||||
inverted_residual_setting: Network structure
|
|
||||||
round_nearest (int): Round the number of channels in each layer to be a multiple of this number
|
|
||||||
Set to 1 to turn off rounding
|
|
||||||
"""
|
|
||||||
super(MobileNetV2, self).__init__()
|
|
||||||
block = InvertedResidual
|
|
||||||
input_channel = 32
|
|
||||||
last_channel = 1280
|
|
||||||
self.output_stride = output_stride
|
|
||||||
current_stride = 1
|
|
||||||
if inverted_residual_setting is None:
|
|
||||||
inverted_residual_setting = [
|
|
||||||
# t, c, n, s
|
|
||||||
[1, 16, 1, 1],
|
|
||||||
[6, 24, 2, 2],
|
|
||||||
[6, 32, 3, 2],
|
|
||||||
[6, 64, 4, 2],
|
|
||||||
[6, 96, 3, 1],
|
|
||||||
[6, 160, 3, 2],
|
|
||||||
[6, 320, 1, 1],
|
|
||||||
]
|
|
||||||
|
|
||||||
# only check the first element, assuming user knows t,c,n,s are required
|
|
||||||
if len(inverted_residual_setting) == 0 or len(inverted_residual_setting[0]) != 4:
|
|
||||||
raise ValueError("inverted_residual_setting should be non-empty "
|
|
||||||
"or a 4-element list, got {}".format(inverted_residual_setting))
|
|
||||||
|
|
||||||
# building first layer
|
|
||||||
input_channel = _make_divisible(input_channel * width_mult, round_nearest)
|
|
||||||
self.last_channel = _make_divisible(last_channel * max(1.0, width_mult), round_nearest)
|
|
||||||
features = [ConvBNReLU(3, input_channel, stride=2)]
|
|
||||||
current_stride *= 2
|
|
||||||
dilation=1
|
|
||||||
previous_dilation = 1
|
|
||||||
|
|
||||||
# building inverted residual blocks
|
|
||||||
for t, c, n, s in inverted_residual_setting:
|
|
||||||
output_channel = _make_divisible(c * width_mult, round_nearest)
|
|
||||||
previous_dilation = dilation
|
|
||||||
if current_stride == output_stride:
|
|
||||||
stride = 1
|
|
||||||
dilation *= s
|
|
||||||
else:
|
|
||||||
stride = s
|
|
||||||
current_stride *= s
|
|
||||||
output_channel = int(c * width_mult)
|
|
||||||
|
|
||||||
for i in range(n):
|
|
||||||
if i==0:
|
|
||||||
features.append(block(input_channel, output_channel, stride, previous_dilation, expand_ratio=t))
|
|
||||||
else:
|
|
||||||
features.append(block(input_channel, output_channel, 1, dilation, expand_ratio=t))
|
|
||||||
input_channel = output_channel
|
|
||||||
# building last several layers
|
|
||||||
features.append(ConvBNReLU(input_channel, self.last_channel, kernel_size=1))
|
|
||||||
# make it nn.Sequential
|
|
||||||
self.features = nn.Sequential(*features)
|
|
||||||
|
|
||||||
# building classifier
|
|
||||||
self.classifier = nn.Sequential(
|
|
||||||
nn.Dropout(0.2),
|
|
||||||
nn.Linear(self.last_channel, num_classes),
|
|
||||||
)
|
|
||||||
|
|
||||||
# weight initialization
|
|
||||||
for m in self.modules():
|
|
||||||
if isinstance(m, nn.Conv2d):
|
|
||||||
nn.init.kaiming_normal_(m.weight, mode='fan_out')
|
|
||||||
if m.bias is not None:
|
|
||||||
nn.init.zeros_(m.bias)
|
|
||||||
elif isinstance(m, nn.BatchNorm2d):
|
|
||||||
nn.init.ones_(m.weight)
|
|
||||||
nn.init.zeros_(m.bias)
|
|
||||||
elif isinstance(m, nn.Linear):
|
|
||||||
nn.init.normal_(m.weight, 0, 0.01)
|
|
||||||
nn.init.zeros_(m.bias)
|
|
||||||
|
|
||||||
def forward(self, x):
|
|
||||||
x = self.features(x)
|
|
||||||
x = x.mean([2, 3])
|
|
||||||
x = self.classifier(x)
|
|
||||||
return x
|
|
||||||
|
|
||||||
|
|
||||||
def mobilenet_v2(pretrained=False, progress=True, **kwargs):
|
|
||||||
"""
|
|
||||||
Constructs a MobileNetV2 architecture from
|
|
||||||
`"MobileNetV2: Inverted Residuals and Linear Bottlenecks" <https://arxiv.org/abs/1801.04381>`_.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
pretrained (bool): If True, returns a model pre-trained on ImageNet
|
|
||||||
progress (bool): If True, displays a progress bar of the download to stderr
|
|
||||||
"""
|
|
||||||
model = MobileNetV2(**kwargs)
|
|
||||||
if pretrained:
|
|
||||||
state_dict = load_state_dict_from_url(model_urls['mobilenet_v2'],
|
|
||||||
progress=progress)
|
|
||||||
model.load_state_dict(state_dict)
|
|
||||||
return model
|
|
||||||
|
|
@ -1,346 +0,0 @@
|
||||||
import torch
|
|
||||||
import torch.nn as nn
|
|
||||||
try: # for torchvision<0.4
|
|
||||||
from torchvision.models.utils import load_state_dict_from_url
|
|
||||||
except: # for torchvision>=0.4
|
|
||||||
from torch.hub import load_state_dict_from_url
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['ResNet', 'resnet18', 'resnet34', 'resnet50', 'resnet101',
|
|
||||||
'resnet152', 'resnext50_32x4d', 'resnext101_32x8d',
|
|
||||||
'wide_resnet50_2', 'wide_resnet101_2']
|
|
||||||
|
|
||||||
|
|
||||||
model_urls = {
|
|
||||||
'resnet18': 'https://download.pytorch.org/models/resnet18-5c106cde.pth',
|
|
||||||
'resnet34': 'https://download.pytorch.org/models/resnet34-333f7ec4.pth',
|
|
||||||
'resnet50': 'https://download.pytorch.org/models/resnet50-19c8e357.pth',
|
|
||||||
'resnet101': 'https://download.pytorch.org/models/resnet101-5d3b4d8f.pth',
|
|
||||||
'resnet152': 'https://download.pytorch.org/models/resnet152-b121ed2d.pth',
|
|
||||||
'resnext50_32x4d': 'https://download.pytorch.org/models/resnext50_32x4d-7cdf4587.pth',
|
|
||||||
'resnext101_32x8d': 'https://download.pytorch.org/models/resnext101_32x8d-8ba56ff5.pth',
|
|
||||||
'wide_resnet50_2': 'https://download.pytorch.org/models/wide_resnet50_2-95faca4d.pth',
|
|
||||||
'wide_resnet101_2': 'https://download.pytorch.org/models/wide_resnet101_2-32ee1156.pth',
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def conv3x3(in_planes, out_planes, stride=1, groups=1, dilation=1):
|
|
||||||
"""3x3 convolution with padding"""
|
|
||||||
return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride,
|
|
||||||
padding=dilation, groups=groups, bias=False, dilation=dilation)
|
|
||||||
|
|
||||||
|
|
||||||
def conv1x1(in_planes, out_planes, stride=1):
|
|
||||||
"""1x1 convolution"""
|
|
||||||
return nn.Conv2d(in_planes, out_planes, kernel_size=1, stride=stride, bias=False)
|
|
||||||
|
|
||||||
|
|
||||||
class BasicBlock(nn.Module):
|
|
||||||
expansion = 1
|
|
||||||
|
|
||||||
def __init__(self, inplanes, planes, stride=1, downsample=None, groups=1,
|
|
||||||
base_width=64, dilation=1, norm_layer=None):
|
|
||||||
super(BasicBlock, self).__init__()
|
|
||||||
if norm_layer is None:
|
|
||||||
norm_layer = nn.BatchNorm2d
|
|
||||||
if groups != 1 or base_width != 64:
|
|
||||||
raise ValueError('BasicBlock only supports groups=1 and base_width=64')
|
|
||||||
if dilation > 1:
|
|
||||||
raise NotImplementedError("Dilation > 1 not supported in BasicBlock")
|
|
||||||
# Both self.conv1 and self.downsample layers downsample the input when stride != 1
|
|
||||||
self.conv1 = conv3x3(inplanes, planes, stride)
|
|
||||||
self.bn1 = norm_layer(planes)
|
|
||||||
self.relu = nn.ReLU(inplace=True)
|
|
||||||
self.conv2 = conv3x3(planes, planes)
|
|
||||||
self.bn2 = norm_layer(planes)
|
|
||||||
self.downsample = downsample
|
|
||||||
self.stride = stride
|
|
||||||
|
|
||||||
def forward(self, x):
|
|
||||||
identity = x
|
|
||||||
|
|
||||||
out = self.conv1(x)
|
|
||||||
out = self.bn1(out)
|
|
||||||
out = self.relu(out)
|
|
||||||
|
|
||||||
out = self.conv2(out)
|
|
||||||
out = self.bn2(out)
|
|
||||||
|
|
||||||
if self.downsample is not None:
|
|
||||||
identity = self.downsample(x)
|
|
||||||
|
|
||||||
out += identity
|
|
||||||
out = self.relu(out)
|
|
||||||
|
|
||||||
return out
|
|
||||||
|
|
||||||
|
|
||||||
class Bottleneck(nn.Module):
|
|
||||||
expansion = 4
|
|
||||||
|
|
||||||
def __init__(self, inplanes, planes, stride=1, downsample=None, groups=1,
|
|
||||||
base_width=64, dilation=1, norm_layer=None):
|
|
||||||
super(Bottleneck, self).__init__()
|
|
||||||
if norm_layer is None:
|
|
||||||
norm_layer = nn.BatchNorm2d
|
|
||||||
width = int(planes * (base_width / 64.)) * groups
|
|
||||||
# Both self.conv2 and self.downsample layers downsample the input when stride != 1
|
|
||||||
self.conv1 = conv1x1(inplanes, width)
|
|
||||||
self.bn1 = norm_layer(width)
|
|
||||||
self.conv2 = conv3x3(width, width, stride, groups, dilation)
|
|
||||||
self.bn2 = norm_layer(width)
|
|
||||||
self.conv3 = conv1x1(width, planes * self.expansion)
|
|
||||||
self.bn3 = norm_layer(planes * self.expansion)
|
|
||||||
self.relu = nn.ReLU(inplace=True)
|
|
||||||
self.downsample = downsample
|
|
||||||
self.stride = stride
|
|
||||||
|
|
||||||
def forward(self, x):
|
|
||||||
identity = x
|
|
||||||
|
|
||||||
out = self.conv1(x)
|
|
||||||
out = self.bn1(out)
|
|
||||||
out = self.relu(out)
|
|
||||||
|
|
||||||
out = self.conv2(out)
|
|
||||||
out = self.bn2(out)
|
|
||||||
out = self.relu(out)
|
|
||||||
|
|
||||||
out = self.conv3(out)
|
|
||||||
out = self.bn3(out)
|
|
||||||
|
|
||||||
if self.downsample is not None:
|
|
||||||
identity = self.downsample(x)
|
|
||||||
|
|
||||||
out += identity
|
|
||||||
out = self.relu(out)
|
|
||||||
|
|
||||||
return out
|
|
||||||
|
|
||||||
|
|
||||||
class ResNet(nn.Module):
|
|
||||||
|
|
||||||
def __init__(self, block, layers, num_classes=1000, zero_init_residual=False,
|
|
||||||
groups=1, width_per_group=64, replace_stride_with_dilation=None,
|
|
||||||
norm_layer=None):
|
|
||||||
super(ResNet, self).__init__()
|
|
||||||
if norm_layer is None:
|
|
||||||
norm_layer = nn.BatchNorm2d
|
|
||||||
self._norm_layer = norm_layer
|
|
||||||
|
|
||||||
self.inplanes = 64
|
|
||||||
self.dilation = 1
|
|
||||||
if replace_stride_with_dilation is None:
|
|
||||||
# each element in the tuple indicates if we should replace
|
|
||||||
# the 2x2 stride with a dilated convolution instead
|
|
||||||
replace_stride_with_dilation = [False, False, False]
|
|
||||||
if len(replace_stride_with_dilation) != 3:
|
|
||||||
raise ValueError("replace_stride_with_dilation should be None "
|
|
||||||
"or a 3-element tuple, got {}".format(replace_stride_with_dilation))
|
|
||||||
self.groups = groups
|
|
||||||
self.base_width = width_per_group
|
|
||||||
self.conv1 = nn.Conv2d(3, self.inplanes, kernel_size=7, stride=2, padding=3,
|
|
||||||
bias=False)
|
|
||||||
self.bn1 = norm_layer(self.inplanes)
|
|
||||||
self.relu = nn.ReLU(inplace=True)
|
|
||||||
self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
|
|
||||||
self.layer1 = self._make_layer(block, 64, layers[0])
|
|
||||||
self.layer2 = self._make_layer(block, 128, layers[1], stride=2,
|
|
||||||
dilate=replace_stride_with_dilation[0])
|
|
||||||
self.layer3 = self._make_layer(block, 256, layers[2], stride=2,
|
|
||||||
dilate=replace_stride_with_dilation[1])
|
|
||||||
self.layer4 = self._make_layer(block, 512, layers[3], stride=2,
|
|
||||||
dilate=replace_stride_with_dilation[2])
|
|
||||||
self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
|
|
||||||
self.fc = nn.Linear(512 * block.expansion, num_classes)
|
|
||||||
|
|
||||||
for m in self.modules():
|
|
||||||
if isinstance(m, nn.Conv2d):
|
|
||||||
nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
|
|
||||||
elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)):
|
|
||||||
nn.init.constant_(m.weight, 1)
|
|
||||||
nn.init.constant_(m.bias, 0)
|
|
||||||
|
|
||||||
# Zero-initialize the last BN in each residual branch,
|
|
||||||
# so that the residual branch starts with zeros, and each residual block behaves like an identity.
|
|
||||||
# This improves the model by 0.2~0.3% according to https://arxiv.org/abs/1706.02677
|
|
||||||
if zero_init_residual:
|
|
||||||
for m in self.modules():
|
|
||||||
if isinstance(m, Bottleneck):
|
|
||||||
nn.init.constant_(m.bn3.weight, 0)
|
|
||||||
elif isinstance(m, BasicBlock):
|
|
||||||
nn.init.constant_(m.bn2.weight, 0)
|
|
||||||
|
|
||||||
def _make_layer(self, block, planes, blocks, stride=1, dilate=False):
|
|
||||||
norm_layer = self._norm_layer
|
|
||||||
downsample = None
|
|
||||||
previous_dilation = self.dilation
|
|
||||||
if dilate:
|
|
||||||
self.dilation *= stride
|
|
||||||
stride = 1
|
|
||||||
if stride != 1 or self.inplanes != planes * block.expansion:
|
|
||||||
downsample = nn.Sequential(
|
|
||||||
conv1x1(self.inplanes, planes * block.expansion, stride),
|
|
||||||
norm_layer(planes * block.expansion),
|
|
||||||
)
|
|
||||||
|
|
||||||
layers = []
|
|
||||||
layers.append(block(self.inplanes, planes, stride, downsample, self.groups,
|
|
||||||
self.base_width, previous_dilation, norm_layer))
|
|
||||||
self.inplanes = planes * block.expansion
|
|
||||||
for _ in range(1, blocks):
|
|
||||||
layers.append(block(self.inplanes, planes, groups=self.groups,
|
|
||||||
base_width=self.base_width, dilation=self.dilation,
|
|
||||||
norm_layer=norm_layer))
|
|
||||||
|
|
||||||
return nn.Sequential(*layers)
|
|
||||||
|
|
||||||
def forward(self, x):
|
|
||||||
x = self.conv1(x)
|
|
||||||
x = self.bn1(x)
|
|
||||||
x = self.relu(x)
|
|
||||||
x = self.maxpool(x)
|
|
||||||
|
|
||||||
x = self.layer1(x)
|
|
||||||
x = self.layer2(x)
|
|
||||||
x = self.layer3(x)
|
|
||||||
x = self.layer4(x)
|
|
||||||
|
|
||||||
x = self.avgpool(x)
|
|
||||||
x = torch.flatten(x, 1)
|
|
||||||
x = self.fc(x)
|
|
||||||
|
|
||||||
return x
|
|
||||||
|
|
||||||
|
|
||||||
def _resnet(arch, block, layers, pretrained, progress, **kwargs):
|
|
||||||
model = ResNet(block, layers, **kwargs)
|
|
||||||
if pretrained:
|
|
||||||
state_dict = load_state_dict_from_url(model_urls[arch],
|
|
||||||
progress=progress)
|
|
||||||
model.load_state_dict(state_dict)
|
|
||||||
return model
|
|
||||||
|
|
||||||
|
|
||||||
def resnet18(pretrained=False, progress=True, **kwargs):
|
|
||||||
r"""ResNet-18 model from
|
|
||||||
`"Deep Residual Learning for Image Recognition" <https://arxiv.org/pdf/1512.03385.pdf>`_
|
|
||||||
|
|
||||||
Args:
|
|
||||||
pretrained (bool): If True, returns a model pre-trained on ImageNet
|
|
||||||
progress (bool): If True, displays a progress bar of the download to stderr
|
|
||||||
"""
|
|
||||||
return _resnet('resnet18', BasicBlock, [2, 2, 2, 2], pretrained, progress,
|
|
||||||
**kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def resnet34(pretrained=False, progress=True, **kwargs):
|
|
||||||
r"""ResNet-34 model from
|
|
||||||
`"Deep Residual Learning for Image Recognition" <https://arxiv.org/pdf/1512.03385.pdf>`_
|
|
||||||
|
|
||||||
Args:
|
|
||||||
pretrained (bool): If True, returns a model pre-trained on ImageNet
|
|
||||||
progress (bool): If True, displays a progress bar of the download to stderr
|
|
||||||
"""
|
|
||||||
return _resnet('resnet34', BasicBlock, [3, 4, 6, 3], pretrained, progress,
|
|
||||||
**kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def resnet50(pretrained=False, progress=True, **kwargs):
|
|
||||||
r"""ResNet-50 model from
|
|
||||||
`"Deep Residual Learning for Image Recognition" <https://arxiv.org/pdf/1512.03385.pdf>`_
|
|
||||||
|
|
||||||
Args:
|
|
||||||
pretrained (bool): If True, returns a model pre-trained on ImageNet
|
|
||||||
progress (bool): If True, displays a progress bar of the download to stderr
|
|
||||||
"""
|
|
||||||
return _resnet('resnet50', Bottleneck, [3, 4, 6, 3], pretrained, progress,
|
|
||||||
**kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def resnet101(pretrained=False, progress=True, **kwargs):
|
|
||||||
r"""ResNet-101 model from
|
|
||||||
`"Deep Residual Learning for Image Recognition" <https://arxiv.org/pdf/1512.03385.pdf>`_
|
|
||||||
|
|
||||||
Args:
|
|
||||||
pretrained (bool): If True, returns a model pre-trained on ImageNet
|
|
||||||
progress (bool): If True, displays a progress bar of the download to stderr
|
|
||||||
"""
|
|
||||||
return _resnet('resnet101', Bottleneck, [3, 4, 23, 3], pretrained, progress,
|
|
||||||
**kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def resnet152(pretrained=False, progress=True, **kwargs):
|
|
||||||
r"""ResNet-152 model from
|
|
||||||
`"Deep Residual Learning for Image Recognition" <https://arxiv.org/pdf/1512.03385.pdf>`_
|
|
||||||
|
|
||||||
Args:
|
|
||||||
pretrained (bool): If True, returns a model pre-trained on ImageNet
|
|
||||||
progress (bool): If True, displays a progress bar of the download to stderr
|
|
||||||
"""
|
|
||||||
return _resnet('resnet152', Bottleneck, [3, 8, 36, 3], pretrained, progress,
|
|
||||||
**kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def resnext50_32x4d(pretrained=False, progress=True, **kwargs):
|
|
||||||
r"""ResNeXt-50 32x4d model from
|
|
||||||
`"Aggregated Residual Transformation for Deep Neural Networks" <https://arxiv.org/pdf/1611.05431.pdf>`_
|
|
||||||
|
|
||||||
Args:
|
|
||||||
pretrained (bool): If True, returns a model pre-trained on ImageNet
|
|
||||||
progress (bool): If True, displays a progress bar of the download to stderr
|
|
||||||
"""
|
|
||||||
kwargs['groups'] = 32
|
|
||||||
kwargs['width_per_group'] = 4
|
|
||||||
return _resnet('resnext50_32x4d', Bottleneck, [3, 4, 6, 3],
|
|
||||||
pretrained, progress, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def resnext101_32x8d(pretrained=False, progress=True, **kwargs):
|
|
||||||
r"""ResNeXt-101 32x8d model from
|
|
||||||
`"Aggregated Residual Transformation for Deep Neural Networks" <https://arxiv.org/pdf/1611.05431.pdf>`_
|
|
||||||
|
|
||||||
Args:
|
|
||||||
pretrained (bool): If True, returns a model pre-trained on ImageNet
|
|
||||||
progress (bool): If True, displays a progress bar of the download to stderr
|
|
||||||
"""
|
|
||||||
kwargs['groups'] = 32
|
|
||||||
kwargs['width_per_group'] = 8
|
|
||||||
return _resnet('resnext101_32x8d', Bottleneck, [3, 4, 23, 3],
|
|
||||||
pretrained, progress, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def wide_resnet50_2(pretrained=False, progress=True, **kwargs):
|
|
||||||
r"""Wide ResNet-50-2 model from
|
|
||||||
`"Wide Residual Networks" <https://arxiv.org/pdf/1605.07146.pdf>`_
|
|
||||||
|
|
||||||
The model is the same as ResNet except for the bottleneck number of channels
|
|
||||||
which is twice larger in every block. The number of channels in outer 1x1
|
|
||||||
convolutions is the same, e.g. last block in ResNet-50 has 2048-512-2048
|
|
||||||
channels, and in Wide ResNet-50-2 has 2048-1024-2048.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
pretrained (bool): If True, returns a model pre-trained on ImageNet
|
|
||||||
progress (bool): If True, displays a progress bar of the download to stderr
|
|
||||||
"""
|
|
||||||
kwargs['width_per_group'] = 64 * 2
|
|
||||||
return _resnet('wide_resnet50_2', Bottleneck, [3, 4, 6, 3],
|
|
||||||
pretrained, progress, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def wide_resnet101_2(pretrained=False, progress=True, **kwargs):
|
|
||||||
r"""Wide ResNet-101-2 model from
|
|
||||||
`"Wide Residual Networks" <https://arxiv.org/pdf/1605.07146.pdf>`_
|
|
||||||
|
|
||||||
The model is the same as ResNet except for the bottleneck number of channels
|
|
||||||
which is twice larger in every block. The number of channels in outer 1x1
|
|
||||||
convolutions is the same, e.g. last block in ResNet-50 has 2048-512-2048
|
|
||||||
channels, and in Wide ResNet-50-2 has 2048-1024-2048.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
pretrained (bool): If True, returns a model pre-trained on ImageNet
|
|
||||||
progress (bool): If True, displays a progress bar of the download to stderr
|
|
||||||
"""
|
|
||||||
kwargs['width_per_group'] = 64 * 2
|
|
||||||
return _resnet('wide_resnet101_2', Bottleneck, [3, 4, 23, 3],
|
|
||||||
pretrained, progress, **kwargs)
|
|
||||||
|
|
@ -1,238 +0,0 @@
|
||||||
|
|
||||||
"""
|
|
||||||
Xception is adapted from https://github.com/Cadene/pretrained-models.pytorch/blob/master/pretrainedmodels/models/xception.py
|
|
||||||
|
|
||||||
Ported to pytorch thanks to [tstandley](https://github.com/tstandley/Xception-PyTorch)
|
|
||||||
@author: tstandley
|
|
||||||
Adapted by cadene
|
|
||||||
Creates an Xception Model as defined in:
|
|
||||||
Francois Chollet
|
|
||||||
Xception: Deep Learning with Depthwise Separable Convolutions
|
|
||||||
https://arxiv.org/pdf/1610.02357.pdf
|
|
||||||
This weights ported from the Keras implementation. Achieves the following performance on the validation set:
|
|
||||||
Loss:0.9173 Prec@1:78.892 Prec@5:94.292
|
|
||||||
REMEMBER to set your image size to 3x299x299 for both test and validation
|
|
||||||
normalize = transforms.Normalize(mean=[0.5, 0.5, 0.5],
|
|
||||||
std=[0.5, 0.5, 0.5])
|
|
||||||
The resize parameter of the validation transform should be 333, and make sure to center crop at 299x299
|
|
||||||
"""
|
|
||||||
from __future__ import print_function, division, absolute_import
|
|
||||||
import math
|
|
||||||
import torch
|
|
||||||
import torch.nn as nn
|
|
||||||
import torch.nn.functional as F
|
|
||||||
import torch.utils.model_zoo as model_zoo
|
|
||||||
from torch.nn import init
|
|
||||||
|
|
||||||
__all__ = ['xception']
|
|
||||||
|
|
||||||
pretrained_settings = {
|
|
||||||
'xception': {
|
|
||||||
'imagenet': {
|
|
||||||
'url': 'http://data.lip6.fr/cadene/pretrainedmodels/xception-43020ad28.pth',
|
|
||||||
'input_space': 'RGB',
|
|
||||||
'input_size': [3, 299, 299],
|
|
||||||
'input_range': [0, 1],
|
|
||||||
'mean': [0.5, 0.5, 0.5],
|
|
||||||
'std': [0.5, 0.5, 0.5],
|
|
||||||
'num_classes': 1000,
|
|
||||||
'scale': 0.8975 # The resize parameter of the validation transform should be 333, and make sure to center crop at 299x299
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class SeparableConv2d(nn.Module):
|
|
||||||
def __init__(self,in_channels,out_channels,kernel_size=1,stride=1,padding=0,dilation=1,bias=False):
|
|
||||||
super(SeparableConv2d,self).__init__()
|
|
||||||
|
|
||||||
self.conv1 = nn.Conv2d(in_channels,in_channels,kernel_size,stride,padding,dilation,groups=in_channels,bias=bias)
|
|
||||||
self.pointwise = nn.Conv2d(in_channels,out_channels,1,1,0,1,1,bias=bias)
|
|
||||||
|
|
||||||
def forward(self,x):
|
|
||||||
x = self.conv1(x)
|
|
||||||
x = self.pointwise(x)
|
|
||||||
return x
|
|
||||||
|
|
||||||
|
|
||||||
class Block(nn.Module):
|
|
||||||
def __init__(self,in_filters,out_filters,reps,strides=1,start_with_relu=True,grow_first=True, dilation=1):
|
|
||||||
super(Block, self).__init__()
|
|
||||||
|
|
||||||
if out_filters != in_filters or strides!=1:
|
|
||||||
self.skip = nn.Conv2d(in_filters,out_filters,1,stride=strides, bias=False)
|
|
||||||
self.skipbn = nn.BatchNorm2d(out_filters)
|
|
||||||
else:
|
|
||||||
self.skip=None
|
|
||||||
|
|
||||||
rep=[]
|
|
||||||
|
|
||||||
filters=in_filters
|
|
||||||
if grow_first:
|
|
||||||
rep.append(nn.ReLU(inplace=True))
|
|
||||||
rep.append(SeparableConv2d(in_filters,out_filters,3,stride=1,padding=dilation, dilation=dilation, bias=False))
|
|
||||||
rep.append(nn.BatchNorm2d(out_filters))
|
|
||||||
filters = out_filters
|
|
||||||
|
|
||||||
for i in range(reps-1):
|
|
||||||
rep.append(nn.ReLU(inplace=True))
|
|
||||||
rep.append(SeparableConv2d(filters,filters,3,stride=1,padding=dilation,dilation=dilation,bias=False))
|
|
||||||
rep.append(nn.BatchNorm2d(filters))
|
|
||||||
|
|
||||||
if not grow_first:
|
|
||||||
rep.append(nn.ReLU(inplace=True))
|
|
||||||
rep.append(SeparableConv2d(in_filters,out_filters,3,stride=1,padding=dilation,dilation=dilation,bias=False))
|
|
||||||
rep.append(nn.BatchNorm2d(out_filters))
|
|
||||||
|
|
||||||
if not start_with_relu:
|
|
||||||
rep = rep[1:]
|
|
||||||
else:
|
|
||||||
rep[0] = nn.ReLU(inplace=False)
|
|
||||||
|
|
||||||
if strides != 1:
|
|
||||||
rep.append(nn.MaxPool2d(3,strides,1))
|
|
||||||
self.rep = nn.Sequential(*rep)
|
|
||||||
|
|
||||||
def forward(self,inp):
|
|
||||||
x = self.rep(inp)
|
|
||||||
|
|
||||||
if self.skip is not None:
|
|
||||||
skip = self.skip(inp)
|
|
||||||
skip = self.skipbn(skip)
|
|
||||||
else:
|
|
||||||
skip = inp
|
|
||||||
x+=skip
|
|
||||||
return x
|
|
||||||
|
|
||||||
|
|
||||||
class Xception(nn.Module):
|
|
||||||
"""
|
|
||||||
Xception optimized for the ImageNet dataset, as specified in
|
|
||||||
https://arxiv.org/pdf/1610.02357.pdf
|
|
||||||
"""
|
|
||||||
def __init__(self, num_classes=1000, replace_stride_with_dilation=None):
|
|
||||||
""" Constructor
|
|
||||||
Args:
|
|
||||||
num_classes: number of classes
|
|
||||||
"""
|
|
||||||
super(Xception, self).__init__()
|
|
||||||
|
|
||||||
self.num_classes = num_classes
|
|
||||||
self.dilation = 1
|
|
||||||
if replace_stride_with_dilation is None:
|
|
||||||
# each element in the tuple indicates if we should replace
|
|
||||||
# the 2x2 stride with a dilated convolution instead
|
|
||||||
replace_stride_with_dilation = [False, False, False, False]
|
|
||||||
if len(replace_stride_with_dilation) != 4:
|
|
||||||
raise ValueError("replace_stride_with_dilation should be None "
|
|
||||||
"or a 4-element tuple, got {}".format(replace_stride_with_dilation))
|
|
||||||
|
|
||||||
self.conv1 = nn.Conv2d(3, 32, 3,2, 0, bias=False) # 1 / 2
|
|
||||||
self.bn1 = nn.BatchNorm2d(32)
|
|
||||||
self.relu1 = nn.ReLU(inplace=True)
|
|
||||||
|
|
||||||
self.conv2 = nn.Conv2d(32,64,3,bias=False)
|
|
||||||
self.bn2 = nn.BatchNorm2d(64)
|
|
||||||
self.relu2 = nn.ReLU(inplace=True)
|
|
||||||
#do relu here
|
|
||||||
|
|
||||||
self.block1=self._make_block(64,128,2,2,start_with_relu=False,grow_first=True, dilate=replace_stride_with_dilation[0]) # 1 / 4
|
|
||||||
self.block2=self._make_block(128,256,2,2,start_with_relu=True,grow_first=True, dilate=replace_stride_with_dilation[1]) # 1 / 8
|
|
||||||
self.block3=self._make_block(256,728,2,2,start_with_relu=True,grow_first=True, dilate=replace_stride_with_dilation[2]) # 1 / 16
|
|
||||||
|
|
||||||
self.block4=self._make_block(728,728,3,1,start_with_relu=True,grow_first=True, dilate=replace_stride_with_dilation[2])
|
|
||||||
self.block5=self._make_block(728,728,3,1,start_with_relu=True,grow_first=True, dilate=replace_stride_with_dilation[2])
|
|
||||||
self.block6=self._make_block(728,728,3,1,start_with_relu=True,grow_first=True, dilate=replace_stride_with_dilation[2])
|
|
||||||
self.block7=self._make_block(728,728,3,1,start_with_relu=True,grow_first=True, dilate=replace_stride_with_dilation[2])
|
|
||||||
|
|
||||||
self.block8=self._make_block(728,728,3,1,start_with_relu=True,grow_first=True, dilate=replace_stride_with_dilation[2])
|
|
||||||
self.block9=self._make_block(728,728,3,1,start_with_relu=True,grow_first=True, dilate=replace_stride_with_dilation[2])
|
|
||||||
self.block10=self._make_block(728,728,3,1,start_with_relu=True,grow_first=True, dilate=replace_stride_with_dilation[2])
|
|
||||||
self.block11=self._make_block(728,728,3,1,start_with_relu=True,grow_first=True, dilate=replace_stride_with_dilation[2])
|
|
||||||
|
|
||||||
self.block12=self._make_block(728,1024,2,2,start_with_relu=True,grow_first=False, dilate=replace_stride_with_dilation[3]) # 1 / 32
|
|
||||||
|
|
||||||
self.conv3 = SeparableConv2d(1024,1536,3,1,1, dilation=self.dilation)
|
|
||||||
self.bn3 = nn.BatchNorm2d(1536)
|
|
||||||
self.relu3 = nn.ReLU(inplace=True)
|
|
||||||
|
|
||||||
#do relu here
|
|
||||||
self.conv4 = SeparableConv2d(1536,2048,3,1,1, dilation=self.dilation)
|
|
||||||
self.bn4 = nn.BatchNorm2d(2048)
|
|
||||||
|
|
||||||
self.fc = nn.Linear(2048, num_classes)
|
|
||||||
|
|
||||||
# #------- init weights --------
|
|
||||||
# for m in self.modules():
|
|
||||||
# if isinstance(m, nn.Conv2d):
|
|
||||||
# n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
|
|
||||||
# m.weight.data.normal_(0, math.sqrt(2. / n))
|
|
||||||
# elif isinstance(m, nn.BatchNorm2d):
|
|
||||||
# m.weight.data.fill_(1)
|
|
||||||
# m.bias.data.zero_()
|
|
||||||
# #-----------------------------
|
|
||||||
|
|
||||||
def _make_block(self, in_filters,out_filters,reps,strides=1,start_with_relu=True,grow_first=True, dilate=False):
|
|
||||||
if dilate:
|
|
||||||
self.dilation *= strides
|
|
||||||
strides = 1
|
|
||||||
return Block(in_filters,out_filters,reps,strides,start_with_relu=start_with_relu,grow_first=grow_first, dilation=self.dilation)
|
|
||||||
|
|
||||||
def features(self, input):
|
|
||||||
x = self.conv1(input)
|
|
||||||
x = self.bn1(x)
|
|
||||||
x = self.relu1(x)
|
|
||||||
|
|
||||||
x = self.conv2(x)
|
|
||||||
x = self.bn2(x)
|
|
||||||
x = self.relu2(x)
|
|
||||||
|
|
||||||
x = self.block1(x)
|
|
||||||
x = self.block2(x)
|
|
||||||
x = self.block3(x)
|
|
||||||
x = self.block4(x)
|
|
||||||
x = self.block5(x)
|
|
||||||
x = self.block6(x)
|
|
||||||
x = self.block7(x)
|
|
||||||
x = self.block8(x)
|
|
||||||
x = self.block9(x)
|
|
||||||
x = self.block10(x)
|
|
||||||
x = self.block11(x)
|
|
||||||
x = self.block12(x)
|
|
||||||
|
|
||||||
x = self.conv3(x)
|
|
||||||
x = self.bn3(x)
|
|
||||||
x = self.relu3(x)
|
|
||||||
|
|
||||||
x = self.conv4(x)
|
|
||||||
x = self.bn4(x)
|
|
||||||
return x
|
|
||||||
|
|
||||||
def logits(self, features):
|
|
||||||
x = nn.ReLU(inplace=True)(features)
|
|
||||||
|
|
||||||
x = F.adaptive_avg_pool2d(x, (1, 1))
|
|
||||||
x = x.view(x.size(0), -1)
|
|
||||||
x = self.last_linear(x)
|
|
||||||
return x
|
|
||||||
|
|
||||||
def forward(self, input):
|
|
||||||
x = self.features(input)
|
|
||||||
x = self.logits(x)
|
|
||||||
return x
|
|
||||||
|
|
||||||
|
|
||||||
def xception(num_classes=1000, pretrained='imagenet', replace_stride_with_dilation=None):
|
|
||||||
model = Xception(num_classes=num_classes, replace_stride_with_dilation=replace_stride_with_dilation)
|
|
||||||
if pretrained:
|
|
||||||
settings = pretrained_settings['xception'][pretrained]
|
|
||||||
assert num_classes == settings['num_classes'], \
|
|
||||||
"num_classes should be {}, but is {}".format(settings['num_classes'], num_classes)
|
|
||||||
|
|
||||||
model = Xception(num_classes=num_classes, replace_stride_with_dilation=replace_stride_with_dilation)
|
|
||||||
model.load_state_dict(model_zoo.load_url(settings['url']))
|
|
||||||
|
|
||||||
# TODO: ugly
|
|
||||||
model.last_linear = model.fc
|
|
||||||
del model.fc
|
|
||||||
return model
|
|
||||||
|
|
@ -1,222 +0,0 @@
|
||||||
from .utils import IntermediateLayerGetter
|
|
||||||
from ._deeplab import DeepLabHead, DeepLabHeadV3Plus, DeepLabV3
|
|
||||||
from .backbone import (
|
|
||||||
resnet,
|
|
||||||
mobilenetv2,
|
|
||||||
hrnetv2,
|
|
||||||
xception
|
|
||||||
)
|
|
||||||
|
|
||||||
def _segm_hrnet(name, backbone_name, num_classes, pretrained_backbone):
|
|
||||||
|
|
||||||
backbone = hrnetv2.__dict__[backbone_name](pretrained_backbone)
|
|
||||||
# HRNetV2 config:
|
|
||||||
# the final output channels is dependent on highest resolution channel config (c).
|
|
||||||
# output of backbone will be the inplanes to assp:
|
|
||||||
hrnet_channels = int(backbone_name.split('_')[-1])
|
|
||||||
inplanes = sum([hrnet_channels * 2 ** i for i in range(4)])
|
|
||||||
low_level_planes = 256 # all hrnet version channel output from bottleneck is the same
|
|
||||||
aspp_dilate = [12, 24, 36] # If follow paper trend, can put [24, 48, 72].
|
|
||||||
|
|
||||||
if name=='deeplabv3plus':
|
|
||||||
return_layers = {'stage4': 'out', 'layer1': 'low_level'}
|
|
||||||
classifier = DeepLabHeadV3Plus(inplanes, low_level_planes, num_classes, aspp_dilate)
|
|
||||||
elif name=='deeplabv3':
|
|
||||||
return_layers = {'stage4': 'out'}
|
|
||||||
classifier = DeepLabHead(inplanes, num_classes, aspp_dilate)
|
|
||||||
|
|
||||||
backbone = IntermediateLayerGetter(backbone, return_layers=return_layers, hrnet_flag=True)
|
|
||||||
model = DeepLabV3(backbone, classifier)
|
|
||||||
return model
|
|
||||||
|
|
||||||
def _segm_resnet(name, backbone_name, num_classes, output_stride, pretrained_backbone):
|
|
||||||
|
|
||||||
if output_stride==8:
|
|
||||||
replace_stride_with_dilation=[False, True, True]
|
|
||||||
aspp_dilate = [12, 24, 36]
|
|
||||||
else:
|
|
||||||
replace_stride_with_dilation=[False, False, True]
|
|
||||||
aspp_dilate = [6, 12, 18]
|
|
||||||
|
|
||||||
backbone = resnet.__dict__[backbone_name](
|
|
||||||
pretrained=pretrained_backbone,
|
|
||||||
replace_stride_with_dilation=replace_stride_with_dilation)
|
|
||||||
|
|
||||||
inplanes = 2048
|
|
||||||
low_level_planes = 256
|
|
||||||
|
|
||||||
if name=='deeplabv3plus':
|
|
||||||
return_layers = {'layer4': 'out', 'layer1': 'low_level'}
|
|
||||||
classifier = DeepLabHeadV3Plus(inplanes, low_level_planes, num_classes, aspp_dilate)
|
|
||||||
elif name=='deeplabv3':
|
|
||||||
return_layers = {'layer4': 'out'}
|
|
||||||
classifier = DeepLabHead(inplanes , num_classes, aspp_dilate)
|
|
||||||
backbone = IntermediateLayerGetter(backbone, return_layers=return_layers)
|
|
||||||
|
|
||||||
model = DeepLabV3(backbone, classifier)
|
|
||||||
return model
|
|
||||||
|
|
||||||
|
|
||||||
def _segm_xception(name, backbone_name, num_classes, output_stride, pretrained_backbone):
|
|
||||||
if output_stride==8:
|
|
||||||
replace_stride_with_dilation=[False, False, True, True]
|
|
||||||
aspp_dilate = [12, 24, 36]
|
|
||||||
else:
|
|
||||||
replace_stride_with_dilation=[False, False, False, True]
|
|
||||||
aspp_dilate = [6, 12, 18]
|
|
||||||
|
|
||||||
backbone = xception.xception(pretrained= 'imagenet' if pretrained_backbone else False, replace_stride_with_dilation=replace_stride_with_dilation)
|
|
||||||
|
|
||||||
inplanes = 2048
|
|
||||||
low_level_planes = 128
|
|
||||||
|
|
||||||
if name=='deeplabv3plus':
|
|
||||||
return_layers = {'conv4': 'out', 'block1': 'low_level'}
|
|
||||||
classifier = DeepLabHeadV3Plus(inplanes, low_level_planes, num_classes, aspp_dilate)
|
|
||||||
elif name=='deeplabv3':
|
|
||||||
return_layers = {'conv4': 'out'}
|
|
||||||
classifier = DeepLabHead(inplanes , num_classes, aspp_dilate)
|
|
||||||
backbone = IntermediateLayerGetter(backbone, return_layers=return_layers)
|
|
||||||
model = DeepLabV3(backbone, classifier)
|
|
||||||
return model
|
|
||||||
|
|
||||||
|
|
||||||
def _segm_mobilenet(name, backbone_name, num_classes, output_stride, pretrained_backbone):
|
|
||||||
if output_stride==8:
|
|
||||||
aspp_dilate = [12, 24, 36]
|
|
||||||
else:
|
|
||||||
aspp_dilate = [6, 12, 18]
|
|
||||||
|
|
||||||
backbone = mobilenetv2.mobilenet_v2(pretrained=pretrained_backbone, output_stride=output_stride)
|
|
||||||
|
|
||||||
# rename layers
|
|
||||||
backbone.low_level_features = backbone.features[0:4]
|
|
||||||
backbone.high_level_features = backbone.features[4:-1]
|
|
||||||
backbone.features = None
|
|
||||||
backbone.classifier = None
|
|
||||||
|
|
||||||
inplanes = 320
|
|
||||||
low_level_planes = 24
|
|
||||||
|
|
||||||
if name=='deeplabv3plus':
|
|
||||||
return_layers = {'high_level_features': 'out', 'low_level_features': 'low_level'}
|
|
||||||
classifier = DeepLabHeadV3Plus(inplanes, low_level_planes, num_classes, aspp_dilate)
|
|
||||||
elif name=='deeplabv3':
|
|
||||||
return_layers = {'high_level_features': 'out'}
|
|
||||||
classifier = DeepLabHead(inplanes , num_classes, aspp_dilate)
|
|
||||||
backbone = IntermediateLayerGetter(backbone, return_layers=return_layers)
|
|
||||||
|
|
||||||
model = DeepLabV3(backbone, classifier)
|
|
||||||
return model
|
|
||||||
|
|
||||||
def _load_model(arch_type, backbone, num_classes, output_stride, pretrained_backbone):
|
|
||||||
|
|
||||||
if backbone=='mobilenetv2':
|
|
||||||
model = _segm_mobilenet(arch_type, backbone, num_classes, output_stride=output_stride, pretrained_backbone=pretrained_backbone)
|
|
||||||
elif backbone.startswith('resnet'):
|
|
||||||
model = _segm_resnet(arch_type, backbone, num_classes, output_stride=output_stride, pretrained_backbone=pretrained_backbone)
|
|
||||||
elif backbone.startswith('hrnetv2'):
|
|
||||||
model = _segm_hrnet(arch_type, backbone, num_classes, pretrained_backbone=pretrained_backbone)
|
|
||||||
elif backbone=='xception':
|
|
||||||
model = _segm_xception(arch_type, backbone, num_classes, output_stride=output_stride, pretrained_backbone=pretrained_backbone)
|
|
||||||
else:
|
|
||||||
raise NotImplementedError
|
|
||||||
return model
|
|
||||||
|
|
||||||
|
|
||||||
# Deeplab v3
|
|
||||||
def deeplabv3_hrnetv2_48(num_classes=21, output_stride=4, pretrained_backbone=False): # no pretrained backbone yet
|
|
||||||
return _load_model('deeplabv3', 'hrnetv2_48', output_stride, num_classes, pretrained_backbone=pretrained_backbone)
|
|
||||||
|
|
||||||
def deeplabv3_hrnetv2_32(num_classes=21, output_stride=4, pretrained_backbone=True):
|
|
||||||
return _load_model('deeplabv3', 'hrnetv2_32', output_stride, num_classes, pretrained_backbone=pretrained_backbone)
|
|
||||||
|
|
||||||
def deeplabv3_resnet50(num_classes=21, output_stride=8, pretrained_backbone=True):
|
|
||||||
"""Constructs a DeepLabV3 model with a ResNet-50 backbone.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
num_classes (int): number of classes.
|
|
||||||
output_stride (int): output stride for deeplab.
|
|
||||||
pretrained_backbone (bool): If True, use the pretrained backbone.
|
|
||||||
"""
|
|
||||||
return _load_model('deeplabv3', 'resnet50', num_classes, output_stride=output_stride, pretrained_backbone=pretrained_backbone)
|
|
||||||
|
|
||||||
def deeplabv3_resnet101(num_classes=21, output_stride=8, pretrained_backbone=True):
|
|
||||||
"""Constructs a DeepLabV3 model with a ResNet-101 backbone.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
num_classes (int): number of classes.
|
|
||||||
output_stride (int): output stride for deeplab.
|
|
||||||
pretrained_backbone (bool): If True, use the pretrained backbone.
|
|
||||||
"""
|
|
||||||
return _load_model('deeplabv3', 'resnet101', num_classes, output_stride=output_stride, pretrained_backbone=pretrained_backbone)
|
|
||||||
|
|
||||||
def deeplabv3_mobilenet(num_classes=21, output_stride=8, pretrained_backbone=True, **kwargs):
|
|
||||||
"""Constructs a DeepLabV3 model with a MobileNetv2 backbone.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
num_classes (int): number of classes.
|
|
||||||
output_stride (int): output stride for deeplab.
|
|
||||||
pretrained_backbone (bool): If True, use the pretrained backbone.
|
|
||||||
"""
|
|
||||||
return _load_model('deeplabv3', 'mobilenetv2', num_classes, output_stride=output_stride, pretrained_backbone=pretrained_backbone)
|
|
||||||
|
|
||||||
def deeplabv3_xception(num_classes=21, output_stride=8, pretrained_backbone=True, **kwargs):
|
|
||||||
"""Constructs a DeepLabV3 model with a Xception backbone.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
num_classes (int): number of classes.
|
|
||||||
output_stride (int): output stride for deeplab.
|
|
||||||
pretrained_backbone (bool): If True, use the pretrained backbone.
|
|
||||||
"""
|
|
||||||
return _load_model('deeplabv3', 'xception', num_classes, output_stride=output_stride, pretrained_backbone=pretrained_backbone)
|
|
||||||
|
|
||||||
|
|
||||||
# Deeplab v3+
|
|
||||||
def deeplabv3plus_hrnetv2_48(num_classes=21, output_stride=4, pretrained_backbone=False): # no pretrained backbone yet
|
|
||||||
return _load_model('deeplabv3plus', 'hrnetv2_48', num_classes, output_stride, pretrained_backbone=pretrained_backbone)
|
|
||||||
|
|
||||||
def deeplabv3plus_hrnetv2_32(num_classes=21, output_stride=4, pretrained_backbone=True):
|
|
||||||
return _load_model('deeplabv3plus', 'hrnetv2_32', num_classes, output_stride, pretrained_backbone=pretrained_backbone)
|
|
||||||
|
|
||||||
def deeplabv3plus_resnet50(num_classes=21, output_stride=8, pretrained_backbone=True):
|
|
||||||
"""Constructs a DeepLabV3 model with a ResNet-50 backbone.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
num_classes (int): number of classes.
|
|
||||||
output_stride (int): output stride for deeplab.
|
|
||||||
pretrained_backbone (bool): If True, use the pretrained backbone.
|
|
||||||
"""
|
|
||||||
return _load_model('deeplabv3plus', 'resnet50', num_classes, output_stride=output_stride, pretrained_backbone=pretrained_backbone)
|
|
||||||
|
|
||||||
|
|
||||||
def deeplabv3plus_resnet101(num_classes=21, output_stride=8, pretrained_backbone=True):
|
|
||||||
"""Constructs a DeepLabV3+ model with a ResNet-101 backbone.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
num_classes (int): number of classes.
|
|
||||||
output_stride (int): output stride for deeplab.
|
|
||||||
pretrained_backbone (bool): If True, use the pretrained backbone.
|
|
||||||
"""
|
|
||||||
return _load_model('deeplabv3plus', 'resnet101', num_classes, output_stride=output_stride, pretrained_backbone=pretrained_backbone)
|
|
||||||
|
|
||||||
|
|
||||||
def deeplabv3plus_mobilenet(num_classes=21, output_stride=8, pretrained_backbone=True):
|
|
||||||
"""Constructs a DeepLabV3+ model with a MobileNetv2 backbone.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
num_classes (int): number of classes.
|
|
||||||
output_stride (int): output stride for deeplab.
|
|
||||||
pretrained_backbone (bool): If True, use the pretrained backbone.
|
|
||||||
"""
|
|
||||||
return _load_model('deeplabv3plus', 'mobilenetv2', num_classes, output_stride=output_stride, pretrained_backbone=pretrained_backbone)
|
|
||||||
|
|
||||||
def deeplabv3plus_xception(num_classes=21, output_stride=8, pretrained_backbone=True):
|
|
||||||
"""Constructs a DeepLabV3+ model with a Xception backbone.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
num_classes (int): number of classes.
|
|
||||||
output_stride (int): output stride for deeplab.
|
|
||||||
pretrained_backbone (bool): If True, use the pretrained backbone.
|
|
||||||
"""
|
|
||||||
return _load_model('deeplabv3plus', 'xception', num_classes, output_stride=output_stride, pretrained_backbone=pretrained_backbone)
|
|
||||||
|
|
@ -1,93 +0,0 @@
|
||||||
import torch
|
|
||||||
import torch.nn as nn
|
|
||||||
import numpy as np
|
|
||||||
import torch.nn.functional as F
|
|
||||||
from collections import OrderedDict
|
|
||||||
|
|
||||||
class _SimpleSegmentationModel(nn.Module):
|
|
||||||
def __init__(self, backbone, classifier):
|
|
||||||
super(_SimpleSegmentationModel, self).__init__()
|
|
||||||
self.backbone = backbone
|
|
||||||
self.classifier = classifier
|
|
||||||
|
|
||||||
def forward(self, x):
|
|
||||||
input_shape = x.shape[-2:]
|
|
||||||
features = self.backbone(x)
|
|
||||||
x = self.classifier(features)
|
|
||||||
x = F.interpolate(x, size=input_shape, mode='bilinear', align_corners=False)
|
|
||||||
return x
|
|
||||||
|
|
||||||
|
|
||||||
class IntermediateLayerGetter(nn.ModuleDict):
|
|
||||||
"""
|
|
||||||
Module wrapper that returns intermediate layers from a model
|
|
||||||
|
|
||||||
It has a strong assumption that the modules have been registered
|
|
||||||
into the model in the same order as they are used.
|
|
||||||
This means that one should **not** reuse the same nn.Module
|
|
||||||
twice in the forward if you want this to work.
|
|
||||||
|
|
||||||
Additionally, it is only able to query submodules that are directly
|
|
||||||
assigned to the model. So if `model` is passed, `model.feature1` can
|
|
||||||
be returned, but not `model.feature1.layer2`.
|
|
||||||
|
|
||||||
Arguments:
|
|
||||||
model (nn.Module): model on which we will extract the features
|
|
||||||
return_layers (Dict[name, new_name]): a dict containing the names
|
|
||||||
of the modules for which the activations will be returned as
|
|
||||||
the key of the dict, and the value of the dict is the name
|
|
||||||
of the returned activation (which the user can specify).
|
|
||||||
|
|
||||||
Examples::
|
|
||||||
|
|
||||||
>>> m = torchvision.models.resnet18(pretrained=True)
|
|
||||||
>>> # extract layer1 and layer3, giving as names `feat1` and feat2`
|
|
||||||
>>> new_m = torchvision.models._utils.IntermediateLayerGetter(m,
|
|
||||||
>>> {'layer1': 'feat1', 'layer3': 'feat2'})
|
|
||||||
>>> out = new_m(torch.rand(1, 3, 224, 224))
|
|
||||||
>>> print([(k, v.shape) for k, v in out.items()])
|
|
||||||
>>> [('feat1', torch.Size([1, 64, 56, 56])),
|
|
||||||
>>> ('feat2', torch.Size([1, 256, 14, 14]))]
|
|
||||||
"""
|
|
||||||
def __init__(self, model, return_layers, hrnet_flag=False):
|
|
||||||
if not set(return_layers).issubset([name for name, _ in model.named_children()]):
|
|
||||||
raise ValueError("return_layers are not present in model")
|
|
||||||
|
|
||||||
self.hrnet_flag = hrnet_flag
|
|
||||||
|
|
||||||
orig_return_layers = return_layers
|
|
||||||
return_layers = {k: v for k, v in return_layers.items()}
|
|
||||||
layers = OrderedDict()
|
|
||||||
for name, module in model.named_children():
|
|
||||||
layers[name] = module
|
|
||||||
if name in return_layers:
|
|
||||||
del return_layers[name]
|
|
||||||
if not return_layers:
|
|
||||||
break
|
|
||||||
|
|
||||||
super(IntermediateLayerGetter, self).__init__(layers)
|
|
||||||
self.return_layers = orig_return_layers
|
|
||||||
|
|
||||||
def forward(self, x):
|
|
||||||
out = OrderedDict()
|
|
||||||
for name, module in self.named_children():
|
|
||||||
if self.hrnet_flag and name.startswith('transition'): # if using hrnet, you need to take care of transition
|
|
||||||
if name == 'transition1': # in transition1, you need to split the module to two streams first
|
|
||||||
x = [trans(x) for trans in module]
|
|
||||||
else: # all other transition is just an extra one stream split
|
|
||||||
x.append(module(x[-1]))
|
|
||||||
else: # other models (ex:resnet,mobilenet) are convolutions in series.
|
|
||||||
x = module(x)
|
|
||||||
|
|
||||||
if name in self.return_layers:
|
|
||||||
out_name = self.return_layers[name]
|
|
||||||
if name == 'stage4' and self.hrnet_flag: # In HRNetV2, we upsample and concat all outputs streams together
|
|
||||||
output_h, output_w = x[0].size(2), x[0].size(3) # Upsample to size of highest resolution stream
|
|
||||||
x1 = F.interpolate(x[1], size=(output_h, output_w), mode='bilinear', align_corners=False)
|
|
||||||
x2 = F.interpolate(x[2], size=(output_h, output_w), mode='bilinear', align_corners=False)
|
|
||||||
x3 = F.interpolate(x[3], size=(output_h, output_w), mode='bilinear', align_corners=False)
|
|
||||||
x = torch.cat([x[0], x1, x2, x3], dim=1)
|
|
||||||
out[out_name] = x
|
|
||||||
else:
|
|
||||||
out[out_name] = x
|
|
||||||
return out
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue