135 lines
4.3 KiB
Java
135 lines
4.3 KiB
Java
package com.example.carcontroller.SLAM;
|
|
|
|
import android.content.Context;
|
|
import android.content.SharedPreferences;
|
|
import android.graphics.Bitmap;
|
|
import android.graphics.Canvas;
|
|
import android.graphics.Color;
|
|
import android.graphics.Paint;
|
|
import android.util.AttributeSet;
|
|
import android.view.SurfaceHolder;
|
|
import android.view.SurfaceView;
|
|
|
|
import androidx.preference.PreferenceManager;
|
|
|
|
import com.example.carcontroller.Empty;
|
|
import com.example.carcontroller.SlamControlGrpc;
|
|
import com.example.carcontroller.SlamDetails;
|
|
import com.example.carcontroller.SlamLocation;
|
|
import com.google.protobuf.ByteString;
|
|
|
|
import io.grpc.ManagedChannel;
|
|
import io.grpc.ManagedChannelBuilder;
|
|
import io.grpc.stub.StreamObserver;
|
|
|
|
public class SlamView extends SurfaceView implements SlamUpdater.MapChangedListener {
|
|
|
|
private SlamUpdater slam;
|
|
private Thread mapThread;
|
|
private Context context;
|
|
private int width;
|
|
private SurfaceHolder surfaceHolder;
|
|
private Paint paint;
|
|
private SlamControlGrpc.SlamControlStub stub;
|
|
private ManagedChannel channel;
|
|
private int mapSizePixels;
|
|
private int mapSizeMeters;
|
|
|
|
public SlamView(Context context) {
|
|
super(context);
|
|
this.context = context;
|
|
init();
|
|
}
|
|
|
|
public SlamView(Context context, AttributeSet attrs) {
|
|
super(context, attrs);
|
|
this.context = context;
|
|
init();
|
|
}
|
|
|
|
public SlamView(Context context, AttributeSet attrs, int defStyleAttr) {
|
|
super(context, attrs, defStyleAttr);
|
|
this.context = context;
|
|
init();
|
|
}
|
|
|
|
private void init() {
|
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
|
String host = prefs.getString("host", "10.0.0.53");
|
|
String port = prefs.getString("zmqPort", "5050");
|
|
String gRPCPort = prefs.getString("port", "50051");
|
|
mapSizePixels = Integer.parseInt(prefs.getString("MAPSIZEPIXELS", "540"));
|
|
mapSizeMeters = Integer.parseInt(prefs.getString("MAPSIZEMETRES", "10"));
|
|
slam = new ZmqSlamUpdater(host, port);
|
|
slam.addMapChangedListener(this);
|
|
surfaceHolder = getHolder();
|
|
paint = new Paint();
|
|
paint.setColor(Color.BLUE);
|
|
mapThread = new Thread(slam);
|
|
channel = ManagedChannelBuilder.forAddress(host, Integer.parseInt(gRPCPort)).usePlaintext().build();
|
|
stub = SlamControlGrpc.newStub(channel);
|
|
|
|
}
|
|
|
|
/**
|
|
* Called by MainActivity.onResume() to start a thread.
|
|
*/
|
|
public void resume() {
|
|
StreamObserver<Empty> response = new StreamObserver<Empty>() {
|
|
@Override
|
|
public void onNext(Empty value) {
|
|
mapThread.start();
|
|
}
|
|
|
|
@Override
|
|
public void onError(Throwable t) {
|
|
// TODO: close the activity,
|
|
System.out.println(t.getMessage());
|
|
}
|
|
|
|
@Override
|
|
public void onCompleted() {
|
|
// Don't care.
|
|
}
|
|
};
|
|
// use async grpc method, ZMQ doesn't need to connect straight away.
|
|
stub.startMapStreaming(SlamDetails.newBuilder().setMapSizePixels(mapSizePixels).setMapSizeMeters(mapSizeMeters).build(), response);
|
|
}
|
|
|
|
public void stop() {
|
|
// Use grpc to tell the loader to stop. Interrupt the loader thread as well.
|
|
slam.stop();
|
|
try {
|
|
mapThread.join();
|
|
} catch (InterruptedException e) {
|
|
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void mapChanged(ByteString map, SlamLocation location) {
|
|
if (surfaceHolder.getSurface().isValid()) {
|
|
Canvas canvas = surfaceHolder.lockCanvas();
|
|
canvas.save();
|
|
canvas.drawColor(Color.WHITE);
|
|
// Using width as we want square.
|
|
Bitmap bitmap = Bitmap.createBitmap(width, width, Bitmap.Config.ALPHA_8);
|
|
for (int i = 0; i < width; i++) {
|
|
for (int j = 0; j < width; j++) {
|
|
// 0-255 is appropriate for the config used.
|
|
bitmap.setPixel(i, j, map.byteAt(i * width + j));
|
|
}
|
|
}
|
|
canvas.drawBitmap(bitmap, 0, 0, paint);
|
|
canvas.restore();
|
|
surfaceHolder.unlockCanvasAndPost(canvas);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void onSizeChanged(int w, int b, int oldW, int oldB) {
|
|
super.onSizeChanged(w, b, oldW, oldB);
|
|
width = w;
|
|
}
|
|
}
|