ROS-Vicon-Crazypony通信

ROS-Serial-Crazypony通信

從第二次開始學(xué)ros到成功進(jìn)行串口通信,讀取vicon數(shù)據(jù)他嚷,再將高度信息發(fā)送給crazypony花了差不多十天的時(shí)間嗤攻,最后的主控程序其實(shí)很短很短,但是終于能完成最基本的功能了屿愚,可喜可賀可喜可賀:)孟害。

首先寫出代碼

#include     <stdio.h>      /*標(biāo)準(zhǔn)輸入輸出定義*/
#include     <stdlib.h>     /*標(biāo)準(zhǔn)函數(shù)庫定義*/
#include     <unistd.h>     /*Unix 標(biāo)準(zhǔn)函數(shù)定義*/
#include     <sys/types.h>  
#include     <sys/stat.h>   
#include     <fcntl.h>      /*文件控制定義*/
#include     <termios.h>    /*PPSIX 終端控制定義*/
#include     <errno.h>      /*錯(cuò)誤號(hào)定義*/
#include     <iostream>
#include     <pthread.h>
#include     <cstdlib>
#include     <string.h>

#include     <ros/ros.h>
#include     <std_msgs/String.h>
#include     <sstream>
#include     <vicon_bridge/Marker.h>
#include     <geometry_msgs/TransformStamped.h>
#include     <geometry_msgs/Transform.h>
#include     <geometry_msgs/Vector3.h>
#include     <geometry_msgs/Quaternion.h>


using namespace std;

int fd=open( "/dev/ttyUSB0", O_RDWR|O_NOCTTY|O_NDELAY);
int nread;
char buff[512];
char tempbuff[512];
int buffnum=0;
char test;
char tempone;  //臨時(shí)字符,用做通信協(xié)議
char temptwo;
int status;
int flag=0;


void *tx(void*)
{
    while(1)
    {
        if(fscanf(stdin,"%c",&test)>0)
            {   
            printf("write\n");
            if(test=='s')
            {
                flag=1;
                close(fd);
                printf("Exit Tx");
            }
            tempone='c';
            write(fd,&tempone,1);
                write(fd,&test,1);
            tempone='s';
            write(fd,&tempone,1);
            }
    }
    printf("Exit Tx");
}

void *rx(void*)
{
    int i=0;
     while(flag==0)
     {
         if((nread=read(fd,buff,512))>0)
             {
            printf("%s\n",buff);
            for(i=0;i<nread;i++)
            {
                tempbuff[buffnum]=buff[i];
        //      printf("%s\n",tempbuff);
                buffnum++;
                if(tempbuff[buffnum-1]=='!')
                {
        //          printf("%s\n",tempbuff);
                    tempbuff[0]='\0';
                    buffnum=0;
                }
            }
         }
          }
    
     printf("Exit Rx");
}

int height;
void callback(const geometry_msgs::TransformStamped& msg)
{
    //測試用,Z是高度孤钦,于實(shí)際同號(hào)
    //printf("translation.x %f  ",msg.transform.translation.x);
    //printf("translation.y %f  ",msg.transform.translation.y);
    //printf("translation.z %f\n",msg.transform.translation.z);
    height=(int)(msg.transform.translation.z*100.0);
    //printf("send %d,height %f\n",height,height/100.0);
    temptwo='h';
    write(fd,&temptwo,1);
    write(fd,&height,1);
    temptwo='s';
    write(fd,&temptwo,1);
}


void *spin(void*)
{
    ros::spin();
}

int main(int argc,char **argv)
{
    //打開串口
    int count;
    printf("begin\n");
    if (fcntl(fd,F_SETFL,0)<0)
    { 
        perror(" 提示錯(cuò)誤!\n"); 
        return 1;
    }
    else
        printf("success open USB0\n");
    //設(shè)置串口纯丸,termios.h中定義了終端控制結(jié)構(gòu)體和POSIX控制函數(shù)
    if(0==isatty(STDIN_FILENO))
    {
        printf("standard input is not terminal device\n");
        return 1;
    }
    
    struct termios options;
    tcgetattr(fd, &options);
    //set speed
    cfsetispeed(&options, B115200);
    cfsetospeed(&options, B115200);

    //保證程序不會(huì)成為端口所有者
    options.c_cflag |= (CLOCAL | CREAD);

    //無校驗(yàn)偏形,8位
    options.c_cflag &= ~PARENB;  
    options.c_cflag &= ~CSTOPB;
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;

    options.c_cflag &= ~CRTSCTS;  //不使用流控制

    options.c_iflag &= ~INPCK;  

    //原始模式通信
    options.c_lflag  &= ~(ICANON | ECHO | ECHOE | ISIG);  //原始數(shù)據(jù)輸入
    options.c_oflag  &= ~OPOST;   //原始數(shù)據(jù)輸出

    tcflush(fd,TCIFLUSH);  //數(shù)據(jù)溢出時(shí)接受數(shù)據(jù)但不讀取

        tcsetattr(fd,TCSANOW,&options);
        status=tcsetattr(fd,TCSANOW,&options);
    if(status!=0)
    {
        perror("com set error");
        return 1;
    }
    
    pthread_t tids[3];  
    //ROS 訂閱發(fā)布消息 
    ros::init(argc,argv,"CP_Posture");  
    ros::NodeHandle n;
    ros::Publisher chatter_pub=n.advertise<std_msgs::String>("posture",1000);
    ros::Subscriber sub=n.subscribe("vicon/CP1_1/CP1_1",1000,callback);
    ros::Rate loop_rate(1);
        

    
    int retRx=pthread_create(&tids[0],NULL,rx,NULL);
    int retTx=pthread_create(&tids[1],NULL,tx,NULL);    
    int retSub=pthread_create(&tids[2],NULL,spin,NULL); 
        
    while(1)
    {
        if(ros::ok)
        {
            //printf("hello\n");
            count++;
            std_msgs::String msg;
            std::stringstream ss;
            ss << "hello" << count;
            msg.data = ss.str();
                        
            chatter_pub.publish(msg);
            loop_rate.sleep();
            ros::spinOnce();
        }
    }

    
    //異常檢測
    if(retRx!=0)
    {
        printf("retRX error\n");
    }
    if(retTx!=0)
    {
        printf("retTX error\n");
    }
    
    pthread_exit(NULL); 

    close(fd);
return 0;
}   

代碼流程

mian函數(shù):

初始化串口設(shè)置:115200B,8位數(shù)據(jù)位觉鼻,無控制流俊扭,無校驗(yàn),這個(gè)程序在很多人的博客已經(jīng)寫到了坠陈,我 僅僅寫出了與我的無人機(jī)匹配的設(shè)置模式萨惑,沒有其他設(shè)置模式的代碼。

打開了三個(gè)線程:RX用于讀取串口仇矾,TX用于寫串口庸蔼,Sub用于訂閱vicon節(jié)點(diǎn)并且通過無線發(fā)送,之所于 要使用者三個(gè)線程贮匕,我的想法是因?yàn)閞ead函數(shù)姐仅、write函數(shù)、ROSmsg函數(shù)都要寫到循環(huán)里,但是如果寫到一個(gè)函數(shù)里就會(huì)陷入等待中掏膏,所以我開了一個(gè)線程專門用來讀緩沖區(qū)劳翰,一個(gè)線程等待輸入,第三個(gè)線程是因?yàn)閞os::spins會(huì)一直自循環(huán)馒疹,所以額外開了一個(gè)線程并把功能都寫入了回調(diào)函數(shù)磕道。

關(guān)于是開多線程還是利用ROS的優(yōu)勢使用topic通信進(jìn)行控制,我的考慮是因?yàn)閒d這個(gè)文件指針會(huì)被占用行冰,所以應(yīng)該把write和read寫進(jìn)一個(gè)程序,這樣控制程序也自然應(yīng)寫在同一個(gè)函數(shù)伶丐,但是因?yàn)槲彝耆珱]有學(xué)習(xí)過C++悼做,也對串口的API細(xì)節(jié)不了解,所以也并不確定哗魂。

有一個(gè)要注意的點(diǎn)是要記得及時(shí)銷毀文件指針肛走,在*rx和*tx里我使用test和flag就是想要控制銷毀該指針(但是最后的結(jié)果很奇怪,在我輸入s后tx確實(shí)不再寫串口也打印了Tx Exit录别,但是但我輸入時(shí)仍然會(huì)打印write)朽色,如果不及時(shí)銷毀,直接關(guān)閉終端會(huì)使ttyUSB0被占用(我也不確定是不是被占用组题,因?yàn)槲以?dev/里找不到ttyUSB0了葫男,只有ttyUSB1,如果繼續(xù)使用ttyUSB1崔列,那么下一次dev里就只有ttyUSB2了)

最后梢褐,整個(gè)過程中最蛋疼的一點(diǎn)是,我使用crazypony做地面站時(shí)赵讯,怎么都無法串口通信盈咳,我檢查程序檢查驅(qū)動(dòng)一切都似乎沒有問題,然后我嘗試把地面站程序移植到了一塊開發(fā)板边翼,就直接可以通信了鱼响。我猜想是因?yàn)閏p2102驅(qū)動(dòng)的問題(雖然我系統(tǒng)顯示我驅(qū)動(dòng)沒問題),開發(fā)板是ch340的就直接可以用了组底。真的有毒丈积。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市斤寇,隨后出現(xiàn)的幾起案子桶癣,更是在濱河造成了極大的恐慌,老刑警劉巖娘锁,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件牙寞,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)间雀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門悔详,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人惹挟,你說我怎么就攤上這事茄螃。” “怎么了连锯?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵归苍,是天一觀的道長。 經(jīng)常有香客問我运怖,道長拼弃,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任摇展,我火速辦了婚禮吻氧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘咏连。我一直安慰自己盯孙,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布祟滴。 她就那樣靜靜地躺著振惰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪垄懂。 梳的紋絲不亂的頭發(fā)上报账,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天,我揣著相機(jī)與錄音埠偿,去河邊找鬼透罢。 笑死,一個(gè)胖子當(dāng)著我的面吹牛冠蒋,可吹牛的內(nèi)容都是我干的羽圃。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼抖剿,長吁一口氣:“原來是場噩夢啊……” “哼朽寞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起斩郎,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤脑融,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后缩宜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肘迎,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡甥温,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了妓布。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片姻蚓。...
    茶點(diǎn)故事閱讀 39,834評論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖匣沼,靈堂內(nèi)的尸體忽然破棺而出狰挡,到底是詐尸還是另有隱情,我是刑警寧澤释涛,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布加叁,位于F島的核電站,受9級特大地震影響唇撬,放射性物質(zhì)發(fā)生泄漏殉农。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一局荚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧愈污,春花似錦耀态、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至杭跪,卻和暖如春仙逻,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背涧尿。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工系奉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人姑廉。 一個(gè)月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓缺亮,卻偏偏與公主長得像,于是被迫代替她去往敵國和親桥言。 傳聞我的和親對象是個(gè)殘疾皇子萌踱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 姓名:莫益彰 學(xué)號(hào):16030140019 【嵌牛導(dǎo)讀】:串口通信是指外設(shè)和計(jì)算機(jī)間,通過數(shù)據(jù)信號(hào)線 号阿、地線并鸵、控制...
    換個(gè)名字消消毒閱讀 1,588評論 1 5
  • *面試心聲:其實(shí)這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個(gè)offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,140評論 30 470
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,111評論 25 707
  • 這里并不對串口的編程作講解,主要是從應(yīng)用的角度去講一講粉铐。因?yàn)楦嗟臅r(shí)候疼约,都是產(chǎn)品做好了,比如觸摸屏需要和控制器蝙泼,P...
    我是嘻哈大哥閱讀 4,048評論 1 9
  • 認(rèn)識(shí)小玫的時(shí)候程剥,我十五歲,她也十五歲汤踏。那年我住在外婆家织鲸,也在那邊念中學(xué),知道高考結(jié)束才回自己家溪胶。那期間搂擦,小玫就是我...
    蔓蔓幔青蘿閱讀 894評論 0 1