Rossum--ROSjava-android控制ROS机器人

From:http://blog.csdn.net/f_season/article/details/9177545

在看文章之前,请确定你已经熟悉了ROS和rosjava,并且具备基本的android开发经验

这个机器人由上网本作为核心,在ubuntu上运行ROS系统,由android端辅助控制。这里主要将android的ROSjava部分,会在以后分篇详述。

第一篇,总体介绍ROSjava-android在这个机器人设计中发挥了怎么样的作用。这个android控制程序有如下功能:英文语音识别,能在脱机状况下语音控制机器人的基本运动;中文语音识别,语音控制并可以布置机器人任务(比如去某地区寻找某物体,和人对话等);最基本的按键控制和舵机控制


整个rosjava程序由主程序PocketSphinxROS.java、处理发送命令的dispose.java、IsrActivity.java中文语音识别、R开头的几个英文语音识别文件和Talk开头的几个负责发送各种命令的文件组成。这里就先介绍下PocketSphinxROS.java,为什么取这个名字,因为最开始主要为了开发PocketSphinx英文语音,后来功能增多名字也就没改。

[java]  view plain copy
  1. package rosjava.wtf.pocketsphinx.version1;  
  2.   
  3. import java.util.Date;  
  4.   
  5. import android.app.ProgressDialog;  
  6. import android.content.Intent;  
  7. import android.os.Bundle;  
  8. import android.os.Handler;  
  9. import android.util.Log;  
  10. import android.view.MotionEvent;  
  11. import android.view.View;  
  12. import android.view.View.OnTouchListener;  
  13. import android.widget.Button;  
  14. import android.widget.SeekBar;  
  15. import android.widget.TextView;  
  16. import android.widget.SeekBar.OnSeekBarChangeListener;  
  17.   
  18. import org.ros.address.InetAddressFactory;  
  19. import org.ros.android.MessageCallable;  
  20. import org.ros.android.RosActivity;  
  21. import org.ros.android.view.RosTextView;  
  22. import org.ros.node.NodeConfiguration;  
  23. import org.ros.node.NodeMainExecutor;  
  24.   
  25. import rosjava.wtf.pocketsphinx.version1.IsrActivity;  
  26. import rosjava.wtf.pocketsphinx.version1.RecognitionListener;  
  27. import rosjava.wtf.pocketsphinx.version1.RecognizerTask;  
  28. import rosjava.wtf.pocketsphinx.version1.TalkChnString;  
  29. import rosjava.wtf.pocketsphinx.version1.TalkEnString;  
  30. import rosjava.wtf.pocketsphinx.version1.TalkParam;  
  31.   
  32. import edu.cmu.pocketsphinx.demo.R;  
  33.   
  34. public class PocketSphinxROS extends RosActivity implements OnTouchListener, RecognitionListener {  
  35.   
  36.   private RosTextView<std_msgs.String> rosTextView;  
  37.   private TalkParam talker;  
  38.   private TalkEnString talkerenstring;  
  39.   private TalkChnString talkerchnstring;  
  40.   private TalkServo talkerserver;  
  41.   private TalkObject talkerobject;  
  42.   public Button forward,back,right,left,stop,btn_isr_demo,revive;  
  43.   public static boolean send=false,sendenstring=false,sendchnstring=false,sendservo=true,sendobject=false;  
  44.   public Handler handler = new Handler(){};  
  45.   //servo  
  46.   public TextView Value01,Value02;  
  47.   public static SeekBar servo1;  
  48.   public static SeekBar servo2;  
  49.     
  50.   public PocketSphinxROS() {  
  51.     // The RosActivity constructor configures the notification title and ticker  
  52.     // messages.  
  53.     super("Pubsub Tutorial""Pubsub Tutorial");  
  54.   }  
  55. //*pocketsphinx***************************************************************************************  
  56.   
  57.   static {  
  58.     System.loadLibrary("pocketsphinx_jni");  
  59.   }  
  60.   /**  
  61.    * Recognizer task, which runs in a worker thread.  
  62.    */  
  63.   RecognizerTask rec;  
  64.   /** 
  65.    * Thread in which the recognizer task runs. 
  66.    */  
  67.   Thread rec_thread;  
  68.   /** 
  69.    * Time at which current recognition started. 
  70.    */  
  71.   Date start_date;  
  72.   /** 
  73.    * Number of seconds of speech. 
  74.    */  
  75.   float speech_dur;  
  76.   /** 
  77.    * Are we listening? 
  78.    */  
  79.   boolean listening;  
  80.   /** 
  81.    * Progress dialog for final recognition. 
  82.    */  
  83.   ProgressDialog rec_dialog;  
  84.   /** 
  85.    * Performance counter view. 
  86.    */  
  87.   static TextView performance_text;  
  88.   /** 
  89.    * Editable text view. 
  90.    */  
  91.   
  92.   public boolean onTouch(View v, MotionEvent event) {  
  93.     switch (event.getAction()) {  
  94.     case MotionEvent.ACTION_DOWN:  
  95.       start_date = new Date();  
  96.       this.listening = true;  
  97.       this.rec.start();  
  98.       break;  
  99.     case MotionEvent.ACTION_UP:  
  100.       if (this.listening) {  
  101.         Log.d(getClass().getName(), "Showing Dialog");  
  102.         this.rec_dialog = ProgressDialog.show(this"""Recognizing speech..."true);  
  103.         this.rec_dialog.setCancelable(false);  
  104.         this.listening = false;  
  105.       }  
  106.       this.rec.stop();  
  107.       break;  
  108.     default:  
  109.       ;  
  110.     }  
  111.     /* Let the button handle its own state */  
  112.     return false;  
  113.   }  
  114. //****************************************************************************************  
  115.   @SuppressWarnings("unchecked")  
  116.   @Override  
  117.   public void onCreate(Bundle savedInstanceState) {  
  118.     super.onCreate(savedInstanceState);  
  119.     setContentView(R.layout.main);  
  120.     rosTextView = (RosTextView<std_msgs.String>) findViewById(R.id.text);  
  121.     rosTextView.setTopicName("recognizer/output");  
  122.     rosTextView.setMessageType(std_msgs.String._TYPE);  
  123.     rosTextView.setMessageToStringCallable(new MessageCallable<String, std_msgs.String>() {  
  124.       @Override  
  125.       public String call(std_msgs.String message) {  
  126.         return message.getData();  
  127.       }  
  128.     });  
  129.     this.rec = new RecognizerTask();  
  130.     this.rec_thread = new Thread(this.rec);  
  131.     this.listening = false;  
  132.     Button voice = (Button) findViewById(R.id.Voice);  
  133.     voice.setOnTouchListener(this);  
  134.     performance_text = (TextView) findViewById(R.id.PerformanceText);   
  135.     this.rec.setRecognitionListener(this);  
  136.     this.rec_thread.start();  
  137.       
  138.     forward = (Button)findViewById(R.id.forward);  
  139.     back = (Button)findViewById(R.id.back);  
  140.     right = (Button)findViewById(R.id.right);  
  141.     left = (Button)findViewById(R.id.left);  
  142.     stop = (Button)findViewById(R.id.stop);  
  143.     revive = (Button)findViewById(R.id.revive);  
  144.     btn_isr_demo=(Button)findViewById(R.id.btn_isr_demo);  
  145.       
  146.     Value01 = (TextView)findViewById(R.id.value1);  
  147.     Value02 = (TextView)findViewById(R.id.value2);  
  148.     final SeekBar servo1 = (SeekBar)findViewById(R.id.servo1); //左右  
  149.     final SeekBar servo2 = (SeekBar)findViewById(R.id.servo2); //上下  
  150.     servo1.setMax(180);  
  151.     servo1.setProgress(73);  
  152.     servo2.setMax(150);  
  153.     servo2.setProgress(145);  
  154.       
  155.     forward.setOnTouchListener(new OnTouchListener(){  
  156.         @Override  
  157.         public boolean onTouch(View v, MotionEvent event) {  
  158.           if (event.getAction() == MotionEvent.ACTION_DOWN)  
  159.           {  
  160.               dispose.control("forward");  
  161.             send=true;  
  162.           }  
  163.           else if(event.getAction() == MotionEvent.ACTION_UP)  
  164.           {  
  165.               send=false;  
  166.               sendenstring=true;  
  167.               sendchnstring=true;  
  168.           }  
  169.          return false;  
  170.          }  
  171.           });  
  172.     back.setOnTouchListener(new OnTouchListener(){  
  173.         @Override  
  174.         public boolean onTouch(View v, MotionEvent event) {  
  175.           if (event.getAction() == MotionEvent.ACTION_DOWN)  
  176.           {  
  177.               dispose.control("back");  
  178.              send=true;  
  179.           }  
  180.           else if(event.getAction() == MotionEvent.ACTION_UP)  
  181.           {  
  182.               send=false;  
  183.               sendenstring=true;  
  184.               sendchnstring=true;  
  185.           }  
  186.          return false;  
  187.          }  
  188.           });  
  189.     left.setOnTouchListener(new OnTouchListener(){  
  190.         @Override  
  191.         public boolean onTouch(View v, MotionEvent event) {  
  192.           if (event.getAction() == MotionEvent.ACTION_DOWN)  
  193.           {  
  194.             dispose.control("left");  
  195.             send=true;  
  196.           }  
  197.           else if(event.getAction() == MotionEvent.ACTION_UP)  
  198.           {  
  199.               send=false;  
  200.               sendenstring=true;  
  201.               sendchnstring=true;  
  202.           }  
  203.          return false;  
  204.          }  
  205.           });  
  206.     right.setOnTouchListener(new OnTouchListener(){  
  207.         @Override  
  208.         public boolean onTouch(View v, MotionEvent event) {  
  209.           if (event.getAction() == MotionEvent.ACTION_DOWN)  
  210.           {  
  211.               dispose.control("right");  
  212.             send=true;  
  213.           }  
  214.           else if(event.getAction() == MotionEvent.ACTION_UP)  
  215.           {  
  216.               send=false;  
  217.               sendenstring=true;  
  218.               sendchnstring=true;  
  219.           }  
  220.          return false;  
  221.          }  
  222.           });  
  223.        stop.setOnTouchListener(new OnTouchListener(){  
  224.         @Override  
  225.         public boolean onTouch(View v, MotionEvent event) {  
  226.           if (event.getAction() == MotionEvent.ACTION_DOWN)  
  227.           {  
  228.               dispose.control("stop");  
  229.             send = false;                 
  230.           }  
  231.           else if(event.getAction() == MotionEvent.ACTION_UP)  
  232.           {  
  233.               sendenstring=true;  
  234.               sendchnstring=true;  
  235.           }  
  236.          return false;  
  237.          }  
  238.           });  
  239.        btn_isr_demo.setOnTouchListener(new OnTouchListener(){  
  240.            @Override  
  241.            public boolean onTouch(View v, MotionEvent event) {  
  242.              if (event.getAction() == MotionEvent.ACTION_DOWN)  
  243.              {  
  244.              }  
  245.              else if(event.getAction() == MotionEvent.ACTION_UP)  
  246.              {  
  247.                 Intent intent = new Intent();  
  248.                 intent.setClass(PocketSphinxROS.this,IsrActivity.class);  
  249.                  startActivity(intent);  
  250.              }  
  251.             return false;  
  252.             }  
  253.              });  
  254.        revive.setOnTouchListener(new OnTouchListener(){  
  255.            @Override  
  256.            public boolean onTouch(View v, MotionEvent event) {  
  257.              if (event.getAction() == MotionEvent.ACTION_DOWN)  
  258.              {  
  259.                  dispose.control("revive");  
  260.              }  
  261.              else if(event.getAction() == MotionEvent.ACTION_UP)  
  262.              {  
  263.               send=false;  
  264.              servo1.setProgress(73);  
  265.              servo2.setProgress(145);  
  266.              }  
  267.             return false;  
  268.             }  
  269.              });  
  270.          
  271.        servo1.setOnSeekBarChangeListener(new OnSeekBarChangeListener(){  
  272.               @Override  
  273.               public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)  
  274.               {  
  275.                   if(progress > 150){  
  276.                         Value01.setText("当前角度:" + 0.6 );  
  277.                         TalkServo.pos[0]=0.6;  
  278.                   }  
  279.                   else{  
  280.                       Value01.setText("当前角度:" + ((float)(progress-90)/100 ));  
  281.                       TalkServo.pos[0]=(float)(progress-90)/100;  
  282.                 }  
  283.                 sendservo=true;  
  284.               }  
  285.               @Override  
  286.               public void onStartTrackingTouch(SeekBar seekBar)  
  287.               {  
  288.               }  
  289.               @Override  
  290.               public void onStopTrackingTouch(SeekBar seekBar)  
  291.               {   
  292.               }             
  293.             });  
  294.               
  295.             servo2.setOnSeekBarChangeListener(new OnSeekBarChangeListener(){  
  296.               @Override  
  297.               public void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser)  
  298.               {  
  299.                 Value02.setText("当前角度:" +((float)(progress-75)/100));                
  300.                 TalkServo.pos[1]=(float)(progress-75)/100;  
  301.                 sendservo=true;  
  302.               }  
  303.               @Override  
  304.               public void onStartTrackingTouch(SeekBar seekBar)  
  305.               {  
  306.               }  
  307.               @Override  
  308.               public void onStopTrackingTouch(SeekBar seekBar)  
  309.               {  
  310.               }  
  311.               });  
  312.   }  
  313.     //Voice Control   
  314.     /** Called when partial results are generated. */  
  315.     public void onPartialResults(Bundle b) {  
  316.       final String hyp = b.getString("hyp");  
  317.       handler.post(new Runnable() {  
  318.           public void run() {  
  319.             performance_text.setText(hyp);  
  320.           }  
  321.         });  
  322.     }  
  323.   
  324.     /** Called with full results are generated. */  
  325.     public void onResults(Bundle b) {  
  326.         final String hyp = b.getString("hyp");  
  327.         final PocketSphinxROS that = this;  
  328.           handler.post(new Runnable() {  
  329.             public void run() {  
  330.                 performance_text.setText(hyp);  
  331.                 dispose.control(hyp);  
  332.                 sendenstring=true;  
  333.                 send=true;  
  334.                 Log.d(getClass().getName(), "Hiding Dialog");  
  335.                 that.rec_dialog.dismiss();  
  336.             }  
  337.         });  
  338.     }  
  339.   
  340.     public void onError(int err) {     
  341.     }     
  342.     @Override  
  343.     protected void init(NodeMainExecutor nodeMainExecutor) {  
  344.         // TODO Auto-generated method stub  
  345.         talker = new TalkParam();  
  346.         talkerenstring = new TalkEnString();  
  347.         talkerchnstring = new TalkChnString();  
  348.         talkerserver = new TalkServo();  
  349.         talkerobject = new TalkObject();  
  350.          NodeConfiguration nodeConfiguration = NodeConfiguration.newPublic(InetAddressFactory.newNonLoopback().getHostAddress(), getMasterUri());  
  351.          // 这里用户已经被提示输入master的URI来开始或启动本地master  
  352.          nodeConfiguration.setMasterUri(getMasterUri());  
  353.          nodeMainExecutor.execute(talker, nodeConfiguration);  
  354.          nodeMainExecutor.execute(talkerenstring, nodeConfiguration);  
  355.          nodeMainExecutor.execute(talkerchnstring, nodeConfiguration);  
  356.          nodeMainExecutor.execute(talkerserver, nodeConfiguration);  
  357.          nodeMainExecutor.execute(talkerobject, nodeConfiguration);  
  358.          //  RosTextView作为显示输入信息是必须存在的  
  359.          nodeMainExecutor.execute(rosTextView, nodeConfiguration);  
  360.        }      
  361. }  
打开程序首先是填写masterURI,告诉rosjava连接到哪个master上。然后进入这个简陋的操作界面。其中有前后左右的基本命令按钮,2个舵机控制滑条,英文识别语音按钮和跳转到中文语音识别activity的按钮。

开发过pocketsphinx语音识别的一定很熟悉其中部分代码,这个是pocketsphinx的固定套路。中文语音我用了讯飞的引擎,联网的状况下效果很好。信息通道建立部分,我建了6个ROS节点,talker(TalkParam)负责发送控制电机的参数命令,使用geometry_msgs/Twist格式。talkerchnstring(TalkChnString)负责发送中文语音识别信息到PC的ROS,使用std_msgs.String._TYPE格式。talkerenstring(TalkEnString)负责发送英文语音识别信息。这里要说明,中文使用讯飞是需要联网才能识别的,而英文pocketsphinx是可以脱机小范围语音识别,用于应对恶劣情况(没网络)。talkerserver(TalkServo)是负责发送控制舵机的命令,使用sensor_msgs/JointState格式。talkerobject(TalkObject)负责把需要寻找的物体名发给机器人,使用std_msgs.String._TYPE格式。这里说明下,我们的机器人具有物体识别能力,通过发送物体名称给机器人,机器人就会明白自己的任务,然后去寻找该物体。

总结,以上代码是由3部分组成:RosActivity中固定格式,包括master连接和节点以及主题的建立;各个功能按键的设定;pocketsphinx英文语音。详细的请看后续文章。



by:season


  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值