Skip to content

Commit

Permalink
Merge pull request #714 from idsc-frazzoli/dh347
Browse files Browse the repository at this point in the history
dh347
  • Loading branch information
datahaki authored Mar 31, 2019
2 parents 6c25535 + b68e5b3 commit 411917b
Show file tree
Hide file tree
Showing 40 changed files with 520 additions and 153 deletions.
19 changes: 11 additions & 8 deletions src/main/java/ch/ethz/idsc/demo/jph/OfflineHud.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,21 @@ public class OfflineHud implements OfflineLogListener {
private final GokartPoseInterface gokartPoseInterface = new GokartPoseInterface() {
@Override
public Tensor getPose() {
return gpe.getPose();
return gokartPoseEvent.getPose();
}
};
final RenderInterface renderInterface = new ImageRender( //
PREDEFINED_MAP.getImage(), Tensors.vector(1, 1));
final GokartRender gokartRender = new GokartRender(gokartPoseInterface);
final GokartRender gokartRender = new GokartRender();
final DavisLcmClient davisLcmClient = new DavisLcmClient(GokartLcmChannel.DAVIS_OVERVIEW);
final AccumulatedEventRender accumulatedEventRender = new AccumulatedEventRender(gokartPoseInterface);
final TrigonometryRender trigonometryRender = new TrigonometryRender(gokartPoseInterface);
final ExtrudedFootprintRender extrudedFootprintRender = new ExtrudedFootprintRender(gokartPoseInterface);
final TrigonometryRender trigonometryRender = new TrigonometryRender();
final ExtrudedFootprintRender extrudedFootprintRender = new ExtrudedFootprintRender();
// ---
private Scalar time_next = Quantity.of(0, SI.SECOND);
private RimoGetEvent rimoGetEvent;
private GokartStatusEvent gokartStatusEvent;
private GokartPoseEvent gpe;
private GokartPoseEvent gokartPoseEvent;

public OfflineHud(Scalar period) {
this.delta = period;
Expand All @@ -87,7 +87,7 @@ public void event(Scalar time, String channel, ByteBuffer byteBuffer) {
gokartStatusEvent = new GokartStatusEvent(byteBuffer);
} else //
if (channel.equals(GokartLcmChannel.POSE_LIDAR)) {
gpe = GokartPoseEvent.of(byteBuffer);
gokartPoseEvent = GokartPoseEvent.of(byteBuffer);
} else //
if (channel.equals("davis240c.overview.dvs")) {
davisLcmClient.messageReceived(byteBuffer);
Expand Down Expand Up @@ -120,13 +120,16 @@ public void event(Scalar time, String channel, ByteBuffer byteBuffer) {
renderInterface.render(geometricLayer, graphics);
geometricLayer.popMatrix();
}
trigonometryRender.getEvent(gokartStatusEvent);
trigonometryRender.gokartPoseListener.getEvent(gokartPoseEvent);
trigonometryRender.gokartStatusListener.getEvent(gokartStatusEvent);
trigonometryRender.render(geometricLayer, graphics);
extrudedFootprintRender.getEvent(gokartStatusEvent);
extrudedFootprintRender.gokartPoseListener.getEvent(gokartPoseEvent);
extrudedFootprintRender.gokartStatusListener.getEvent(gokartStatusEvent);
extrudedFootprintRender.color = Color.CYAN;
extrudedFootprintRender.render(geometricLayer, graphics);
gokartRender.rimoGetListener.getEvent(rimoGetEvent);
gokartRender.gokartStatusListener.getEvent(gokartStatusEvent);
gokartRender.gokartPoseListener.getEvent(gokartPoseEvent);
gokartRender.render(geometricLayer, graphics);
accumulatedEventRender.render(geometricLayer, graphics);
// ---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import ch.ethz.idsc.gokart.core.pos.GokartPoseEvent;
import ch.ethz.idsc.gokart.core.pos.GokartPoseHelper;
import ch.ethz.idsc.gokart.core.pos.GokartPoseListener;
import ch.ethz.idsc.gokart.core.slam.LidarLocalizationCore;
import ch.ethz.idsc.gokart.gui.GokartLcmChannel;
import ch.ethz.idsc.gokart.lcm.OfflineLogPlayer;
Expand All @@ -30,13 +32,15 @@
import ch.ethz.idsc.tensor.io.Export;
import ch.ethz.idsc.tensor.io.TableBuilder;

// TODO JPH build table outside
/* package */ class LidarLocalizationTable implements OfflineTableSupplier, LidarRayBlockListener {
private static final String CHANNEL_LIDAR = //
VelodyneLcmChannels.ray(VelodyneModel.VLP16, GokartLcmChannel.VLP16_CENTER);
// ---
private final LidarLocalizationCore lidarLocalizationCore = new LidarLocalizationCore();
final LidarLocalizationCore lidarLocalizationCore = new LidarLocalizationCore();
private final TableBuilder tableBuilder = new TableBuilder();
private final TableBuilder tableBuilderOdometry = new TableBuilder();
final List<GokartPoseListener> listeners = new LinkedList<>();

public LidarLocalizationTable() {
lidarLocalizationCore.lidarAngularFiringCollector.addListener(this);
Expand All @@ -61,6 +65,7 @@ public void event(Scalar time, String channel, ByteBuffer byteBuffer) {
if (channel.equals(GokartPoseChannel.INSTANCE.channel())) {
GokartPoseEvent gokartPoseEvent = GokartPoseEvent.of(byteBuffer);
GokartPoseEvent gokartPoseUpdat = lidarLocalizationCore.createPoseEvent();
listeners.forEach(listener -> listener.getEvent(gokartPoseUpdat));
tableBuilder.appendRow( //
Magnitude.SECOND.apply(time), //
gokartPoseEvent.asVector(), //
Expand Down Expand Up @@ -92,6 +97,12 @@ public static void main(String[] args) throws IOException {
System.out.println(folder.getName());
GokartLogInterface gokartLogInterface = GokartLogAdapter.of(folder, "log.lcm");
LidarLocalizationTable lidarLocalizationTable = new LidarLocalizationTable();
lidarLocalizationTable.listeners.add(new GokartPoseListener() {
@Override
public void getEvent(GokartPoseEvent gokartPoseEvent) {
System.out.println(gokartPoseEvent.getQuality());
}
});
lidarLocalizationTable.lidarLocalizationCore.resetPose(gokartLogInterface.pose());
OfflineLogPlayer.process(gokartLogInterface.file(), lidarLocalizationTable);
Export.of(new File(dest, folder.getName() + ".csv.gz"), lidarLocalizationTable.getTable().map(CsvFormat.strict()));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// code by jph
package ch.ethz.idsc.demo.jph.lidar.local;

import java.io.File;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import ch.ethz.idsc.gokart.core.pos.GokartPoseEvent;
import ch.ethz.idsc.gokart.core.pos.GokartPoseListener;
import ch.ethz.idsc.gokart.core.pos.LocalizationConfig;
import ch.ethz.idsc.gokart.offline.api.GokartLogAdapter;
import ch.ethz.idsc.gokart.offline.api.GokartLogInterface;
import ch.ethz.idsc.gokart.offline.pose.LogPosePostInject;
import ch.ethz.idsc.tensor.Scalar;

public class LogPosePostProvider {
public static void main(String[] args) throws Exception {
File root = new File("/media/datahaki/data/gokart/cuts/20190311");
File dest = new File("/media/datahaki/data/gokart/localization/20190311");
dest.mkdir();
List<File> list = Stream.of(root.listFiles()) //
.filter(File::isDirectory) //
.sorted() //
.skip(1) //
.limit(1) //
.collect(Collectors.toList());
for (File folder : list) {
System.out.println(folder.getName());
GokartLogInterface gokartLogInterface = GokartLogAdapter.of(folder, "log.lcm");
LidarLocalizationTable lidarLocalizationTable = new LidarLocalizationTable();
lidarLocalizationTable.listeners.add(new GokartPoseListener() {
@Override
public void getEvent(GokartPoseEvent gokartPoseEvent) {
Scalar quality = gokartPoseEvent.getQuality();
if (!LocalizationConfig.GLOBAL.isQualityOk(quality))
System.err.println("quality! " + quality);
}
});
lidarLocalizationTable.lidarLocalizationCore.resetPose(gokartLogInterface.pose());
// ---
LogPosePostInject logPosePostInject = new LogPosePostInject();
lidarLocalizationTable.listeners.add(logPosePostInject);
logPosePostInject.process(gokartLogInterface.file(), new File(folder, "post.lcm"), lidarLocalizationTable);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ public static void in(File folder) throws Exception {
} else {
OfflineLocalizeWrap lidarGyroPoseEstimator = of(gokartLogInterface.pose());
LogPosePostInject logPosePostInject = new LogPosePostInject();
lidarGyroPoseEstimator.offlineLocalize.addListener(logPosePostInject);
// FIXME JPH
// lidarGyroPoseEstimator.offlineLocalize.addListener(logPosePostInject);
logPosePostInject.process(gokartLogInterface.file(), post_lcm, lidarGyroPoseEstimator);
}
if (post_lcm.isFile()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ public static void main(String[] args) throws IOException {
LogPlayerConfig logPlayerConfig = new LogPlayerConfig();
File file;
// file = DatahakiLogFileLocator.file(GokartLogFile._20190311T173809_da0bb9b9);
file = new File("/media/datahaki/data/gokart/cuts/20190311/20190311T173809_02/log.lcm");
file = new File("/media/datahaki/data/gokart/cuts/20190311/20190311T173809_02/post.lcm");
// file = new File("/media/datahaki/media/ethz/gokart/topic/trackid", "changingtrack.lcm");
// file = new File("/media/datahaki/data/gokart/cuts/20190318/20190318T142605_08/post.lcm");
logPlayerConfig.logFile = file.toString();
logPlayerConfig.speed_numerator = 1;
logPlayerConfig.speed_denominator = 8;
logPlayerConfig.speed_denominator = 1;
LogPlayer logPlayer = LogPlayer.create(logPlayerConfig);
WindowConfiguration windowConfiguration = //
AppCustomization.load(GokartLcmLogPlayer.class, new WindowConfiguration());
Expand Down
46 changes: 46 additions & 0 deletions src/main/java/ch/ethz/idsc/demo/jph/video/DriftLinesRender.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// code by jph
package ch.ethz.idsc.demo.jph.video;

import java.awt.Color;
import java.awt.Graphics2D;

import ch.ethz.idsc.gokart.core.pos.GokartPoseEvent;
import ch.ethz.idsc.gokart.core.pos.GokartPoseHelper;
import ch.ethz.idsc.gokart.core.pos.GokartPoseListener;
import ch.ethz.idsc.owl.data.BoundedLinkedList;
import ch.ethz.idsc.owl.gui.RenderInterface;
import ch.ethz.idsc.owl.gui.win.GeometricLayer;
import ch.ethz.idsc.tensor.Tensor;
import ch.ethz.idsc.tensor.Tensors;

public class DriftLinesRender implements GokartPoseListener, RenderInterface {
private static final Color COLOR = new Color(128, 128, 128, 64);
private static final Tensor PATH = Tensors.of( //
Tensors.vector(0.0, 0), //
Tensors.vector(0.4, 0));
// ---
private final BoundedLinkedList<Tensor> boundedLinkedList;

public DriftLinesRender(int limit) {
boundedLinkedList = new BoundedLinkedList<>(limit);
}

@Override // from GokartPoseListener
public void getEvent(GokartPoseEvent gokartPoseEvent) {
synchronized (boundedLinkedList) {
boundedLinkedList.add(GokartPoseHelper.toSE2Matrix(gokartPoseEvent.getPose()));
}
}

@Override // from RenderInterface
public void render(GeometricLayer geometricLayer, Graphics2D graphics) {
synchronized (boundedLinkedList) {
graphics.setColor(COLOR);
for (Tensor matrix : boundedLinkedList) {
geometricLayer.pushMatrix(matrix);
graphics.draw(geometricLayer.toPath2D(PATH));
geometricLayer.popMatrix();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package ch.ethz.idsc.demo.jph.video;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
Expand All @@ -26,7 +27,6 @@
;
public static void main(String[] args) throws Exception {
/** Read in some option values and their defaults. */
final int snaps = 50; // fps
final String string = "multidriver";
final String filename = HomeDirectory.file(string + ".mp4").toString();
// ---
Expand All @@ -40,14 +40,15 @@ public static void main(String[] args) throws Exception {
list.add(trackDriving);
}
BufferedImage background = ImageIO.read(VideoBackground.IMAGE_FILE);
Dimension dimension = new Dimension(background.getWidth(), background.getHeight());
final int max = list.stream().mapToInt(TrackDriving::maxIndex).max().getAsInt();
BufferedImage bufferedImage = new BufferedImage( //
VideoBackground.DIMENSION.width, //
VideoBackground.DIMENSION.height, //
BufferedImage.TYPE_3BYTE_BGR);
Graphics2D graphics = bufferedImage.createGraphics();
GraphicsUtil.setQualityHigh(graphics);
try (Mp4AnimationWriter mp4AnimationWriter = new Mp4AnimationWriter(filename, VideoBackground.DIMENSION, snaps)) {
try (Mp4AnimationWriter mp4AnimationWriter = new Mp4AnimationWriter(filename, dimension, StaticHelper.FRAMERATE)) {
for (int index = 0; index < max; ++index) {
System.out.println(index);
Scalar time = list.get(0).timeFor(index);
Expand Down
126 changes: 126 additions & 0 deletions src/main/java/ch/ethz/idsc/demo/jph/video/OfflineRender.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// code by jph
package ch.ethz.idsc.demo.jph.video;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.nio.ByteBuffer;
import java.util.Objects;

import ch.ethz.idsc.gokart.core.mpc.ControlAndPredictionSteps;
import ch.ethz.idsc.gokart.core.mpc.ControlAndPredictionStepsMessage;
import ch.ethz.idsc.gokart.core.pos.GokartPoseEvent;
import ch.ethz.idsc.gokart.dev.linmot.LinmotGetEvent;
import ch.ethz.idsc.gokart.dev.rimo.RimoGetEvent;
import ch.ethz.idsc.gokart.dev.rimo.RimoPutEvent;
import ch.ethz.idsc.gokart.dev.rimo.RimoPutHelper;
import ch.ethz.idsc.gokart.gui.GokartLcmChannel;
import ch.ethz.idsc.gokart.gui.GokartStatusEvent;
import ch.ethz.idsc.gokart.gui.top.AccelerationRender;
import ch.ethz.idsc.gokart.gui.top.ExtrudedFootprintRender;
import ch.ethz.idsc.gokart.gui.top.GokartRender;
import ch.ethz.idsc.gokart.gui.top.GroundSpeedRender;
import ch.ethz.idsc.gokart.gui.top.MPCPredictionRender;
import ch.ethz.idsc.gokart.gui.top.MPCPredictionSequenceRender;
import ch.ethz.idsc.gokart.gui.top.TachometerMustangDash;
import ch.ethz.idsc.gokart.lcm.OfflineLogListener;
import ch.ethz.idsc.gokart.lcm.autobox.LinmotLcmServer;
import ch.ethz.idsc.gokart.lcm.autobox.RimoLcmServer;
import ch.ethz.idsc.gokart.offline.channel.Vmu931ImuChannel;
import ch.ethz.idsc.owl.gui.RenderInterface;
import ch.ethz.idsc.owl.gui.win.GeometricLayer;
import ch.ethz.idsc.retina.imu.vmu931.Vmu931ImuFrame;
import ch.ethz.idsc.sophus.group.Se2Utils;
import ch.ethz.idsc.tensor.Scalar;
import ch.ethz.idsc.tensor.Tensor;
import ch.ethz.idsc.tensor.Tensors;
import ch.ethz.idsc.tensor.mat.DiagonalMatrix;
import ch.ethz.idsc.tensor.mat.Inverse;
import ch.ethz.idsc.tensor.sca.Round;

public class OfflineRender implements OfflineLogListener, RenderInterface {
private final MPCPredictionSequenceRender mpcPredictionSequenceRender = new MPCPredictionSequenceRender(20);
private final MPCPredictionRender mpcPredictionRender = new MPCPredictionRender();
private final DriftLinesRender driftLinesRender = new DriftLinesRender(100);
private final GokartRender gokartRender = new GokartRender();
private final AccelerationRender accelerationRender;
private final GroundSpeedRender groundSpeedRender;
private final TachometerMustangDash tachometerMustangDash;
private final ExtrudedFootprintRender extrudedFootprintRender = new ExtrudedFootprintRender();
private final String poseChannel;
// ---
private LinmotGetEvent linmotGetEvent;

public OfflineRender(Tensor model2pixel, String poseChannel) {
this.poseChannel = poseChannel;
accelerationRender = new AccelerationRender(50, //
Inverse.of(model2pixel) //
.dot(Se2Utils.toSE2Matrix(Tensors.vector(960 + 250, 140, 0))) //
.dot(Se2Utils.toSE2Matrix(Tensors.vector(0, 0, -Math.PI / 2))) //
.dot(DiagonalMatrix.of(8, -8, 1)));
Tensor matrix = Inverse.of(model2pixel) //
.dot(Se2Utils.toSE2Matrix(Tensors.vector(960 - 250, 140, 0))) //
.dot(Se2Utils.toSE2Matrix(Tensors.vector(0, 0, -Math.PI / 2))) //
.dot(DiagonalMatrix.of(10, -10, 1));
groundSpeedRender = new GroundSpeedRender(50, matrix);
tachometerMustangDash = new TachometerMustangDash(matrix); //
}

@Override // from OfflineLogListener
public void event(Scalar time, String channel, ByteBuffer byteBuffer) {
if (channel.equals(GokartLcmChannel.STATUS)) {
GokartStatusEvent gokartStatusEvent = new GokartStatusEvent(byteBuffer);
gokartRender.gokartStatusListener.getEvent(gokartStatusEvent);
extrudedFootprintRender.gokartStatusListener.getEvent(gokartStatusEvent);
} else //
if (channel.equals(LinmotLcmServer.CHANNEL_GET)) {
linmotGetEvent = new LinmotGetEvent(byteBuffer);
gokartRender.linmotGetListener.getEvent(linmotGetEvent);
} else //
if (channel.equals(RimoLcmServer.CHANNEL_GET)) {
RimoGetEvent rimoGetEvent = new RimoGetEvent(byteBuffer);
gokartRender.rimoGetListener.getEvent(rimoGetEvent);
tachometerMustangDash.getEvent(rimoGetEvent);
} else //
if (channel.equals(RimoLcmServer.CHANNEL_PUT)) {
RimoPutEvent rimoGetEvent = RimoPutHelper.from(byteBuffer);
gokartRender.rimoPutListener.putEvent(rimoGetEvent);
} else //
if (channel.equals(Vmu931ImuChannel.INSTANCE.channel())) {
Vmu931ImuFrame vmu931ImuFrame = new Vmu931ImuFrame(byteBuffer);
accelerationRender.vmu931ImuFrame(vmu931ImuFrame);
} else //
if (channel.equals(GokartLcmChannel.MPC_FORCES_CNS)) {
ControlAndPredictionSteps controlAndPredictionSteps = new ControlAndPredictionStepsMessage(byteBuffer).getPayload();
mpcPredictionSequenceRender.getControlAndPredictionSteps(controlAndPredictionSteps);
mpcPredictionRender.getControlAndPredictionSteps(controlAndPredictionSteps);
} else //
if (channel.equals(poseChannel)) {
GokartPoseEvent gokartPoseEvent = GokartPoseEvent.of(byteBuffer);
driftLinesRender.getEvent(gokartPoseEvent);
groundSpeedRender.getEvent(gokartPoseEvent);
gokartRender.gokartPoseListener.getEvent(gokartPoseEvent);
extrudedFootprintRender.gokartPoseListener.getEvent(gokartPoseEvent);
}
}

@Override // from RenderInterface
public void render(GeometricLayer geometricLayer, Graphics2D graphics) {
mpcPredictionSequenceRender.render(geometricLayer, graphics);
mpcPredictionRender.render(geometricLayer, graphics);
driftLinesRender.render(geometricLayer, graphics);
gokartRender.render(geometricLayer, graphics);
extrudedFootprintRender.render(geometricLayer, graphics);
accelerationRender.render(geometricLayer, graphics);
groundSpeedRender.render(geometricLayer, graphics);
tachometerMustangDash.render(geometricLayer, graphics);
// ---
graphics.setFont(new Font(Font.MONOSPACED, Font.BOLD, 30));
graphics.setColor(Color.GRAY);
if (Objects.nonNull(linmotGetEvent))
graphics.drawString(String.format("brake:%12s", linmotGetEvent.getWindingTemperatureMax().map(Round._2)), 0, 25 + 30);
// ---
graphics.drawString("vel", 960 - 250 - 140, 25);
graphics.drawString("acc", 960 + 250 - 140, 25);
}
}
7 changes: 7 additions & 0 deletions src/main/java/ch/ethz/idsc/demo/jph/video/StaticHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// code by jph
package ch.ethz.idsc.demo.jph.video;

/* package */ enum StaticHelper {
;
public static final int FRAMERATE = 50;
}
Loading

0 comments on commit 411917b

Please sign in to comment.