Make SLAM view easier to implement in multiple protocols.

This commit is contained in:
Piv
2020-02-07 20:36:51 +10:30
parent 7937b6858e
commit 110facb8a3
3 changed files with 129 additions and 32 deletions

View File

@@ -0,0 +1,36 @@
package com.example.carcontroller.SLAM;
import com.example.carcontroller.SlamLocation;
import com.example.carcontroller.SlamScan;
import com.google.protobuf.ByteString;
import java.util.HashSet;
import java.util.Set;
public abstract class SlamUpdater implements Runnable {
private Set<MapChangedListener> listeners;
public SlamUpdater() {
init();
}
protected void init() {
listeners = new HashSet<>();
}
public void addMapChangedListener(MapChangedListener listener) {
listeners.add(listener);
}
protected void fireMapChanged(SlamScan scan) {
listeners.forEach(listener -> listener.mapChanged(scan.getMap(), scan.getLocation()));
}
public abstract void stop();
public interface MapChangedListener {
void mapChanged(ByteString map, SlamLocation location);
}
}

View File

@@ -3,67 +3,69 @@ package com.example.carcontroller.SLAM;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView; import android.view.SurfaceView;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import com.example.carcontroller.SlamScan; import com.example.carcontroller.SlamLocation;
import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.ByteString;
import org.zeromq.SocketType; public class SlamView extends SurfaceView implements SlamUpdater.MapChangedListener {
import org.zeromq.ZContext;
import org.zeromq.ZMQ;
public class SlamView extends SurfaceView implements Runnable { SlamUpdater slam;
ZContext context;
String host;
String port;
Thread mapThread; Thread mapThread;
Context context;
private int width;
private int height;
private SurfaceHolder surfaceHolder;
public SlamView(Context context) { public SlamView(Context context) {
super(context); super(context);
this.context = context;
init(); init();
} }
public SlamView(Context context, AttributeSet attrs) { public SlamView(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
this.context = context;
init(); init();
} }
public SlamView(Context context, AttributeSet attrs, int defStyleAttr) { public SlamView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr); super(context, attrs, defStyleAttr);
this.context = context;
init(); init();
} }
private void init() { private void init() {
context = new ZContext(); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); String host = prefs.getString("host", "10.0.0.53");
host = prefs.getString("host", "10.0.0.53"); String port = prefs.getString("zmqPort", "5050");
port = prefs.getString("zmqPort", "5050"); slam = new ZmqSlamUpdater(host, port);
slam.addMapChangedListener(this);
} }
@Override /**
public void run() { * Called by MainActivity.onResume() to start a thread.
// Receive map from zmq and update appropriately. */
try (ZMQ.Socket socket = context.createSocket(SocketType.PAIR)) { public void resume() {
socket.connect("tcp://" + host + ":" + port); mapThread = new Thread(slam);
socket.send("Hi"); mapThread.start();
while (!Thread.currentThread().isInterrupted()) {
byte[] map = socket.recv();
SlamScan scan = SlamScan.parseFrom(map);
for (Byte b : scan.getMap()) {
}
}
} catch (InvalidProtocolBufferException e) {
System.out.println("Invalid map found");
}
} }
public void stop() { public void stop() {
// Use grpc to tell the loader to stop. Interrupt the loader thread as well. // Use grpc to tell the loader to stop. Interrupt the loader thread as well.
mapThread.interrupt(); slam.stop();
try {
mapThread.join();
} catch (InterruptedException e) {
}
}
@Override
public void mapChanged(ByteString map, SlamLocation location) {
} }
} }

View File

@@ -0,0 +1,59 @@
package com.example.carcontroller.SLAM;
import com.example.carcontroller.SlamScan;
import com.google.protobuf.InvalidProtocolBufferException;
import org.zeromq.SocketType;
import org.zeromq.ZContext;
import org.zeromq.ZMQ;
/**
* Connects to Pi and retrieves updates of the SLAM map,
* notifying listeners of changes to the map when they arrive.
* Uses 0MQ for the transport.
*/
public class ZmqSlamUpdater extends SlamUpdater {
private ZContext context;
private String host;
private String port;
private boolean running = false;
public ZmqSlamUpdater(String host, String port) {
super();
this.host = host;
this.port = port;
init();
}
@Override
protected void init() {
context = new ZContext();
}
@Override
public void run() {
// Should send a gRPC message to start listening...
running = true;
// Receive map from zmq and update appropriately.
try (ZMQ.Socket socket = context.createSocket(SocketType.PAIR)) {
socket.connect("tcp://" + host + ":" + port);
socket.send("Hi");
while (running) {
byte[] map = socket.recv();
fireMapChanged(SlamScan.parseFrom(map));
}
} catch (InvalidProtocolBufferException e) {
System.out.println("Invalid map found");
running = false;
}
}
public void stop() {
running = false;
}
}