Make SLAM view easier to implement in multiple protocols.
This commit is contained in:
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user