Para os queridos leitores do GeekTimes, o próximo (quarto) artigo
aguardado sobre o que acontecerá se você misturar novamente o arduino, ESP8266, WI-FI, tempere com um smartphone Android e salpique sobre o aplicativo JAVA.
Falaremos sobre os robôs do
artigo antes da última, que chegou a hora de pelo menos ficar um pouco mais inteligente.

Quem se importa, bem-vindo ao gato.
Se você não está muito interessado em ler artigos antigos, então brevemente - o ponto era que, para controlar o carrinho de quatro rodas habitual na plataforma Arduino, uma ponte UART sem fio desenvolvida por mim com base no conhecido módulo ESP8266 foi adicionada a ele. Também por conveniência (e em geral esse era o objetivo principal) usando o mesmo ESP, escrevi um programador para o arduinki, que permite que você faça o flash remotamente.

Ou seja, o carrinho em algum lugar distante (mas dentro da sua rede WI-FI) viaja (sim, eu gosto de escrever essa palavra), envia dados e recebe comandos e, se necessário, por ordem, também pode alterar o programa no microcontrolador AVR. Consequentemente, o programa em JAVA para o PC foi executado, executando o qual você pode ter controle e obter telemetria primitiva na forma da distância percorrida (chave reed e ímã no volante).

Além disso, experimentei com sucesso no próximo
artigo controlar o carrinho usando um smartphone - botões, inclinações e até voz. Mas quando o carrinho partiu para a próxima sala, mesmo a voz não pôde devolvê-lo (ao contrário do gato). Ela foi até lá, bateu nas paredes e nos móveis, enredou-se nos fios, mas além de informações sobre a distância percorrida, ela não enviou nada.
Portanto, surgiu imediatamente a idéia de fornecer ao futuro Terminator órgãos sensoriais. Uma das opções mais fáceis para isso é o uso do sonar.

O algoritmo de trabalho para a desgraça é simples, iniciamos o sensor de uma frente e, ao mesmo tempo, um contador de microcontrolador. O HC-SR04 começa a balançar o ultrassom à distância. O sinal de resposta do sensor através de outro fio sinaliza o final da medição da distância e o intervalo de tempo entre o início e a resposta é proporcional à distância medida. Assim, nesse momento desaceleramos o balcão e vemos quanto ele entrou.
A precisão é obtida até cerca de um centímetro e um intervalo de metros a dois. Ele não gosta de superfícies felpudas e de lã (por exemplo, um gato), onde qualquer sinal de eco se afoga irrevogavelmente.
A área afetada, o ângulo de visão do HC-SR04, é pequeno; portanto, para saber o que está acontecendo à frente no âmbito de um ângulo de pelo menos 90 graus, é recomendável fazer o seguinte:
- parafuse o sensor na máquina servo e olhe-o em direções diferentes
- coloque alguns sensores.
No início, implementei a primeira opção, colocando o sonar em um servo barato SG90 e o carrinho se transformou em um veículo espacial. Foi necessário tanto tempo para realizar pelo menos três medições, então, basicamente, o carrinho ficou rodando com um servo, depois avançou cuidadosamente, mas não muito longe (e de repente um obstáculo apareceu ao lado), e novamente sentiu o espaço à sua frente. Ainda assim, o som não é a luz para você.
Portanto, sem mais delongas, coloquei três sistemas de sonar ao mesmo tempo. O carrinho adquiriu uma aparência de aranha crônica, parou embotado na frente de obstáculos e começou a taxiá-los em movimento. Mas, no final, os cérebros eram suficientes para não ficarem presos em um ambiente amigável. Tivemos que seguir em frente - para autonomia e progresso. E aqui, sem sentidos diferentes, até o worm nematóide dirá, você não pode fazê-lo.
Além disso, geralmente os entusiastas começam a esculpir em suas criações vários novos sensores, como giroscópios, acelerômetros-magnetômetros e até sensores FIRE (todos os chineses sem nome produzem em milhões de quantidades para o Arduino). E eu também quase comecei por esse caminho escorregadio, mas mudei de idéia com o tempo. E eu fiz isso por esse motivo. Na perspectiva mais distante, o robô robótico deveria ter visão na forma de uma câmera e também entender o que vê. Mas o microcontrolador AVR da placa Arduino diz adeus a você, mesmo na fase de recebimento do vídeo, sem mencionar o processamento. E de repente meu olhar caiu no velho smartphone GALAXY S7, já agredido pela vida.
Tal poder de computação, oito núcleos, 4 gigabytes de memória, duas câmeras, acesso à rede, o que mais é necessário para transformar um macaco em uma pessoa?
Mas precisamos apenas de um design pequeno para que o smartphone repouse em um carrinho e possa ser facilmente colocado e removido.

Então subi no site de desenvolvedores do Android para descobrir quais outros recursos um smartphone comum pode nos dar. Acabou que não é pequeno. Teoricamente você pode
acesse os seguintes sensores sensores.TYPE_ACCELEROMETER
TYPE_AMBIENT_TEMPERATURE
TYPE_GAME_ROTATION_VECTOR
GEOMAGNETIC_ROTATION_VECTOR
TYPE_GRAVITY
TYPE_GYROSCOPE
TYPE_GYROSCOPE_UNCALIBRATED
TYPE_HEART_BEAT
TYPE_HEART_RATE
TYPE_LIGHT
TYPE_LINEAR_ACCELERATION
TYPE_LOW_LATENCY_OFFBODY_DETECT
TYPE_MAGNETIC_FIELD
TYPE_MAGNETIC_FIELD_UNCALIBRATED
TYPE_MOTION_DETECT
TYPE_ORIENTATION
TYPE_POSE_6DOF
TYPE_PRESSURE
TYPE_PROXIMITY
TYPE_RELATIVE_HUMIDITY
TYPE_ROTATION_VECTOR
TYPE_SIGNIFICANT_MOTION
TYPE_STATIONARY_DETECT
TYPE_STEP_COUNTER
TYPE_STEP_DETECTOR
Como se costuma dizer, o que há apenas! E, de fato, não havia muito específico para o GALAXY S7. Por exemplo, um sensor de umidade. E a temperatura ambiente (embora eu entenda que, por estar dentro do gabinete, ele mostrará a temperatura do próprio smartphone). Mas os sensores de pressão e luz estavam presentes. Sem mencionar os giroscópios, acelerômetros, com os quais você pode facilmente determinar sua posição no espaço.
Como resultado, uma decisão amadureceu, deixe o smartphone receber e processar todas as informações de nível superior - vídeo e todos esses vários sensores. E a plataforma Arduino será responsável, por assim dizer, pelo inconsciente - por tudo o que já funciona e não requer retrabalho, todos esses motores, sonar, chaves de palheta e assim por diante.
Como é difícil depurar o programa diretamente no smartphone, mesmo com o UDB, decidi que tudo seria transferido para um computador pessoal normal e processado lá. E então, de alguma forma, quando houver uma versão funcional, retornaremos os cérebros de volta ao carrinho. Temos que começar pequenos e, de fato, é interessante observar a transmissão de vídeo de um carrinho frenético.
Os dados dos sensores podem ser enviados em uma linha simples, através de um servidor cliente primitivo, não há problemas com isso. Mas com a transferência do vídeo, imediatamente houve dificuldades. Em geral, eu precisava de uma transmissão em tempo real da câmera do smartphone para a janela do aplicativo no computador. Isso é por enquanto. No futuro, não apenas eu, mas algum tipo de sistema de reconhecimento de padrões poderia olhar para essa foto na janela. Por exemplo, JAVA OpenCV. Ou talvez até uma rede neural da nuvem: D. Não sei, esse estágio ainda está muito longe. Mas eu gostaria de ver o mundo com o "olho" de um caminhão robótico.
Todo mundo conhece vários aplicativos, como uma "câmera móvel" da loja do Google, onde você captura um fluxo de vídeo da câmera de um smartphone abrindo um navegador com o IP desejado no computador. Portanto, no começo eu pensei que não seria difícil traduzir do meu GALAXY (o que não foi um erro fraco), então primeiro você precisa verificar como será a recepção no computador, já que eu posso escrever de alguma forma apenas em JAVA.
Como se viu, com a reprodução de vídeo JAVA, para dizer o mínimo, não muito bem. Em 1997, foi lançado o chamado Java Media Framework - uma biblioteca que facilita o desenvolvimento de programas que funcionam com áudio e vídeo pelos próprios criadores do JAVA. Mas, em algum lugar depois de 2003, um grande raio foi colocado nele e desde então já faz 15 anos. Após algumas experiências, consegui executar um arquivo na janela, não me lembro qual deles já (parece AVI), mas essa visão parecia bastante infeliz. Arquivos com outras extensões não desejavam ser executados; em casos extremos, havia uma faixa de áudio.
Na Internet, encontrei mais dois projetos alternativos para trabalhar com vídeo: Xuggler e aprica VLCj. O primeiro projeto era atraente em suas capacidades, mas também morreu há muito tempo, mas o segundo acabou sendo bastante animado e interessante em sua própria idéia. Os caras pegaram e prenderam ao JAVA o conhecido popular media player VLC. Ou seja, o aprica não usa codecs auto-escritos, mas usa codecs prontos. Com ele, você perderá qualquer arquivo. Uma decisão sábia, mas o principal é que você já possui esse VLC player instalado no seu computador. Bem, quem não tem? A única ressalva, no entanto, é que você tem as mesmas profundidades de bits do player e do JAVA. Por exemplo, mais tarde, com surpresa, descobri que ainda tinha um VLC de 32 bits no computador, em contraste com o JAVA de 64 bits. E meio dia de vida foi perdido em vão.
Os desenvolvedores de Caprica prometem aos usuários muitas coisas em seu site. E todos os formatos de arquivo e inicialização em várias janelas em um aplicativo JAVA, reproduzindo vídeos do You-Tube, capturando um fluxo de vídeo "ao vivo" e assim por diante. Mas a dura realidade coloca tudo em seu lugar. Não, eles não enganaram com arquivos - tudo é reproduzido. Mas agora o vídeo do YouTube não quer mais. No começo, eu não conseguia entender o porquê, mas então vi uma inscrição no log que, de alguma forma, era impossível executar um determinado script lua e lembrei imediatamente:
Essa "captura de tela" da página da Web do YouTube é quebradiça - se o YouTube alterar a estrutura de suas páginas da Web, o VLC às vezes falha em encontrar o URL de streaming. Quando isso acontece, você precisa esperar que um desenvolvedor forneça uma nova LUA script e aguarde o lançamento de uma nova versão do VLC.
Em suma, aparentemente o YouTube mudou a estrutura de sua página da web e preciso aguardar um novo lançamento. Por outro lado, preciso de uma transmissão de vídeo "ao vivo" e não reproduzir um arquivo do site. Ou seja, mesmo que o script lua funcionasse, isso não me ajudaria muito.
Mas não encontrei o streaming prometido, embora tenha sido escrito que:
Servidor de streaming de rede (por exemplo, uma estação de rádio em rede ou um servidor de vídeo sob demanda);
Cliente de streaming de rede;
Talvez seja uma lista de desejos, ou talvez esteja na versão comercial, é difícil dizer.
Mas os arquivos são reproduzidos, repito, sem queixas. Por exemplo, você pode criar, aqui está essa indecência
A instalação do pacote em si não é difícil e é descrita até em detalhes, por exemplo,
aqui . É verdade que, de alguma forma, prescrevi desajeitadamente variáveis de ambiente e agora meu VLC inicia pela primeira vez com um atraso de dez segundos, mas salva o necessário no cache e, posteriormente, na sessão atual, inicia sem pausas.
Então, no seu projeto JAVA, você prescreve as dependências necessárias e pode começar a
reproduzir os media players nas janelas JAVA para funcionar.
Depois de marcar o plano de trabalho aproximado na lateral do computador pessoal, voltei à fonte dos dados de vídeo, meu smartphone ANDROID.
Mas aqui eu estava esperando outra decepção bastante grande. Depois de digitalizar alguns sites e até o manual ANDROID on-line, descobri que é impossível organizar a transmissão em tempo real usando meios regulares. Como em Caprica, você só pode ler arquivos já gravados. Ou seja, com a câmera ligada, o MEDIA RECORDER começou a gravar quando precisou ser interrompido. E podemos ter acesso aos dados (e sua transferência) somente após uma parada.
Encontrei confirmação de minhas conclusões em um
artigo antigo. Havia realmente dicas de que, uma vez que alguém conseguiu induzir o Android a pensar que ele estava gravando em um arquivo, mas na verdade eles deixaram um buffer. Mas, de qualquer forma, como já foi explicado anteriormente, não foi possível capturar um fluxo de vídeo no lado do PC no aplicativo JAVA.
Portanto, foi tomada uma decisão simples,
temporária , em carvalho (quero enfatizar) - enviar um fluxo de vídeo da câmera em pedaços por dois segundos. Não é um rover, é claro, mas o rover já sai bastante.
Tendo decidido sobre essa decisão, comecei a dominar as aulas de CAMERA e MEDIA RECORDER. Existem alguns exemplos de código na rede para iniciar a câmera e gravar arquivos de vídeo, mas por algum motivo, nenhum deles funcionou para mim. Nem no emulador, nem em um dispositivo real. Descobriu-se que o motivo está nas permissões, ou seja, nas permissões. Acontece que exemplos de código foram escritos naqueles dias em que o Android ainda estava livre e o programador poderia fazer o que quisesse se escrevesse todas as permissões necessárias no manifesto. Mas minha versão atual do OC não permitiu isso. Primeiro, você tinha que dar ao usuário permissão para gravar o arquivo e ligar a câmera imediatamente após iniciar o aplicativo. Isso me custou atividade extra, ou seja, em Atividade.
Classe MainActivity.javaimport android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; import android.hardware.Camera; import android.media.MediaRecorder; import android.os.AsyncTask; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.Toast; import java.io.File; public class MainActivity extends AppCompatActivity { Camera camera; MediaRecorder mediaRecorder; public static MainActivity m; public static boolean Camera_granted; File videoFile; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if ((ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) ||(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) )
Depois disso, tudo correu bem e o seguinte código de funcionamento apareceu. A segunda atividade da classe Camera_Activity é responsável por trabalhar com a câmera e gravar arquivos de vídeo. Classe Http_server para encaminhamento (o nome, é claro, está incorreto, mas acabou historicamente). O código é simples, sempre que houver uma explicação.

Tudo está completamente no Github.
LinkCamera_Activity import android.hardware.Camera; import android.media.MediaRecorder; import android.os.AsyncTask; import android.os.Bundle; import android.os.Environment; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.widget.Button; import android.widget.TextView; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.ServerSocket; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.content.Context; import android.hardware.Sensor; import static android.hardware.Camera.getNumberOfCameras; import java.io.BufferedOutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; public class CameraActivity extends AppCompatActivity implements SensorEventListener { SurfaceView surfaceView; TextView mTextView; Button mStart; Button mStop; Camera camera; MediaRecorder mediaRecorder; public static ServerSocket ss; public static ServerSocket ss2; public static MainActivity m; public static volatile boolean stopCamera=true; public static int count=1; public static File videoFile1; public static File videoFile2; public static File videoFile3; public static volatile byte[] data; public SensorManager mSensorManager; public Sensor mAxeleration, mLight,mRotation,mHumidity,mPressure,mTemperature; public int ax; public int ay; public int az; public double light; public int x; public int y; public int z; public double hum; public double press; public double tempr; public static String Sensors; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
A essência do programa após iniciar e ligar a câmera é a seguinte:
escreva um vídeo por dois segundos no primeiro arquivo,
escrevemos o vídeo por dois segundos no segundo arquivo e, enquanto isso, enviamos o primeiro arquivo via TCP-IP via WI-FI local para o computador,
escreva o primeiro arquivo novamente e, enquanto isso, envie o segundo,
e assim por diante.
Em seguida, o ciclo se repete até o botão "parar" ser pressionado ou a bateria do smartphone acabar. Em princípio, é possível implementar um análogo de pressionar botões, usando comandos de um computador, também via TCP, isso não é difícil.
A princípio, o buffer de vídeo consistia em três arquivos no formato 3GP (escrevemos o primeiro, enviamos o terceiro, escrevemos o segundo, enviamos o primeiro, escrevemos o terceiro, enviamos o segundo), mas depois os arquivos são suficientes (gravando e enviando um ao outro) não interfira).
Com uma resolução de câmera de 640 por 480, os arquivos são obtidos, algo em torno de 200-300 kB, o que é bastante difícil para o meu roteador. Ainda não me incomodei com o som, mas tudo parece simples: você instala os codificadores de áudio, as taxas de bits, o número de canais e similares.
Um pouco mais tarde, quando depurei a transferência de vídeo, suplementei o código também transmitindo informações dos sensores do smartphone. Tudo é transmitido trivialmente em uma linha, mas não foi possível transferi-lo pelo mesmo soquete do vídeo. Aparentemente, as classes para a transmissão de uma sequência PrintWriter e a transmissão de dados binários BufferedOutputStream usam fluxos diferentes, mas, em seguida, eles têm um buffer de saída, no qual são bem sucedidos. Como resultado, o vídeo começa a falhar e desmoronar. Além disso, o arquivo de vídeo é transmitido a cada dois segundos e, para sensores, esse intervalo é muito grande. Portanto, foi decidido distribuí-los em diferentes soquetes para que eles não interfiram entre si. Por esse motivo, uma nova classe Http_server_Sensors apareceu.
Assim, organizamos a expedição, agora novamente retornaremos ao lado negro de recebimento.
Como já vimos desde o primeiro exemplo, reproduzir arquivos de vídeo em um aplicativo JAVA usando um player VLC agora não apresenta problemas. O principal é obter esses arquivos.
O seguinte programa de demonstração é responsável por isso.
Video player import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.SwingUtilities; import uk.co.caprica.vlcj.component.EmbeddedMediaPlayerComponent; import uk.co.caprica.vlcj.discovery.NativeDiscovery; import uk.co.caprica.vlcj.player.MediaPlayer; import uk.co.caprica.vlcj.player.MediaPlayerEventAdapter; import java.io.*; import java.net.Socket; public class VideoPlayer { public final JFrame frame; public static EmbeddedMediaPlayerComponent mediaPlayerComponent; public final JButton pauseButton; public final JButton rewindButton; public final JButton skipButton; public static String mr1, mr2; public static boolean playing_finished = false; public static boolean File_1_play_starting = false; public static boolean File_1_play_finished = false; public static boolean File_2_play_starting = false; public static boolean File_2_play_finished = false;
Sua essência é simples. Um cliente TCP é iniciado, que começa a aguardar o servidor estar pronto no smartphone. Após receber o primeiro arquivo, ele começa a ser reproduzido imediatamente e o arquivo número dois é esperado em paralelo. Além disso, espera-se o final da recepção do segundo arquivo ou o final da reprodução do primeiro. O melhor de tudo, é claro,
três estrelas , quando o arquivo é baixado mais rapidamente do que é reproduzido. Se você perdeu o primeiro arquivo, mas ainda não recebeu o segundo, tudo está aguardando ... Demonstraremos uma tela preta. Caso contrário, comece rapidamente a reproduzir o segundo arquivo e baixe o primeiro novamente.
Eu tinha uma vaga esperança de que a pausa entre a troca de arquivos reproduzidos fosse menor que o tempo de reação do olho humano, mas não se concretizou. Lazer, é claro, este VLC.
Como resultado, temos um tipo de vídeo vil e descontínuo (o primeiro trilobita, aparentemente, viu o mundo assim), onde a nitidez ainda está sendo constantemente ajustada. E devemos levar em conta que o vídeo também está atrasado por dois segundos. Em resumo, na produção, eu não recomendo espalhá-lo. Mas eu tenho falta de peixe e trilobita, como eles dizem ...
Resumindo o exposto, podemos absolutamente dizer que:
O envio de vídeo em partes é essencialmente inoperante e só pode ser útil nos casos em que o vídeo é longo o suficiente e você não precisa de uma segunda reação ao que está acontecendo.
A transmissão de vídeo por TCP-IP também é uma idéia incorreta, independentemente do que algumas personalidades de Habr diriam sobre a velocidade de transferência de dados usando esse protocolo (que é supostamente ainda mais rápido que o UDP). Obviamente, as intranets sem fio modernas têm boas características para garantir handshakes contínuos de servidores e clientes TCP, e o próprio TCP parece ter sido atualizado para dados longos, mas ainda assim os plugues entre a reprodução de vídeos aparecem periodicamente na demonstração.
Mas, pelo menos para o futuro, surgiram os seguintes pensamentos:
- envie quadro a quadro (não vídeo, mas fotos) via UDP, mas controle as informações via TCP,
- conduza molduras por todo o UDP, mas com sinais de sincronização no mesmo canal.
Obviamente, até agora há mais perguntas do que respostas. Existe velocidade de recepção suficiente no JAVA com seu nível de abstração ao trabalhar com a rede e as imagens? É possível fazer 30 fotos normais por segundo no nível acessível para mim no Android? Vou ter que colher antes de enviar para reduzir a taxa de bits? E o JAVA é suficiente para empacotar e descompactar? E se, de repente, algo der certo, será possível seguir o próximo passo, danificar o sistema de visão computacional JAVA OpenCV aqui? Ele mesmo, é claro, sempre é interessante assistir a vídeos em fluxo desde o nível do chão, mas não devemos esquecer o objetivo mais alto - um robô robótico com a inteligência de uma formiga!
Mas, enquanto tivermos o que temos, retornaremos ao carrinho atual. O antigo programa do artigo anterior para o microcontrolador AVR na plataforma Arduino não mudou muito, apenas a opção de ramificação foi adicionada - direção autônoma ou controlada pelo operador. Os dados que o carrinho (medula espinhal) transmite via WIFI são os mesmos - a distância percorrida. Um pouco mais tarde, também anexei a transferência de temperatura de um elemento crítico - o driver do motor. Tudo isso é transmitido e recebido primeiro pelo UART, e já ao entrar na rede via UDP. Não dou o código, toda a análise completa no
artigo antes da última
.
Para dois motores, o (driver) ainda é suficiente, mais ou menos, mas com quatro depois de um tempo superaquece para um estado inoperante. No começo, tentei usar os sensores analógicos de temperatura mais simples baseados em diodos zener, como o LM335, mas nada resultou disso. Eu não tinha uma fonte de tensão de referência, para abreviar, ION.
E pegar milivolts com uma bateria fraca não faz sentido. A propósito, sobre a bateria - quando eu estava cansado de remover e reinserir constantemente 14500 baterias de lítio para recarregar, peguei uma bateria sobressalente de uma chave de fenda e o carrinho começou a funcionar continuamente por uma hora e meia, além de ter uma aparência e peso ameaçadores (sim, está nesta bateria "Olhos"). Portanto, para medir a temperatura, instalei um acelerômetro giroscópio com defeito, baseado no L3G4200D. Felizmente, ele também mediu a temperatura e a transmitiu através do barramento I2C.Um smartphone sentado atrás da bateria e sobre os olhos do eco-sonar transmite um fluxo de vídeo, leituras do acelerômetro (você pode usá-lo para inclinar o carrinho e a inclinação do carrinho quando está em pé), girar e inclinar em graus na dinâmica já calculada pelo próprio smartphone (uma opção muito conveniente) , aceleração linear na direção da viagem, iluminação. Em geral, é claro, você pode transferir tudo o que seu smartphone pode medir da pressão do ar para a direção norte.Como resultado, o aplicativo em JAVA adquiriu a seguinte forma:
O engraçado é que ele realmente se parece com um painel de controle de um Lunokhod soviético, só que eu tenho uma tela de TV ao lado e eles a têm no centro.
Ao ligá-lo, primeiro conecte-se ao carrinho e ao smartphone, selecione o modo de controle manual ou autonomia total - e pronto! Até a janela de temperatura do motorista ficar amarela e depois vermelha. Gráficos!Algo assim parece vivo.Não trago o programa aqui, porque, como sempre, a construção de janelas ocupa 95% do código. Pode ser encontrado aqui.No futuro, o cérebro (smartphone) deve aprender a transferir vídeo normal (e não o que é agora) para um computador, onde deve ser reconhecido de alguma maneira de uma maneira boa (enquanto o objetivo é criar um mapa da sala no nível do chão e determinar sua localização). Bem, e já sob o comunismo, gostaria de portá-lo de volta para o meu smartphone para que ele não precisasse de um computador.Se pelo menos algo der certo, eu definitivamente o publicarei. Obrigado pela atenção.