5iMX宗旨:分享遥控模型兴趣爱好

5iMX.com 我爱模型 玩家论坛 ——专业遥控模型和无人机玩家论坛(玩模型就上我爱模型,创始于2003年)
楼主: 切风40.83
打印 上一主题 下一主题

GPS 罗盘 四轴导航(这几天风大,做了个地面站界面)

[复制链接]
41
 楼主| 发表于 2011-12-25 04:05 | 只看该作者
点击查看详情
前天考完之后立即 去电影院 看碟中谍了。 今天刚刚把负责通讯和导航的单片机 ( 我们以后就叫它 A#1 , 另一块单片机叫 A#2) 的程序写好了, 而且测试过了。

接线方法:
GPS TX = D2
GPS RX = D3  (要是搞不清楚就随便接一下,没反应就对调)


罗盘 SCL = A4
罗盘 SDA = A5(要是没反应就对调 A4 A5)


A#1 D1 = A#2 D0


注: DX 表示 数字端口X, AX 表示模拟端口X


这个程序会从A#1 通过串口发送滚转和俯仰的控制量到A#2  (信号是一个6个数字的数字串)
A#2 通过串口接受 再把数字串 转换成 滚转和俯仰的 控制量。


#include <Wire.h>
#include <NewSoftSerial.h>
#include <TinyGPS.h>

TinyGPS gps;
NewSoftSerial uart_gps(2, 3);

String val;
int r=0;
int p=0;
long lat0, lon0, latc, lonc;


void setup()
{
  Wire.begin();
  Serial.begin(9600);
  uart_gps.begin(9600);
}


void loop(){
  if(uart_gps.available()){
    int c = uart_gps.read();    // load the data into a variable...
    if(gps.encode(c)){      // if there is a new valid sentence...
      gps.get_position(&latc, &lonc);         
    }
  }
  else{
    byte highByte, lowByte;            
    float bearing;                              

    Wire.beginTransmission(0x60);         
    Wire.send(2);                             
    Wire.endTransmission();

    Wire.requestFrom(0x60, 2);            
    while(Wire.available() < 2);
    highByte = Wire.receive();           
    lowByte = Wire.receive();            

    bearing = ((highByte<<8)+lowByte)/10;
    bearing = bearing/57;

    r = cos(bearing)*(lat0-latc)-sin(bearing)*(lon0-lonc);
    p = sin(bearing)*(lat0-latc)+cos(bearing)*(lon0-lonc);
    r = constrain(r,-49,49);
    p = constrain(p,-49,49);
    val = String(r+150)+String(p+150);
    Serial.println(val);

  }
  int mode = digitalRead(11);
  if(mode==HIGH){
    if(uart_gps.available()){
      int c = uart_gps.read();    // load the data into a variable...
      if(gps.encode(c)){      // if there is a new valid sentence...
        gps.get_position(&lat0, &lon0);

      }
    }
  }
}

欢迎继续阅读楼主其他信息

42
 楼主| 发表于 2011-12-25 05:38 | 只看该作者
A#2 的程序 和接线方法。
目前程序还没有融入任何高度控制, 这个过两天再考虑。

预计的效果是这样的:

1. 通道六开关,关闭。

2. 启动后 等半分钟,给GPS充分的时间启动。

3. 手动起飞。

4. 通道六开关, 打开。

5. 这时候 飞碟是混控的, 你可以强行控制飞碟。 如果你放开操纵杆, 飞机会自动飞回到你拨开关时候的位置。( 这样也是为了安全考虑。 之前的红外壁障功能也是样的。第四通道也是手动控制的。但是不管飞碟头朝哪个方向,都能自己飘回来)

如果关闭开关,飞碟又回到手动控制模式

代码:
#include <Servo.h>
String readString;
Servo roll;
Servo pitch;
Servo throttle;

int mode = 0;
int R;
int P;
long ch1, ch2, ch3, ch6;
int p = 1500;
int r = 1500;

void autopilot();
void output();

void setup(){

  pinMode(3,INPUT);
  pinMode(4,INPUT);
  pinMode(5,INPUT);
  pinMode(6,INPUT);
  pinMode(11,OUTPUT);

  roll.attach(7);
  pitch.attach(8);
  throttle.attach(9);

  ch1 = pulseIn(3,HIGH);
  ch2 = pulseIn(4,HIGH);

  Serial.begin(9600);

}


void loop(){

  if(ch6 > 1500){
    digitalWrite(11,HIGH);

    ch1 = pulseIn(3,HIGH);
    ch3 = pulseIn(5,HIGH);
    p = ch1;

    output();
    autopilot();

    /*------------------------------------------------------------------*/

    ch2 = pulseIn(4,HIGH);
    ch6 = pulseIn(6,HIGH);
    r = ch2;

    output();
    autopilot();

  }

  else{                    //(else) lasts 40ms

    ch1 = pulseIn(3,HIGH);
    ch3 = pulseIn(5,HIGH);
    r = ch1;

    output();

   /*------------------------------------------------------------------*/

    ch2 = pulseIn(4,HIGH);
    ch6 = pulseIn(6,HIGH);
    p = ch2;

    output();  

  }

}

void autopilot(){
  if (Serial.available()) {
    delay(10);
    if (Serial.available() >0) {
      char c = Serial.read();
      readString += c;
    }
  }

  if (readString.length() == 6) {
    Serial.println(readString);
    R = (readString.charAt(1)-48)*10 + (readString.charAt(2)-48) - 50;   
    P = (readString.charAt(4)-48)*10 + (readString.charAt(5)-48) - 50;
    r = ch1 + R;
    p = ch2 + P;
    readString="";
  }


}

void output(){
  roll.writeMicroseconds(p);
  pitch.writeMicroseconds(r);
  throttle.writeMicroseconds(ch3);
}
43
 楼主| 发表于 2011-12-25 05:48 | 只看该作者
还有什么问题到我群里去问。

其实我早就不像在这个论坛发帖子了,这个论坛和几年前相比真是差远了。

但是为了兑现诺言,我还是会把这个帖子更新到这个项目结束为止。
44
发表于 2011-12-25 21:36 | 只看该作者
定你楼主,希望能出个成品卖
45
发表于 2011-12-25 22:03 | 只看该作者
期待,果然很补错~
46
 楼主| 发表于 2011-12-26 06:34 | 只看该作者
今天天气不好, 我的四轴扛不住风。 所以没有测试。 但是我把代码又改进了许多。
47
 楼主| 发表于 2011-12-26 09:31 | 只看该作者
没测试得了, 反正闲着也是闲着,于是就做了个地面站。 我四轴上的GPS坐标传回来,地图上就会出现白点,表示飞碟的位置。 用的IDE 是 processing, 也是开源的。
界面就是一张地图 和一个白点。 至于方向啊,速度啊, 海拔之类的以后再慢慢加上去。

[ 本帖最后由 切风40.83 于 2011-12-26 11:18 编辑 ]

377797_311297942236465_100000687866636_991083_111170062_n.jpg (69.53 KB, 下载次数: 70)

377797_311297942236465_100000687866636_991083_111170062_n.jpg

382902_311341722232087_100000687866636_991376_821753122_n.jpg (80.14 KB, 下载次数: 54)

加上了数字显示,更加直观

加上了数字显示,更加直观
48
发表于 2011-12-26 10:40 | 只看该作者
学习了,顶起来~~~
49
 楼主| 发表于 2011-12-27 08:16 | 只看该作者
今天场外测试了下。 纠正了些小错误。 但是还是飞不了,我的四轴抗风能力太弱了。

我知道大家看了代码就头疼,我也一样。 A#1通过串口发出的信息如下:

.5050.5050   如果要需要向前方飞的话 .5023.5023

A#2 解码后 R=0, P=0  如果往前飞的话: R=0, P=50-23=27
50
发表于 2011-12-28 20:15 | 只看该作者
楼主 我顶你
因为我也在搞这个东西:em15:
四轴的导航
51
发表于 2011-12-28 20:17 | 只看该作者
不过俺是业余的
目前还在初步测试GPS和AVR的计算能力
打算先用M8+3310+瑟夫3带的GPS 做个自己走路的导航
也就是在3310上面显示GPS信息 和离家距离 以及回家方向
类似于FPV中OSD的功能
52
 楼主| 发表于 2011-12-29 06:14 | 只看该作者
原来楼上也是同行啊。 幸会:em00:
不妨到我群里聊聊。

我的四轴已经做了十几次地面测试了,能想到会出问题的地方都进行了单向测试。 就等哪天没风,空中测完了好给大家交差。往后就永久潜水了。:em15:
53
发表于 2011-12-29 09:18 | 只看该作者
我也在玩,难道你们的姿态融合和PID控制都做出来了吗?
54
发表于 2011-12-29 09:24 | 只看该作者

回复 53楼 切风40.83 的帖子

:em00: :em00:
呵呵 目前的计划是先给行人导航
然后安装到四轴上 给四轴导航
四轴用的是玉兔的飞控 还算不错
目前的方案是用模拟开关CD4066控制遥控接收机或者单片机控制板对飞控板的控制权
飞控板上安装了无线透明串口(号称1.5公里的距离)气压计+数字指南针模块+GPS
主控目前用的是AVR的M8 估计是不够用 ,但是目前仅仅是开发GPS的导航 所以应该是够了。
过几天回了家就改成M16
55
发表于 2011-12-31 08:54 | 只看该作者
楼主的群号多少?
56
 楼主| 发表于 2012-1-4 07:13 | 只看该作者
号: 三宜三舅四舅溜溜
57
 楼主| 发表于 2012-1-4 07:16 | 只看该作者
今天没风,室外温度零下6,出去测试。

结果接收机脉冲采样有严重的干扰。 不知道哪里来的干扰。 以前出现过一次。 又没测试得了。 :em25:
58
发表于 2012-1-5 15:27 | 只看该作者
机架木质 哈哈
59
发表于 2012-2-21 19:15 | 只看该作者
:em16: 头大了
60
发表于 2012-2-21 20:39 | 只看该作者
强烈支持
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

关闭

【站内推荐】上一条 /2 下一条

快速回复 返回顶部 返回列表