FollowerActivity.java
Go to the documentation of this file.
00001 package com.github.turtlebot.turtlebot_android.follower;
00002 
00003 import org.ros.address.InetAddressFactory;
00004 import org.ros.android.BitmapFromCompressedImage;
00005 import com.github.rosjava.android_apps.application_management.RosAppActivity;
00006 import org.ros.android.view.RosImageView;
00007 import org.ros.exception.RemoteException;
00008 import org.ros.exception.ServiceNotFoundException;
00009 import org.ros.namespace.GraphName;
00010 import org.ros.namespace.NameResolver;
00011 import org.ros.node.AbstractNodeMain;
00012 import org.ros.node.ConnectedNode;
00013 import org.ros.node.NodeConfiguration;
00014 import org.ros.node.NodeMainExecutor;
00015 import org.ros.node.service.ServiceClient;
00016 import org.ros.node.service.ServiceResponseListener;
00017 
00018 import android.os.Bundle;
00019 import android.os.StrictMode;
00020 import android.util.Log;
00021 import android.view.Menu;
00022 import android.view.MenuItem;
00023 import android.view.View;
00024 import android.view.View.OnClickListener;
00025 import android.widget.Button;
00026 import android.widget.ImageButton;
00027 import android.widget.Toast;
00028 
00029 public class FollowerActivity extends RosAppActivity
00030 {
00031   private Toast    lastToast;
00032   private ConnectedNode node;
00033   private RosImageView<sensor_msgs.CompressedImage> cameraView;
00034   private static final String cameraTopic = "camera/rgb/image_color/compressed_throttle";
00035 
00036 
00037   public FollowerActivity()
00038   {
00039     super("FollowerActivity", "FollowerActivity");
00040   }
00041 
00043   @Override
00044   public void onCreate(Bundle savedInstanceState)
00045   {
00046     setDefaultMasterName(getString(R.string.default_robot));
00047     setDefaultAppName(getString(R.string.default_app));
00048     setDashboardResource(R.id.top_bar);
00049     setMainWindowResource(R.layout.main);
00050 
00051     super.onCreate(savedInstanceState);
00052 
00053     cameraView = (RosImageView<sensor_msgs.CompressedImage>)findViewById(R.id.image);
00054     cameraView.setMessageType(sensor_msgs.CompressedImage._TYPE);
00055     cameraView.setMessageToBitmapCallable(new BitmapFromCompressedImage());
00056 
00057     // Register input controls callbacks
00058     Button backButton = (Button) findViewById(R.id.back_button);
00059     backButton.setOnClickListener(backButtonListener);
00060 
00061     ImageButton startButton = (ImageButton)findViewById(R.id.button_start);
00062     startButton.setOnClickListener(startButtonListener);
00063 
00064     ImageButton stopButton = (ImageButton)findViewById(R.id.button_stop);
00065     stopButton.setOnClickListener(stopButtonListener);
00066 
00067     // TODO Tricky solution to the StrictMode; the recommended way is by using AsyncTask
00068     if (android.os.Build.VERSION.SDK_INT > 9) {
00069       StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
00070       StrictMode.setThreadPolicy(policy);
00071     }
00072   }
00073 
00074 
00075   @Override
00076   protected void init(NodeMainExecutor nodeMainExecutor)
00077   {
00078     super.init(nodeMainExecutor);
00079 
00080     NodeConfiguration nodeConfiguration =
00081       NodeConfiguration.newPublic(InetAddressFactory.newNonLoopback().getHostAddress(), getMasterUri());
00082 
00083     // Execute camera view node
00084     cameraView.setTopicName(getMasterNameSpace().resolve(cameraTopic).toString());
00085     nodeMainExecutor.execute(cameraView, nodeConfiguration.setNodeName("android/camera_view"));
00086 
00087     // Execute another node just to allow calling services; I suppose there will be a shortcut for this in the future
00088     nodeMainExecutor.execute(new AbstractNodeMain()
00089     {
00090       @Override
00091       public GraphName getDefaultNodeName()
00092       {
00093         return GraphName.of("android/follower");
00094       }
00095 
00096       @Override
00097       public void onStart(final ConnectedNode connectedNode)
00098       {
00099         node = connectedNode;
00100       }
00101     }, nodeConfiguration.setNodeName("android/follower"));
00102   }
00103 
00104   @Override
00105   public boolean onCreateOptionsMenu(Menu menu)
00106   {
00107     menu.add(0,0,0,R.string.stop_app);
00108     return super.onCreateOptionsMenu(menu);
00109   }
00110 
00111   @Override
00112   public boolean onOptionsItemSelected(MenuItem item)
00113   {
00114     super.onOptionsItemSelected(item);
00115     switch (item.getItemId()){
00116     case 0:
00117         onDestroy();
00118         break;
00119     }
00120     return true;
00121   }
00122 
00123   private void callService(byte newState)
00124   {
00125     if (node == null)
00126     {
00127       Log.e("FollowerActivity", "Still doesn't have a connected node");
00128       return;
00129     }
00130 
00131     ServiceClient<turtlebot_msgs.SetFollowStateRequest, turtlebot_msgs.SetFollowStateResponse> serviceClient;
00132     try
00133     {
00134         NameResolver appNameSpace = getMasterNameSpace();
00135         String srvTopic = appNameSpace.resolve("turtlebot_follower/change_state").toString();
00136       serviceClient = node.newServiceClient(srvTopic, turtlebot_msgs.SetFollowState._TYPE);
00137     }
00138     catch (ServiceNotFoundException e)
00139     {
00140       Log.e("FollowerActivity", "Service not found: " + e.getMessage());
00141       Toast.makeText(getBaseContext(), "Change follower state service not found", Toast.LENGTH_LONG).show();
00142       return;
00143     }
00144     final turtlebot_msgs.SetFollowStateRequest request = serviceClient.newMessage();
00145     request.setState(newState);
00146 
00147     serviceClient.call(request, new ServiceResponseListener<turtlebot_msgs.SetFollowStateResponse>() {
00148       @Override
00149       public void onSuccess(turtlebot_msgs.SetFollowStateResponse response) {
00150         Log.i("FollowerActivity", "Service result " + response.getResult());
00151         if (request.getState() == turtlebot_msgs.SetFollowStateRequest.STOPPED)
00152           showToast("Follower stopped");
00153         else
00154           showToast("Follower started");
00155       }
00156 
00157       @Override
00158       public void onFailure(RemoteException e) {
00159         Log.e("FollowerActivity", "Service result: failure (" + e.getMessage() + ")");
00160         showToast("Change follower state failed");
00161       }
00162     });
00163   }
00164 
00169   private void showToast(final String message)
00170   {
00171     runOnUiThread(new Runnable()
00172     {
00173       @Override
00174       public void run() {
00175         if (lastToast != null)
00176           lastToast.cancel();
00177 
00178         lastToast = Toast.makeText(getBaseContext(), message, Toast.LENGTH_LONG);
00179         lastToast.show();
00180       }
00181     });
00182   }
00183 
00184   private final OnClickListener backButtonListener = new OnClickListener()
00185   {
00186     @Override
00187     public void onClick(View v)
00188     {
00189       onBackPressed();
00190     }
00191   };
00192 
00193   private final OnClickListener startButtonListener = new OnClickListener()
00194   {
00195     @Override
00196     public void onClick(View v)
00197     {
00198       callService(turtlebot_msgs.SetFollowStateRequest.FOLLOW);
00199     }
00200   };
00201 
00202   private final OnClickListener stopButtonListener = new OnClickListener()
00203   {
00204     @Override
00205     public void onClick(View v)
00206     {
00207       callService(turtlebot_msgs.SetFollowStateRequest.STOPPED);
00208     }
00209   };
00210 }


turtlebot_android
Author(s):
autogenerated on Wed Aug 26 2015 16:32:04