Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 package com.github.rosjava.android_apps.make_a_map;
00018
00019 import java.util.concurrent.TimeUnit;
00020
00021 import android.app.AlertDialog;
00022 import android.app.Dialog;
00023 import android.app.ProgressDialog;
00024 import android.content.DialogInterface;
00025 import android.os.Bundle;
00026 import android.view.KeyEvent;
00027 import android.view.Menu;
00028 import android.view.MenuItem;
00029 import android.view.View;
00030 import android.view.ViewGroup;
00031 import android.widget.Button;
00032 import android.widget.EditText;
00033 import android.widget.ImageButton;
00034 import android.widget.Toast;
00035
00036 import map_store.SaveMapResponse;
00037
00038 import com.github.rosjava.android_apps.application_management.RosAppActivity;
00039 import org.ros.android.view.RosImageView;
00040 import org.ros.namespace.NameResolver;
00041 import org.ros.node.NodeConfiguration;
00042 import org.ros.node.NodeMainExecutor;
00043 import org.ros.node.service.ServiceResponseListener;
00044 import org.ros.address.InetAddressFactory;
00045 import org.ros.android.BitmapFromCompressedImage;
00046 import org.ros.android.view.VirtualJoystickView;
00047 import org.ros.android.view.visualization.VisualizationView;
00048 import org.ros.android.view.visualization.layer.CameraControlListener;
00049 import org.ros.android.view.visualization.layer.OccupancyGridLayer;
00050 import org.ros.android.view.visualization.layer.LaserScanLayer;
00051 import org.ros.android.view.visualization.layer.RobotLayer;
00052 import org.ros.exception.RemoteException;
00053 import org.ros.time.NtpTimeProvider;
00054
00058 public class MainActivity extends RosAppActivity {
00059
00060 private static final String MAP_FRAME = "map";
00061 private static final String ROBOT_FRAME = "base_link";
00062 private static final String virtualJoystickTopic = "android/virtual_joystick/cmd_vel";
00063 private static final String cameraTopic = "camera/rgb/image_color/compressed_throttle";
00064 private static final String mapTopic = "map";
00065 private static final String scanTopic = "scan";
00066 private static final int NAME_MAP_DIALOG_ID = 0;
00067
00068 private RosImageView<sensor_msgs.CompressedImage> cameraView;
00069 private VirtualJoystickView virtualJoystickView;
00070 private VisualizationView mapView;
00071 private ViewGroup mainLayout;
00072 private ViewGroup sideLayout;
00073 private ImageButton refreshButton;
00074 private ImageButton saveButton;
00075 private Button backButton;
00076 private NodeMainExecutor nodeMainExecutor;
00077 private NodeConfiguration nodeConfiguration;
00078 private ProgressDialog waitingDialog;
00079 private AlertDialog errorDialog;
00080
00081 public MainActivity() {
00082
00083
00084
00085 super("Make a map", "Make a map");
00086
00087 }
00088
00089 @SuppressWarnings("unchecked")
00090 @Override
00091 public void onCreate(Bundle savedInstanceState) {
00092
00093 String defaultRobotName = getString(R.string.default_robot);
00094 String defaultAppName = getString(R.string.default_app);
00095 setDefaultRobotName(defaultRobotName);
00096 setDefaultAppName(defaultAppName);
00097 setDashboardResource(R.id.top_bar);
00098 setMainWindowResource(R.layout.main);
00099
00100 super.onCreate(savedInstanceState);
00101
00102 cameraView = (RosImageView<sensor_msgs.CompressedImage>) findViewById(R.id.image);
00103 cameraView.setMessageType(sensor_msgs.CompressedImage._TYPE);
00104 cameraView.setMessageToBitmapCallable(new BitmapFromCompressedImage());
00105 mapView = (VisualizationView) findViewById(R.id.map_view);
00106 virtualJoystickView = (VirtualJoystickView) findViewById(R.id.virtual_joystick);
00107 refreshButton = (ImageButton) findViewById(R.id.refresh_button);
00108 saveButton = (ImageButton) findViewById(R.id.save_map);
00109 backButton = (Button) findViewById(R.id.back_button);
00110
00111 refreshButton.setOnClickListener(new View.OnClickListener() {
00112 @Override
00113 public void onClick(View view) {
00114
00115 Toast.makeText(MainActivity.this, "refreshing map...",
00116 Toast.LENGTH_SHORT).show();
00117 mapView.getCamera().jumpToFrame(ROBOT_FRAME);
00118 }
00119 });
00120
00121 saveButton.setOnClickListener(new View.OnClickListener() {
00122 @Override
00123 public void onClick(View view) {
00124 showDialog(NAME_MAP_DIALOG_ID);
00125
00126 }
00127
00128 });
00129
00130 backButton.setOnClickListener(new View.OnClickListener() {
00131 @Override
00132 public void onClick(View view) {
00133 onBackPressed();
00134 }
00135 });
00136
00137 mapView.getCamera().jumpToFrame(ROBOT_FRAME);
00138
00139 mainLayout = (ViewGroup) findViewById(R.id.main_layout);
00140 sideLayout = (ViewGroup) findViewById(R.id.side_layout);
00141
00142 }
00143
00144 @Override
00145 protected Dialog onCreateDialog(int id) {
00146 Dialog dialog;
00147 Button button;
00148
00149 switch (id) {
00150 case NAME_MAP_DIALOG_ID:
00151 dialog = new Dialog(this);
00152 dialog.setContentView(R.layout.name_map_dialog);
00153 dialog.setTitle("Save Map");
00154 final EditText nameField = (EditText) dialog
00155 .findViewById(R.id.name_editor);
00156
00157 nameField.setOnKeyListener(new View.OnKeyListener() {
00158 @Override
00159 public boolean onKey(final View view, int keyCode,
00160 KeyEvent event) {
00161 if (event.getAction() == KeyEvent.ACTION_DOWN
00162 && keyCode == KeyEvent.KEYCODE_ENTER) {
00163 safeShowWaitingDialog("Saving map...");
00164 try {
00165 MapManager mapManager = new MapManager();
00166 String name = nameField.getText().toString();
00167 if (name != null) {
00168 mapManager.setMapName(name);
00169 }
00170 mapManager.setNameResolver(getAppNameSpace());
00171 mapManager.setSaveService(new ServiceResponseListener<SaveMapResponse>()
00172 {
00173 @Override
00174 public void onFailure(RemoteException e)
00175 {
00176 e.printStackTrace();
00177 }
00178
00179 @Override
00180 public void onSuccess(SaveMapResponse arg0)
00181 {
00182 safeDismissWaitingDialog();
00183 }
00184 });
00185
00186 nodeMainExecutor.execute(mapManager,
00187 nodeConfiguration
00188 .setNodeName("android/save_map"));
00189
00190 } catch (Exception e) {
00191 e.printStackTrace();
00192 safeShowErrorDialog("Error during saving: "
00193 + e.toString());
00194 }
00195
00196 removeDialog(NAME_MAP_DIALOG_ID);
00197 return true;
00198 } else {
00199 return false;
00200 }
00201 }
00202 });
00203
00204 button = (Button) dialog.findViewById(R.id.cancel_button);
00205 button.setOnClickListener(new View.OnClickListener() {
00206 @Override
00207 public void onClick(View v) {
00208 removeDialog(NAME_MAP_DIALOG_ID);
00209 }
00210 });
00211 break;
00212 default:
00213 dialog = null;
00214 }
00215 return dialog;
00216 }
00217
00218 private void safeDismissWaitingDialog() {
00219 runOnUiThread(new Runnable() {
00220 @Override
00221 public void run() {
00222 if (waitingDialog != null) {
00223 waitingDialog.dismiss();
00224 waitingDialog = null;
00225 }
00226 }
00227 });
00228 }
00229
00230 private void safeShowWaitingDialog(final CharSequence message) {
00231 runOnUiThread(new Runnable() {
00232 @Override
00233 public void run() {
00234 if (waitingDialog != null) {
00235 waitingDialog.dismiss();
00236 waitingDialog = null;
00237 }
00238 waitingDialog = ProgressDialog.show(MainActivity.this, "",
00239 message, true);
00240 }
00241 });
00242 }
00243
00244 private void safeShowErrorDialog(final CharSequence message) {
00245 runOnUiThread(new Runnable() {
00246 @Override
00247 public void run() {
00248 if (errorDialog != null) {
00249 errorDialog.dismiss();
00250 errorDialog = null;
00251 }
00252 if (waitingDialog != null) {
00253 waitingDialog.dismiss();
00254 waitingDialog = null;
00255 }
00256 AlertDialog.Builder dialog = new AlertDialog.Builder(
00257 MainActivity.this);
00258 dialog.setTitle("Error");
00259 dialog.setMessage(message);
00260 dialog.setNeutralButton("Ok",
00261 new DialogInterface.OnClickListener() {
00262 @Override
00263 public void onClick(DialogInterface dlog, int i) {
00264 dlog.dismiss();
00265 }
00266 });
00267 errorDialog = dialog.show();
00268 }
00269 });
00270 }
00271
00272 @Override
00273 protected void init(NodeMainExecutor nodeMainExecutor) {
00274
00275 super.init(nodeMainExecutor);
00276 this.nodeMainExecutor = nodeMainExecutor;
00277
00278 nodeConfiguration = NodeConfiguration.newPublic(InetAddressFactory
00279 .newNonLoopback().getHostAddress(), getMasterUri());
00280
00281 NameResolver appNameSpace = getAppNameSpace();
00282 cameraView.setTopicName(appNameSpace.resolve(cameraTopic).toString());
00283 virtualJoystickView.setTopicName(appNameSpace.resolve(virtualJoystickTopic).toString());
00284
00285 nodeMainExecutor.execute(cameraView,
00286 nodeConfiguration.setNodeName("android/camera_view"));
00287 nodeMainExecutor.execute(virtualJoystickView,
00288 nodeConfiguration.setNodeName("android/virtual_joystick"));
00289
00290 ViewControlLayer viewControlLayer = new ViewControlLayer(this,
00291 nodeMainExecutor.getScheduledExecutorService(), cameraView,
00292 mapView, mainLayout, sideLayout);
00293
00294 viewControlLayer.addListener(new CameraControlListener() {
00295 @Override
00296 public void onZoom(double focusX, double focusY, double factor) {
00297
00298 }
00299
00300 @Override
00301 public void onTranslate(float distanceX, float distanceY) {
00302
00303 }
00304
00305 @Override
00306 public void onRotate(double focusX, double focusY, double deltaAngle) {
00307
00308 }
00309 });
00310
00311 mapView.addLayer(viewControlLayer);
00312 mapView.addLayer(new OccupancyGridLayer(appNameSpace.resolve(mapTopic).toString()));
00313 mapView.addLayer(new LaserScanLayer(appNameSpace.resolve(scanTopic).toString()));
00314 mapView.addLayer(new RobotLayer(ROBOT_FRAME));
00315 NtpTimeProvider ntpTimeProvider = new NtpTimeProvider(
00316 InetAddressFactory.newFromHostString("192.168.0.1"),
00317 nodeMainExecutor.getScheduledExecutorService());
00318 ntpTimeProvider.startPeriodicUpdates(1, TimeUnit.MINUTES);
00319 nodeConfiguration.setTimeProvider(ntpTimeProvider);
00320 nodeMainExecutor.execute(mapView,
00321 nodeConfiguration.setNodeName("android/map_view"));
00322 }
00323
00324 @Override
00325 public boolean onCreateOptionsMenu(Menu menu) {
00326 menu.add(0, 0, 0, R.string.stop_app);
00327 return super.onCreateOptionsMenu(menu);
00328 }
00329
00330 @Override
00331 public boolean onOptionsItemSelected(MenuItem item) {
00332 super.onOptionsItemSelected(item);
00333 switch (item.getItemId()) {
00334 case 0:
00335 onDestroy();
00336 break;
00337 }
00338 return true;
00339 }
00340
00341 }