FlightGear 模拟微调标签轮
组件和用品
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
应用和在线服务
| ||||
| ||||
|
关于这个项目
将 Arduino 连接到 FlightGear 并不是什么新鲜事,但我发现 wiki 已经过时,论坛提供了宝贵的提示,您必须解决该问题。
这个想法是有一个漂亮、便宜和紧凑的模拟命令来控制 FlightGear 中飞机的升降舵配平轮。 wiki 一直工作到交流部分。严格来说,您不能直接使用串行通信将命令从 Arduino 传递到 FlightGear。您必须使用 Python 解决方法才能通过 UDP 发送数据包。
什么是修边轮?它是一种模拟装置,用于控制配平片的偏转,这是一种空气动力学装置,可将操纵面(在这种情况下是控制飞机俯仰的升降舵)保持在给定位置,而无需飞行员的努力。来自维基百科:
此项目的附加要求:带有库 serial
的 python , socket
, 和 sys
安装。假设已经安装了 Anaconda,可以在 Anaconda 提示符下键入:
>>> conda install -c anaconda pyserial
与 serial
相同 和 socket
.在 Internet 上搜索合适的软件包,通常为您的平台下载最多的软件包是好的。一旦你有了带有这些库的 Python(当然,也安装了 FlightGear),你可以转到下一部分。
共有三种代码脚本:Arduino 草图、python 可执行脚本和 XML 脚本。 Arduino 草图必须加载到您的板上。必须执行 python 脚本才能启用 Arduino 和 FlightGear 之间的通信。 XML 脚本是 FlightGear 通用协议,必须移动到
Arduino 草图需要 U8glib
图书馆。如评论中所述,用您的显示器调整草图的第 2 行:
#include U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0); // I2C / TWI
见U8glib
示例和文档。即使没有显示器,草图也能正常工作,因此您可以在没有来自电路板的视觉反馈的情况下进行游戏。
如果你对旋转方向不满意,只需在下面的map
中切换最后两个参数的位置 说明
w =map(p,0,1023,100,-100);m =map(p,0,1023,90,0);
使电位器的值从 -100 变为 100,指针的量规从 0 变为 90(这是将指针拉到正确位置的技巧,如果您好奇,请自行尝试)。
python脚本包括主机地址和串口号。主机应该是 "localhost"
(如果它不起作用,请尝试使用 127.0.0.1
),端口 any(也许最好是其他应用程序未使用的端口,我不知道),您的开发板连接的串行端口可以从 Arduino IDE 读取。就我而言,它是 "COM4"
. 注意:如果您使用串行监视器测试 Arduino,您可能需要在执行 python 脚本之前断开并重新连接您的电路板,以使其正常工作。
host ="localhost"port =21567#buf =1024addr =(host,port)UDPSock =socket(AF_INET,SOCK_DGRAM)tty="COM4"print("tty is ", tty)
python 脚本可以位于任何地方。您可以从操作系统的命令行执行它。在我的情况下(Windows),我输入命令提示符:
python c:\path\to\file\arduinoElevatorTrim.py
这可能会在启动 FlightGear 之前或之后启动。
最后,如前所述,必须在 FlightGear 安装的协议文件夹中一次性移动 XML 脚本。现在你准备好了。通过添加以下命令以您的首选模式(命令行或启动器)启动 FlightGear (字符之间没有空格!) :
--generic=socket,in,30,localhost,21567,udp,arduinoElevatorTrim
我们告诉 FlightGear 通过套接字应用通用协议,每秒读取 30 次输入,地址为 localhost,端口 21567,UDP 协议,arduinoElevatorTrim.xml 文件中的指令。享受您的个人装饰轮!
代码
- arduinoElevatorTrimOLED.ino
- arduinoElevatorTrim.py
- arduinoElevatorTrim.xml
arduinoElevatorTrimOLED.inoArduino
在 Arduino Nano 上加载的代码。根据需要调整第 2 行(显示类型)。#includeU8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0); // I2C / TWI int xmax =128; int ymax =64; int xcenter =xmax/2; int ycenter =ymax/2+10; int 弧 =ymax/2;整数角 =0;字符*标签=“修剪”; int labelXpos =53; int p, w, m;u8g_uint_t xx =0;int const potPin =A6;float potVal;// 自定义函数void Gauge(uint8_t angle) { // 绘制仪表的边框 u8g.drawCircle(xcenter,ycenter,arc+6, U8G_DRAW_UPPER_RIGHT); u8g.drawCircle(xcenter,ycenter,arc+4, U8G_DRAW_UPPER_RIGHT); u8g.drawCircle(xcenter,ycenter,arc+6, U8G_DRAW_UPPER_LEFT); u8g.drawCircle(xcenter,ycenter,arc+4, U8G_DRAW_UPPER_LEFT); // 画针 float x1 =sin(2*angle*2*3.14/360);浮动 y1 =cos(2*角度*2*3.14/360); u8g.drawLine(xcenter, ycenter, xcenter+arc*x1, ycenter-arc*y1); u8g.drawDisc(xcenter, ycenter, 5, U8G_DRAW_UPPER_LEFT); u8g.drawDisc(xcenter, ycenter, 5, U8G_DRAW_UPPER_RIGHT); u8g.setFont(u8g_font_chikita); // 显示比例标签// u8g.drawStr( 10, 42, "-1.0"); // u8g.drawStr( 19, 14, "-0.5");// u8g.drawStr( 63, 14, "0");// u8g.drawStr( 92, 14, "0.5");// u8g. drawStr(105, 42, "1.0"); u8g.drawStr(1, 42, "DOWN"); u8g.drawStr( 52, 17 , "NEUT"); u8g.drawStr(105, 42, "UP"); // 显示仪表标签 u8g.setPrintPos(labelXpos,32); u8g.print(标签); // 显示数字值并对齐其位置 u8g.setFont(u8g_font_profont22);如果 (w>=99) { u8g.setPrintPos(47,60); } if (w>=10 &&w <99) { u8g.setPrintPos(54,60); } if (w>=0 &&w <9) { u8g.setPrintPos(60,60); } if (w>=-9 &&w <0) { u8g.setPrintPos(48,60); } if (w>=-99 &&w <-9) { u8g.setPrintPos(42,60); } if (w <-99) { u8g.setPrintPos(35,60); } u8g.print(w);}void setup() { Serial.begin(9600); u8g.setFont(u8g_font_chikita); u8g.setColorIndex(1); // 分配默认颜色值 if ( u8g.getMode() ==U8G_MODE_R3G3B2 ) { u8g.setColorIndex(255); } else if ( u8g.getMode() ==U8G_MODE_GRAY2BIT ) { u8g.setColorIndex(3); } else if ( u8g.getMode() ==U8G_MODE_BW ) { u8g.setColorIndex(1); } else if ( u8g.getMode() ==U8G_MODE_HICOLOR ) { u8g.setHiColorByRGB(255,255,255); }}void loop() { potVal =analogRead(potPin); potVal =(potVal - 512.0)/512.0; Serial.print(potVal); Serial.print("\n"); // p 与potVal 相同,但它是一个整数 p =analogRead(potPin); w =地图(p,0,1023,100,-100); m =地图(p,0,1023,90,0); // 显示指针并拨 xx =m;如果 (xx <45){ xx =xx + 135; } else { xx =xx - 45; } // 图片循环{ u8g.firstPage();做{仪表(xx); } while( u8g.nextPage() ); }延迟(10);}
arduinoElevatorTrim.pyPython
与 FlightGear 一起执行的脚本,用于将串行通信“转换”为 UDP 数据包。您需要安装 Python 才能执行此脚本。根据需要修改第 14 行(连接 Arduino 的 USB 端口)。#!/usr/bin/pythonimport sysimport serialfrom socket import *host ="localhost"port =21567#buf =1024addr =(host,port)UDPSock =socket(AF_INET,SOCK_DGRAM)tty="COM4"print("tty is ", tty)try:ser =serial.Serial(tty,9600)except:print("Error connected to " , tty) prevline=""while 1:outline='' line=ser.readline() if line !=prevline:#some value changed print(line) outline=line UDPSock.sendto(outline,addr) prevline=line
arduinoElevatorTrim.xmlXML
要添加到文件夹\n , 电梯修剪 /controls/flight/elevator-trim float
Github
Github 上的在线存储库 https://github.com/dciliberti/arduinoElevatorTrimOLED示意图
在 Fritzing 中,不可能在组件下方通过电线。显示器的地线可能位于 Arduino Nano 下方。制造工艺