diff --git a/simulation/JavaGazebo/build.gradle b/simulation/JavaGazebo/build.gradle
new file mode 100644
index 0000000..4a0456a
--- /dev/null
+++ b/simulation/JavaGazebo/build.gradle
@@ -0,0 +1,18 @@
+apply plugin: 'java'
+apply plugin: 'maven-publish'
+
+publishing {
+    publications {
+        maven(MavenPublication) {
+            artifact jar
+            groupId 'org.gazebosim'
+            artifactId 'JavaGazebo'
+            version '0.1.0-SNAPSHOT'
+        }
+    }
+    setupWpilibRepo(it)
+}
+
+dependencies {
+    compile 'com.google.protobuf:protobuf-java:2.5.0'
+}
\ No newline at end of file
diff --git a/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzBool.java b/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzBool.java
new file mode 100644
index 0000000..dd3abd1
--- /dev/null
+++ b/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzBool.java
@@ -0,0 +1,453 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: frc_gazebo_plugin/msgs/bool.proto
+
+package gazebo.msgs;
+
+public final class GzBool {
+  private GzBool() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface BoolOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required bool data = 1;
+    /**
+     * <code>required bool data = 1;</code>
+     */
+    boolean hasData();
+    /**
+     * <code>required bool data = 1;</code>
+     */
+    boolean getData();
+  }
+  /**
+   * Protobuf type {@code gazebo.msgs.Bool}
+   */
+  public static final class Bool extends
+      com.google.protobuf.GeneratedMessage
+      implements BoolOrBuilder {
+    // Use Bool.newBuilder() to construct.
+    private Bool(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private Bool(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final Bool defaultInstance;
+    public static Bool getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public Bool getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private Bool(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 8: {
+              bitField0_ |= 0x00000001;
+              data_ = input.readBool();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return gazebo.msgs.GzBool.internal_static_gazebo_msgs_Bool_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return gazebo.msgs.GzBool.internal_static_gazebo_msgs_Bool_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              gazebo.msgs.GzBool.Bool.class, gazebo.msgs.GzBool.Bool.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<Bool> PARSER =
+        new com.google.protobuf.AbstractParser<Bool>() {
+      public Bool parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new Bool(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<Bool> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required bool data = 1;
+    public static final int DATA_FIELD_NUMBER = 1;
+    private boolean data_;
+    /**
+     * <code>required bool data = 1;</code>
+     */
+    public boolean hasData() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required bool data = 1;</code>
+     */
+    public boolean getData() {
+      return data_;
+    }
+
+    private void initFields() {
+      data_ = false;
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasData()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBool(1, data_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(1, data_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static gazebo.msgs.GzBool.Bool parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static gazebo.msgs.GzBool.Bool parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static gazebo.msgs.GzBool.Bool parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static gazebo.msgs.GzBool.Bool parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static gazebo.msgs.GzBool.Bool parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static gazebo.msgs.GzBool.Bool parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static gazebo.msgs.GzBool.Bool parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static gazebo.msgs.GzBool.Bool parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static gazebo.msgs.GzBool.Bool parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static gazebo.msgs.GzBool.Bool parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(gazebo.msgs.GzBool.Bool prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code gazebo.msgs.Bool}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements gazebo.msgs.GzBool.BoolOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return gazebo.msgs.GzBool.internal_static_gazebo_msgs_Bool_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return gazebo.msgs.GzBool.internal_static_gazebo_msgs_Bool_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                gazebo.msgs.GzBool.Bool.class, gazebo.msgs.GzBool.Bool.Builder.class);
+      }
+
+      // Construct using gazebo.msgs.GzBool.Bool.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        data_ = false;
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return gazebo.msgs.GzBool.internal_static_gazebo_msgs_Bool_descriptor;
+      }
+
+      public gazebo.msgs.GzBool.Bool getDefaultInstanceForType() {
+        return gazebo.msgs.GzBool.Bool.getDefaultInstance();
+      }
+
+      public gazebo.msgs.GzBool.Bool build() {
+        gazebo.msgs.GzBool.Bool result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public gazebo.msgs.GzBool.Bool buildPartial() {
+        gazebo.msgs.GzBool.Bool result = new gazebo.msgs.GzBool.Bool(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.data_ = data_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof gazebo.msgs.GzBool.Bool) {
+          return mergeFrom((gazebo.msgs.GzBool.Bool)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(gazebo.msgs.GzBool.Bool other) {
+        if (other == gazebo.msgs.GzBool.Bool.getDefaultInstance()) return this;
+        if (other.hasData()) {
+          setData(other.getData());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasData()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        gazebo.msgs.GzBool.Bool parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (gazebo.msgs.GzBool.Bool) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required bool data = 1;
+      private boolean data_ ;
+      /**
+       * <code>required bool data = 1;</code>
+       */
+      public boolean hasData() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required bool data = 1;</code>
+       */
+      public boolean getData() {
+        return data_;
+      }
+      /**
+       * <code>required bool data = 1;</code>
+       */
+      public Builder setData(boolean value) {
+        bitField0_ |= 0x00000001;
+        data_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required bool data = 1;</code>
+       */
+      public Builder clearData() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        data_ = false;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:gazebo.msgs.Bool)
+    }
+
+    static {
+      defaultInstance = new Bool(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:gazebo.msgs.Bool)
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_gazebo_msgs_Bool_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_gazebo_msgs_Bool_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n!frc_gazebo_plugin/msgs/bool.proto\022\013gaz" +
+      "ebo.msgs\"\024\n\004Bool\022\014\n\004data\030\001 \002(\010B\010B\006GzBool"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          internal_static_gazebo_msgs_Bool_descriptor =
+            getDescriptor().getMessageTypes().get(0);
+          internal_static_gazebo_msgs_Bool_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_gazebo_msgs_Bool_descriptor,
+              new java.lang.String[] { "Data", });
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzDriverStation.java b/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzDriverStation.java
new file mode 100644
index 0000000..c3e967d
--- /dev/null
+++ b/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzDriverStation.java
@@ -0,0 +1,645 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: frc_gazebo_plugin/msgs/driver-station.proto
+
+package gazebo.msgs;
+
+public final class GzDriverStation {
+  private GzDriverStation() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface DriverStationOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required bool enabled = 1;
+    /**
+     * <code>required bool enabled = 1;</code>
+     */
+    boolean hasEnabled();
+    /**
+     * <code>required bool enabled = 1;</code>
+     */
+    boolean getEnabled();
+
+    // required .gazebo.msgs.DriverStation.State state = 2;
+    /**
+     * <code>required .gazebo.msgs.DriverStation.State state = 2;</code>
+     */
+    boolean hasState();
+    /**
+     * <code>required .gazebo.msgs.DriverStation.State state = 2;</code>
+     */
+    gazebo.msgs.GzDriverStation.DriverStation.State getState();
+  }
+  /**
+   * Protobuf type {@code gazebo.msgs.DriverStation}
+   */
+  public static final class DriverStation extends
+      com.google.protobuf.GeneratedMessage
+      implements DriverStationOrBuilder {
+    // Use DriverStation.newBuilder() to construct.
+    private DriverStation(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private DriverStation(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final DriverStation defaultInstance;
+    public static DriverStation getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public DriverStation getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private DriverStation(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 8: {
+              bitField0_ |= 0x00000001;
+              enabled_ = input.readBool();
+              break;
+            }
+            case 16: {
+              int rawValue = input.readEnum();
+              gazebo.msgs.GzDriverStation.DriverStation.State value = gazebo.msgs.GzDriverStation.DriverStation.State.valueOf(rawValue);
+              if (value == null) {
+                unknownFields.mergeVarintField(2, rawValue);
+              } else {
+                bitField0_ |= 0x00000002;
+                state_ = value;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return gazebo.msgs.GzDriverStation.internal_static_gazebo_msgs_DriverStation_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return gazebo.msgs.GzDriverStation.internal_static_gazebo_msgs_DriverStation_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              gazebo.msgs.GzDriverStation.DriverStation.class, gazebo.msgs.GzDriverStation.DriverStation.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<DriverStation> PARSER =
+        new com.google.protobuf.AbstractParser<DriverStation>() {
+      public DriverStation parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new DriverStation(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<DriverStation> getParserForType() {
+      return PARSER;
+    }
+
+    /**
+     * Protobuf enum {@code gazebo.msgs.DriverStation.State}
+     */
+    public enum State
+        implements com.google.protobuf.ProtocolMessageEnum {
+      /**
+       * <code>AUTO = 0;</code>
+       */
+      AUTO(0, 0),
+      /**
+       * <code>TELEOP = 1;</code>
+       */
+      TELEOP(1, 1),
+      /**
+       * <code>TEST = 2;</code>
+       */
+      TEST(2, 2),
+      ;
+
+      /**
+       * <code>AUTO = 0;</code>
+       */
+      public static final int AUTO_VALUE = 0;
+      /**
+       * <code>TELEOP = 1;</code>
+       */
+      public static final int TELEOP_VALUE = 1;
+      /**
+       * <code>TEST = 2;</code>
+       */
+      public static final int TEST_VALUE = 2;
+
+
+      public final int getNumber() { return value; }
+
+      public static State valueOf(int value) {
+        switch (value) {
+          case 0: return AUTO;
+          case 1: return TELEOP;
+          case 2: return TEST;
+          default: return null;
+        }
+      }
+
+      public static com.google.protobuf.Internal.EnumLiteMap<State>
+          internalGetValueMap() {
+        return internalValueMap;
+      }
+      private static com.google.protobuf.Internal.EnumLiteMap<State>
+          internalValueMap =
+            new com.google.protobuf.Internal.EnumLiteMap<State>() {
+              public State findValueByNumber(int number) {
+                return State.valueOf(number);
+              }
+            };
+
+      public final com.google.protobuf.Descriptors.EnumValueDescriptor
+          getValueDescriptor() {
+        return getDescriptor().getValues().get(index);
+      }
+      public final com.google.protobuf.Descriptors.EnumDescriptor
+          getDescriptorForType() {
+        return getDescriptor();
+      }
+      public static final com.google.protobuf.Descriptors.EnumDescriptor
+          getDescriptor() {
+        return gazebo.msgs.GzDriverStation.DriverStation.getDescriptor().getEnumTypes().get(0);
+      }
+
+      private static final State[] VALUES = values();
+
+      public static State valueOf(
+          com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
+        if (desc.getType() != getDescriptor()) {
+          throw new java.lang.IllegalArgumentException(
+            "EnumValueDescriptor is not for this type.");
+        }
+        return VALUES[desc.getIndex()];
+      }
+
+      private final int index;
+      private final int value;
+
+      private State(int index, int value) {
+        this.index = index;
+        this.value = value;
+      }
+
+      // @@protoc_insertion_point(enum_scope:gazebo.msgs.DriverStation.State)
+    }
+
+    private int bitField0_;
+    // required bool enabled = 1;
+    public static final int ENABLED_FIELD_NUMBER = 1;
+    private boolean enabled_;
+    /**
+     * <code>required bool enabled = 1;</code>
+     */
+    public boolean hasEnabled() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required bool enabled = 1;</code>
+     */
+    public boolean getEnabled() {
+      return enabled_;
+    }
+
+    // required .gazebo.msgs.DriverStation.State state = 2;
+    public static final int STATE_FIELD_NUMBER = 2;
+    private gazebo.msgs.GzDriverStation.DriverStation.State state_;
+    /**
+     * <code>required .gazebo.msgs.DriverStation.State state = 2;</code>
+     */
+    public boolean hasState() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>required .gazebo.msgs.DriverStation.State state = 2;</code>
+     */
+    public gazebo.msgs.GzDriverStation.DriverStation.State getState() {
+      return state_;
+    }
+
+    private void initFields() {
+      enabled_ = false;
+      state_ = gazebo.msgs.GzDriverStation.DriverStation.State.AUTO;
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasEnabled()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasState()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBool(1, enabled_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeEnum(2, state_.getNumber());
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(1, enabled_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeEnumSize(2, state_.getNumber());
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static gazebo.msgs.GzDriverStation.DriverStation parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static gazebo.msgs.GzDriverStation.DriverStation parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static gazebo.msgs.GzDriverStation.DriverStation parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static gazebo.msgs.GzDriverStation.DriverStation parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static gazebo.msgs.GzDriverStation.DriverStation parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static gazebo.msgs.GzDriverStation.DriverStation parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static gazebo.msgs.GzDriverStation.DriverStation parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static gazebo.msgs.GzDriverStation.DriverStation parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static gazebo.msgs.GzDriverStation.DriverStation parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static gazebo.msgs.GzDriverStation.DriverStation parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(gazebo.msgs.GzDriverStation.DriverStation prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code gazebo.msgs.DriverStation}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements gazebo.msgs.GzDriverStation.DriverStationOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return gazebo.msgs.GzDriverStation.internal_static_gazebo_msgs_DriverStation_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return gazebo.msgs.GzDriverStation.internal_static_gazebo_msgs_DriverStation_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                gazebo.msgs.GzDriverStation.DriverStation.class, gazebo.msgs.GzDriverStation.DriverStation.Builder.class);
+      }
+
+      // Construct using gazebo.msgs.GzDriveStation.DriverStation.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        enabled_ = false;
+        bitField0_ = (bitField0_ & ~0x00000001);
+        state_ = gazebo.msgs.GzDriverStation.DriverStation.State.AUTO;
+        bitField0_ = (bitField0_ & ~0x00000002);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return gazebo.msgs.GzDriverStation.internal_static_gazebo_msgs_DriverStation_descriptor;
+      }
+
+      public gazebo.msgs.GzDriverStation.DriverStation getDefaultInstanceForType() {
+        return gazebo.msgs.GzDriverStation.DriverStation.getDefaultInstance();
+      }
+
+      public gazebo.msgs.GzDriverStation.DriverStation build() {
+        gazebo.msgs.GzDriverStation.DriverStation result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public gazebo.msgs.GzDriverStation.DriverStation buildPartial() {
+        gazebo.msgs.GzDriverStation.DriverStation result = new gazebo.msgs.GzDriverStation.DriverStation(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.enabled_ = enabled_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.state_ = state_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof gazebo.msgs.GzDriverStation.DriverStation) {
+          return mergeFrom((gazebo.msgs.GzDriverStation.DriverStation)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(gazebo.msgs.GzDriverStation.DriverStation other) {
+        if (other == gazebo.msgs.GzDriverStation.DriverStation.getDefaultInstance()) return this;
+        if (other.hasEnabled()) {
+          setEnabled(other.getEnabled());
+        }
+        if (other.hasState()) {
+          setState(other.getState());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasEnabled()) {
+          
+          return false;
+        }
+        if (!hasState()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        gazebo.msgs.GzDriverStation.DriverStation parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (gazebo.msgs.GzDriverStation.DriverStation) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required bool enabled = 1;
+      private boolean enabled_ ;
+      /**
+       * <code>required bool enabled = 1;</code>
+       */
+      public boolean hasEnabled() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required bool enabled = 1;</code>
+       */
+      public boolean getEnabled() {
+        return enabled_;
+      }
+      /**
+       * <code>required bool enabled = 1;</code>
+       */
+      public Builder setEnabled(boolean value) {
+        bitField0_ |= 0x00000001;
+        enabled_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required bool enabled = 1;</code>
+       */
+      public Builder clearEnabled() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        enabled_ = false;
+        onChanged();
+        return this;
+      }
+
+      // required .gazebo.msgs.DriverStation.State state = 2;
+      private gazebo.msgs.GzDriverStation.DriverStation.State state_ = gazebo.msgs.GzDriverStation.DriverStation.State.AUTO;
+      /**
+       * <code>required .gazebo.msgs.DriverStation.State state = 2;</code>
+       */
+      public boolean hasState() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>required .gazebo.msgs.DriverStation.State state = 2;</code>
+       */
+      public gazebo.msgs.GzDriverStation.DriverStation.State getState() {
+        return state_;
+      }
+      /**
+       * <code>required .gazebo.msgs.DriverStation.State state = 2;</code>
+       */
+      public Builder setState(gazebo.msgs.GzDriverStation.DriverStation.State value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        bitField0_ |= 0x00000002;
+        state_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required .gazebo.msgs.DriverStation.State state = 2;</code>
+       */
+      public Builder clearState() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        state_ = gazebo.msgs.GzDriverStation.DriverStation.State.AUTO;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:gazebo.msgs.DriverStation)
+    }
+
+    static {
+      defaultInstance = new DriverStation(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:gazebo.msgs.DriverStation)
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_gazebo_msgs_DriverStation_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_gazebo_msgs_DriverStation_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n+frc_gazebo_plugin/msgs/driver-station." +
+      "proto\022\013gazebo.msgs\"z\n\rDriverStation\022\017\n\007e" +
+      "nabled\030\001 \002(\010\022/\n\005state\030\002 \002(\0162 .gazebo.msg" +
+      "s.DriverStation.State\"\'\n\005State\022\010\n\004AUTO\020\000" +
+      "\022\n\n\006TELEOP\020\001\022\010\n\004TEST\020\002B\020B\016GzDriveStation"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          internal_static_gazebo_msgs_DriverStation_descriptor =
+            getDescriptor().getMessageTypes().get(0);
+          internal_static_gazebo_msgs_DriverStation_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_gazebo_msgs_DriverStation_descriptor,
+              new java.lang.String[] { "Enabled", "State", });
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzFloat64.java b/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzFloat64.java
new file mode 100644
index 0000000..ac5a085
--- /dev/null
+++ b/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzFloat64.java
@@ -0,0 +1,453 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: msgs/float64.proto
+
+package gazebo.msgs;
+
+public final class GzFloat64 {
+  private GzFloat64() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface Float64OrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required double data = 1;
+    /**
+     * <code>required double data = 1;</code>
+     */
+    boolean hasData();
+    /**
+     * <code>required double data = 1;</code>
+     */
+    double getData();
+  }
+  /**
+   * Protobuf type {@code gazebo.msgs.Float64}
+   */
+  public static final class Float64 extends
+      com.google.protobuf.GeneratedMessage
+      implements Float64OrBuilder {
+    // Use Float64.newBuilder() to construct.
+    private Float64(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private Float64(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final Float64 defaultInstance;
+    public static Float64 getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public Float64 getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private Float64(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 9: {
+              bitField0_ |= 0x00000001;
+              data_ = input.readDouble();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return gazebo.msgs.GzFloat64.internal_static_gazebo_msgs_Float64_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return gazebo.msgs.GzFloat64.internal_static_gazebo_msgs_Float64_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              gazebo.msgs.GzFloat64.Float64.class, gazebo.msgs.GzFloat64.Float64.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<Float64> PARSER =
+        new com.google.protobuf.AbstractParser<Float64>() {
+      public Float64 parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new Float64(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<Float64> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required double data = 1;
+    public static final int DATA_FIELD_NUMBER = 1;
+    private double data_;
+    /**
+     * <code>required double data = 1;</code>
+     */
+    public boolean hasData() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required double data = 1;</code>
+     */
+    public double getData() {
+      return data_;
+    }
+
+    private void initFields() {
+      data_ = 0D;
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasData()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeDouble(1, data_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeDoubleSize(1, data_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static gazebo.msgs.GzFloat64.Float64 parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static gazebo.msgs.GzFloat64.Float64 parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static gazebo.msgs.GzFloat64.Float64 parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static gazebo.msgs.GzFloat64.Float64 parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static gazebo.msgs.GzFloat64.Float64 parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static gazebo.msgs.GzFloat64.Float64 parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static gazebo.msgs.GzFloat64.Float64 parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static gazebo.msgs.GzFloat64.Float64 parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static gazebo.msgs.GzFloat64.Float64 parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static gazebo.msgs.GzFloat64.Float64 parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(gazebo.msgs.GzFloat64.Float64 prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code gazebo.msgs.Float64}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements gazebo.msgs.GzFloat64.Float64OrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return gazebo.msgs.GzFloat64.internal_static_gazebo_msgs_Float64_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return gazebo.msgs.GzFloat64.internal_static_gazebo_msgs_Float64_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                gazebo.msgs.GzFloat64.Float64.class, gazebo.msgs.GzFloat64.Float64.Builder.class);
+      }
+
+      // Construct using gazebo.msgs.GzFloat64.Float64.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        data_ = 0D;
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return gazebo.msgs.GzFloat64.internal_static_gazebo_msgs_Float64_descriptor;
+      }
+
+      public gazebo.msgs.GzFloat64.Float64 getDefaultInstanceForType() {
+        return gazebo.msgs.GzFloat64.Float64.getDefaultInstance();
+      }
+
+      public gazebo.msgs.GzFloat64.Float64 build() {
+        gazebo.msgs.GzFloat64.Float64 result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public gazebo.msgs.GzFloat64.Float64 buildPartial() {
+        gazebo.msgs.GzFloat64.Float64 result = new gazebo.msgs.GzFloat64.Float64(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.data_ = data_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof gazebo.msgs.GzFloat64.Float64) {
+          return mergeFrom((gazebo.msgs.GzFloat64.Float64)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(gazebo.msgs.GzFloat64.Float64 other) {
+        if (other == gazebo.msgs.GzFloat64.Float64.getDefaultInstance()) return this;
+        if (other.hasData()) {
+          setData(other.getData());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasData()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        gazebo.msgs.GzFloat64.Float64 parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (gazebo.msgs.GzFloat64.Float64) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required double data = 1;
+      private double data_ ;
+      /**
+       * <code>required double data = 1;</code>
+       */
+      public boolean hasData() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required double data = 1;</code>
+       */
+      public double getData() {
+        return data_;
+      }
+      /**
+       * <code>required double data = 1;</code>
+       */
+      public Builder setData(double value) {
+        bitField0_ |= 0x00000001;
+        data_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required double data = 1;</code>
+       */
+      public Builder clearData() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        data_ = 0D;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:gazebo.msgs.Float64)
+    }
+
+    static {
+      defaultInstance = new Float64(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:gazebo.msgs.Float64)
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_gazebo_msgs_Float64_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_gazebo_msgs_Float64_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\022msgs/float64.proto\022\013gazebo.msgs\"\027\n\007Flo" +
+      "at64\022\014\n\004data\030\001 \002(\001B\013B\tGzFloat64"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          internal_static_gazebo_msgs_Float64_descriptor =
+            getDescriptor().getMessageTypes().get(0);
+          internal_static_gazebo_msgs_Float64_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_gazebo_msgs_Float64_descriptor,
+              new java.lang.String[] { "Data", });
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzJoystick.java b/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzJoystick.java
new file mode 100644
index 0000000..9f1d1a6
--- /dev/null
+++ b/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzJoystick.java
@@ -0,0 +1,670 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: frc_gazebo_plugin/msgs/joystick.proto
+
+package gazebo.msgs;
+
+public final class GzJoystick {
+  private GzJoystick() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface JoystickOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // repeated double axes = 1;
+    /**
+     * <code>repeated double axes = 1;</code>
+     */
+    java.util.List<java.lang.Double> getAxesList();
+    /**
+     * <code>repeated double axes = 1;</code>
+     */
+    int getAxesCount();
+    /**
+     * <code>repeated double axes = 1;</code>
+     */
+    double getAxes(int index);
+
+    // repeated bool buttons = 2;
+    /**
+     * <code>repeated bool buttons = 2;</code>
+     */
+    java.util.List<java.lang.Boolean> getButtonsList();
+    /**
+     * <code>repeated bool buttons = 2;</code>
+     */
+    int getButtonsCount();
+    /**
+     * <code>repeated bool buttons = 2;</code>
+     */
+    boolean getButtons(int index);
+  }
+  /**
+   * Protobuf type {@code gazebo.msgs.Joystick}
+   */
+  public static final class Joystick extends
+      com.google.protobuf.GeneratedMessage
+      implements JoystickOrBuilder {
+    // Use Joystick.newBuilder() to construct.
+    private Joystick(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private Joystick(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final Joystick defaultInstance;
+    public static Joystick getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public Joystick getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private Joystick(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 9: {
+              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+                axes_ = new java.util.ArrayList<java.lang.Double>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              axes_.add(input.readDouble());
+              break;
+            }
+            case 10: {
+              int length = input.readRawVarint32();
+              int limit = input.pushLimit(length);
+              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001) && input.getBytesUntilLimit() > 0) {
+                axes_ = new java.util.ArrayList<java.lang.Double>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              while (input.getBytesUntilLimit() > 0) {
+                axes_.add(input.readDouble());
+              }
+              input.popLimit(limit);
+              break;
+            }
+            case 16: {
+              if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+                buttons_ = new java.util.ArrayList<java.lang.Boolean>();
+                mutable_bitField0_ |= 0x00000002;
+              }
+              buttons_.add(input.readBool());
+              break;
+            }
+            case 18: {
+              int length = input.readRawVarint32();
+              int limit = input.pushLimit(length);
+              if (!((mutable_bitField0_ & 0x00000002) == 0x00000002) && input.getBytesUntilLimit() > 0) {
+                buttons_ = new java.util.ArrayList<java.lang.Boolean>();
+                mutable_bitField0_ |= 0x00000002;
+              }
+              while (input.getBytesUntilLimit() > 0) {
+                buttons_.add(input.readBool());
+              }
+              input.popLimit(limit);
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+          axes_ = java.util.Collections.unmodifiableList(axes_);
+        }
+        if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+          buttons_ = java.util.Collections.unmodifiableList(buttons_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return gazebo.msgs.GzJoystick.internal_static_gazebo_msgs_Joystick_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return gazebo.msgs.GzJoystick.internal_static_gazebo_msgs_Joystick_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              gazebo.msgs.GzJoystick.Joystick.class, gazebo.msgs.GzJoystick.Joystick.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<Joystick> PARSER =
+        new com.google.protobuf.AbstractParser<Joystick>() {
+      public Joystick parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new Joystick(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<Joystick> getParserForType() {
+      return PARSER;
+    }
+
+    // repeated double axes = 1;
+    public static final int AXES_FIELD_NUMBER = 1;
+    private java.util.List<java.lang.Double> axes_;
+    /**
+     * <code>repeated double axes = 1;</code>
+     */
+    public java.util.List<java.lang.Double>
+        getAxesList() {
+      return axes_;
+    }
+    /**
+     * <code>repeated double axes = 1;</code>
+     */
+    public int getAxesCount() {
+      return axes_.size();
+    }
+    /**
+     * <code>repeated double axes = 1;</code>
+     */
+    public double getAxes(int index) {
+      return axes_.get(index);
+    }
+
+    // repeated bool buttons = 2;
+    public static final int BUTTONS_FIELD_NUMBER = 2;
+    private java.util.List<java.lang.Boolean> buttons_;
+    /**
+     * <code>repeated bool buttons = 2;</code>
+     */
+    public java.util.List<java.lang.Boolean>
+        getButtonsList() {
+      return buttons_;
+    }
+    /**
+     * <code>repeated bool buttons = 2;</code>
+     */
+    public int getButtonsCount() {
+      return buttons_.size();
+    }
+    /**
+     * <code>repeated bool buttons = 2;</code>
+     */
+    public boolean getButtons(int index) {
+      return buttons_.get(index);
+    }
+
+    private void initFields() {
+      axes_ = java.util.Collections.emptyList();
+      buttons_ = java.util.Collections.emptyList();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      for (int i = 0; i < axes_.size(); i++) {
+        output.writeDouble(1, axes_.get(i));
+      }
+      for (int i = 0; i < buttons_.size(); i++) {
+        output.writeBool(2, buttons_.get(i));
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      {
+        int dataSize = 0;
+        dataSize = 8 * getAxesList().size();
+        size += dataSize;
+        size += 1 * getAxesList().size();
+      }
+      {
+        int dataSize = 0;
+        dataSize = 1 * getButtonsList().size();
+        size += dataSize;
+        size += 1 * getButtonsList().size();
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static gazebo.msgs.GzJoystick.Joystick parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static gazebo.msgs.GzJoystick.Joystick parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static gazebo.msgs.GzJoystick.Joystick parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static gazebo.msgs.GzJoystick.Joystick parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static gazebo.msgs.GzJoystick.Joystick parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static gazebo.msgs.GzJoystick.Joystick parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static gazebo.msgs.GzJoystick.Joystick parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static gazebo.msgs.GzJoystick.Joystick parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static gazebo.msgs.GzJoystick.Joystick parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static gazebo.msgs.GzJoystick.Joystick parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(gazebo.msgs.GzJoystick.Joystick prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code gazebo.msgs.Joystick}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements gazebo.msgs.GzJoystick.JoystickOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return gazebo.msgs.GzJoystick.internal_static_gazebo_msgs_Joystick_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return gazebo.msgs.GzJoystick.internal_static_gazebo_msgs_Joystick_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                gazebo.msgs.GzJoystick.Joystick.class, gazebo.msgs.GzJoystick.Joystick.Builder.class);
+      }
+
+      // Construct using gazebo.msgs.GzJoystick.Joystick.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        axes_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+        buttons_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000002);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return gazebo.msgs.GzJoystick.internal_static_gazebo_msgs_Joystick_descriptor;
+      }
+
+      public gazebo.msgs.GzJoystick.Joystick getDefaultInstanceForType() {
+        return gazebo.msgs.GzJoystick.Joystick.getDefaultInstance();
+      }
+
+      public gazebo.msgs.GzJoystick.Joystick build() {
+        gazebo.msgs.GzJoystick.Joystick result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public gazebo.msgs.GzJoystick.Joystick buildPartial() {
+        gazebo.msgs.GzJoystick.Joystick result = new gazebo.msgs.GzJoystick.Joystick(this);
+        int from_bitField0_ = bitField0_;
+        if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          axes_ = java.util.Collections.unmodifiableList(axes_);
+          bitField0_ = (bitField0_ & ~0x00000001);
+        }
+        result.axes_ = axes_;
+        if (((bitField0_ & 0x00000002) == 0x00000002)) {
+          buttons_ = java.util.Collections.unmodifiableList(buttons_);
+          bitField0_ = (bitField0_ & ~0x00000002);
+        }
+        result.buttons_ = buttons_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof gazebo.msgs.GzJoystick.Joystick) {
+          return mergeFrom((gazebo.msgs.GzJoystick.Joystick)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(gazebo.msgs.GzJoystick.Joystick other) {
+        if (other == gazebo.msgs.GzJoystick.Joystick.getDefaultInstance()) return this;
+        if (!other.axes_.isEmpty()) {
+          if (axes_.isEmpty()) {
+            axes_ = other.axes_;
+            bitField0_ = (bitField0_ & ~0x00000001);
+          } else {
+            ensureAxesIsMutable();
+            axes_.addAll(other.axes_);
+          }
+          onChanged();
+        }
+        if (!other.buttons_.isEmpty()) {
+          if (buttons_.isEmpty()) {
+            buttons_ = other.buttons_;
+            bitField0_ = (bitField0_ & ~0x00000002);
+          } else {
+            ensureButtonsIsMutable();
+            buttons_.addAll(other.buttons_);
+          }
+          onChanged();
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        gazebo.msgs.GzJoystick.Joystick parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (gazebo.msgs.GzJoystick.Joystick) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // repeated double axes = 1;
+      private java.util.List<java.lang.Double> axes_ = java.util.Collections.emptyList();
+      private void ensureAxesIsMutable() {
+        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+          axes_ = new java.util.ArrayList<java.lang.Double>(axes_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+      /**
+       * <code>repeated double axes = 1;</code>
+       */
+      public java.util.List<java.lang.Double>
+          getAxesList() {
+        return java.util.Collections.unmodifiableList(axes_);
+      }
+      /**
+       * <code>repeated double axes = 1;</code>
+       */
+      public int getAxesCount() {
+        return axes_.size();
+      }
+      /**
+       * <code>repeated double axes = 1;</code>
+       */
+      public double getAxes(int index) {
+        return axes_.get(index);
+      }
+      /**
+       * <code>repeated double axes = 1;</code>
+       */
+      public Builder setAxes(
+          int index, double value) {
+        ensureAxesIsMutable();
+        axes_.set(index, value);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated double axes = 1;</code>
+       */
+      public Builder addAxes(double value) {
+        ensureAxesIsMutable();
+        axes_.add(value);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated double axes = 1;</code>
+       */
+      public Builder addAllAxes(
+          java.lang.Iterable<? extends java.lang.Double> values) {
+        ensureAxesIsMutable();
+        super.addAll(values, axes_);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated double axes = 1;</code>
+       */
+      public Builder clearAxes() {
+        axes_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+        onChanged();
+        return this;
+      }
+
+      // repeated bool buttons = 2;
+      private java.util.List<java.lang.Boolean> buttons_ = java.util.Collections.emptyList();
+      private void ensureButtonsIsMutable() {
+        if (!((bitField0_ & 0x00000002) == 0x00000002)) {
+          buttons_ = new java.util.ArrayList<java.lang.Boolean>(buttons_);
+          bitField0_ |= 0x00000002;
+         }
+      }
+      /**
+       * <code>repeated bool buttons = 2;</code>
+       */
+      public java.util.List<java.lang.Boolean>
+          getButtonsList() {
+        return java.util.Collections.unmodifiableList(buttons_);
+      }
+      /**
+       * <code>repeated bool buttons = 2;</code>
+       */
+      public int getButtonsCount() {
+        return buttons_.size();
+      }
+      /**
+       * <code>repeated bool buttons = 2;</code>
+       */
+      public boolean getButtons(int index) {
+        return buttons_.get(index);
+      }
+      /**
+       * <code>repeated bool buttons = 2;</code>
+       */
+      public Builder setButtons(
+          int index, boolean value) {
+        ensureButtonsIsMutable();
+        buttons_.set(index, value);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated bool buttons = 2;</code>
+       */
+      public Builder addButtons(boolean value) {
+        ensureButtonsIsMutable();
+        buttons_.add(value);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated bool buttons = 2;</code>
+       */
+      public Builder addAllButtons(
+          java.lang.Iterable<? extends java.lang.Boolean> values) {
+        ensureButtonsIsMutable();
+        super.addAll(values, buttons_);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated bool buttons = 2;</code>
+       */
+      public Builder clearButtons() {
+        buttons_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000002);
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:gazebo.msgs.Joystick)
+    }
+
+    static {
+      defaultInstance = new Joystick(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:gazebo.msgs.Joystick)
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_gazebo_msgs_Joystick_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_gazebo_msgs_Joystick_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n%frc_gazebo_plugin/msgs/joystick.proto\022" +
+      "\013gazebo.msgs\")\n\010Joystick\022\014\n\004axes\030\001 \003(\001\022\017" +
+      "\n\007buttons\030\002 \003(\010B\014B\nGzJoystick"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          internal_static_gazebo_msgs_Joystick_descriptor =
+            getDescriptor().getMessageTypes().get(0);
+          internal_static_gazebo_msgs_Joystick_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_gazebo_msgs_Joystick_descriptor,
+              new java.lang.String[] { "Axes", "Buttons", });
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzPacket.java b/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzPacket.java
new file mode 100644
index 0000000..6294811
--- /dev/null
+++ b/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzPacket.java
@@ -0,0 +1,831 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: packet.proto
+
+package gazebo.msgs;
+
+public final class GzPacket {
+  private GzPacket() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface PacketOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required .gazebo.msgs.Time stamp = 1;
+    /**
+     * <code>required .gazebo.msgs.Time stamp = 1;</code>
+     */
+    boolean hasStamp();
+    /**
+     * <code>required .gazebo.msgs.Time stamp = 1;</code>
+     */
+    gazebo.msgs.GzTime.Time getStamp();
+    /**
+     * <code>required .gazebo.msgs.Time stamp = 1;</code>
+     */
+    gazebo.msgs.GzTime.TimeOrBuilder getStampOrBuilder();
+
+    // required string type = 2;
+    /**
+     * <code>required string type = 2;</code>
+     */
+    boolean hasType();
+    /**
+     * <code>required string type = 2;</code>
+     */
+    java.lang.String getType();
+    /**
+     * <code>required string type = 2;</code>
+     */
+    com.google.protobuf.ByteString
+        getTypeBytes();
+
+    // required bytes serialized_data = 3;
+    /**
+     * <code>required bytes serialized_data = 3;</code>
+     */
+    boolean hasSerializedData();
+    /**
+     * <code>required bytes serialized_data = 3;</code>
+     */
+    com.google.protobuf.ByteString getSerializedData();
+  }
+  /**
+   * Protobuf type {@code gazebo.msgs.Packet}
+   */
+  public static final class Packet extends
+      com.google.protobuf.GeneratedMessage
+      implements PacketOrBuilder {
+    // Use Packet.newBuilder() to construct.
+    private Packet(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private Packet(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final Packet defaultInstance;
+    public static Packet getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public Packet getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private Packet(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              gazebo.msgs.GzTime.Time.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+                subBuilder = stamp_.toBuilder();
+              }
+              stamp_ = input.readMessage(gazebo.msgs.GzTime.Time.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(stamp_);
+                stamp_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000001;
+              break;
+            }
+            case 18: {
+              bitField0_ |= 0x00000002;
+              type_ = input.readBytes();
+              break;
+            }
+            case 26: {
+              bitField0_ |= 0x00000004;
+              serializedData_ = input.readBytes();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return gazebo.msgs.GzPacket.internal_static_gazebo_msgs_Packet_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return gazebo.msgs.GzPacket.internal_static_gazebo_msgs_Packet_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              gazebo.msgs.GzPacket.Packet.class, gazebo.msgs.GzPacket.Packet.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<Packet> PARSER =
+        new com.google.protobuf.AbstractParser<Packet>() {
+      public Packet parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new Packet(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<Packet> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required .gazebo.msgs.Time stamp = 1;
+    public static final int STAMP_FIELD_NUMBER = 1;
+    private gazebo.msgs.GzTime.Time stamp_;
+    /**
+     * <code>required .gazebo.msgs.Time stamp = 1;</code>
+     */
+    public boolean hasStamp() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required .gazebo.msgs.Time stamp = 1;</code>
+     */
+    public gazebo.msgs.GzTime.Time getStamp() {
+      return stamp_;
+    }
+    /**
+     * <code>required .gazebo.msgs.Time stamp = 1;</code>
+     */
+    public gazebo.msgs.GzTime.TimeOrBuilder getStampOrBuilder() {
+      return stamp_;
+    }
+
+    // required string type = 2;
+    public static final int TYPE_FIELD_NUMBER = 2;
+    private java.lang.Object type_;
+    /**
+     * <code>required string type = 2;</code>
+     */
+    public boolean hasType() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>required string type = 2;</code>
+     */
+    public java.lang.String getType() {
+      java.lang.Object ref = type_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          type_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string type = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getTypeBytes() {
+      java.lang.Object ref = type_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        type_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // required bytes serialized_data = 3;
+    public static final int SERIALIZED_DATA_FIELD_NUMBER = 3;
+    private com.google.protobuf.ByteString serializedData_;
+    /**
+     * <code>required bytes serialized_data = 3;</code>
+     */
+    public boolean hasSerializedData() {
+      return ((bitField0_ & 0x00000004) == 0x00000004);
+    }
+    /**
+     * <code>required bytes serialized_data = 3;</code>
+     */
+    public com.google.protobuf.ByteString getSerializedData() {
+      return serializedData_;
+    }
+
+    private void initFields() {
+      stamp_ = gazebo.msgs.GzTime.Time.getDefaultInstance();
+      type_ = "";
+      serializedData_ = com.google.protobuf.ByteString.EMPTY;
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasStamp()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasType()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasSerializedData()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!getStamp().isInitialized()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeMessage(1, stamp_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeBytes(2, getTypeBytes());
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        output.writeBytes(3, serializedData_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, stamp_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(2, getTypeBytes());
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(3, serializedData_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static gazebo.msgs.GzPacket.Packet parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static gazebo.msgs.GzPacket.Packet parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static gazebo.msgs.GzPacket.Packet parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static gazebo.msgs.GzPacket.Packet parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static gazebo.msgs.GzPacket.Packet parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static gazebo.msgs.GzPacket.Packet parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static gazebo.msgs.GzPacket.Packet parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static gazebo.msgs.GzPacket.Packet parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static gazebo.msgs.GzPacket.Packet parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static gazebo.msgs.GzPacket.Packet parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(gazebo.msgs.GzPacket.Packet prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code gazebo.msgs.Packet}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements gazebo.msgs.GzPacket.PacketOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return gazebo.msgs.GzPacket.internal_static_gazebo_msgs_Packet_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return gazebo.msgs.GzPacket.internal_static_gazebo_msgs_Packet_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                gazebo.msgs.GzPacket.Packet.class, gazebo.msgs.GzPacket.Packet.Builder.class);
+      }
+
+      // Construct using gazebo.msgs.GzPacket.Packet.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getStampFieldBuilder();
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        if (stampBuilder_ == null) {
+          stamp_ = gazebo.msgs.GzTime.Time.getDefaultInstance();
+        } else {
+          stampBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000001);
+        type_ = "";
+        bitField0_ = (bitField0_ & ~0x00000002);
+        serializedData_ = com.google.protobuf.ByteString.EMPTY;
+        bitField0_ = (bitField0_ & ~0x00000004);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return gazebo.msgs.GzPacket.internal_static_gazebo_msgs_Packet_descriptor;
+      }
+
+      public gazebo.msgs.GzPacket.Packet getDefaultInstanceForType() {
+        return gazebo.msgs.GzPacket.Packet.getDefaultInstance();
+      }
+
+      public gazebo.msgs.GzPacket.Packet build() {
+        gazebo.msgs.GzPacket.Packet result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public gazebo.msgs.GzPacket.Packet buildPartial() {
+        gazebo.msgs.GzPacket.Packet result = new gazebo.msgs.GzPacket.Packet(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        if (stampBuilder_ == null) {
+          result.stamp_ = stamp_;
+        } else {
+          result.stamp_ = stampBuilder_.build();
+        }
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.type_ = type_;
+        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+          to_bitField0_ |= 0x00000004;
+        }
+        result.serializedData_ = serializedData_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof gazebo.msgs.GzPacket.Packet) {
+          return mergeFrom((gazebo.msgs.GzPacket.Packet)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(gazebo.msgs.GzPacket.Packet other) {
+        if (other == gazebo.msgs.GzPacket.Packet.getDefaultInstance()) return this;
+        if (other.hasStamp()) {
+          mergeStamp(other.getStamp());
+        }
+        if (other.hasType()) {
+          bitField0_ |= 0x00000002;
+          type_ = other.type_;
+          onChanged();
+        }
+        if (other.hasSerializedData()) {
+          setSerializedData(other.getSerializedData());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasStamp()) {
+          
+          return false;
+        }
+        if (!hasType()) {
+          
+          return false;
+        }
+        if (!hasSerializedData()) {
+          
+          return false;
+        }
+        if (!getStamp().isInitialized()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        gazebo.msgs.GzPacket.Packet parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (gazebo.msgs.GzPacket.Packet) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required .gazebo.msgs.Time stamp = 1;
+      private gazebo.msgs.GzTime.Time stamp_ = gazebo.msgs.GzTime.Time.getDefaultInstance();
+      private com.google.protobuf.SingleFieldBuilder<
+          gazebo.msgs.GzTime.Time, gazebo.msgs.GzTime.Time.Builder, gazebo.msgs.GzTime.TimeOrBuilder> stampBuilder_;
+      /**
+       * <code>required .gazebo.msgs.Time stamp = 1;</code>
+       */
+      public boolean hasStamp() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required .gazebo.msgs.Time stamp = 1;</code>
+       */
+      public gazebo.msgs.GzTime.Time getStamp() {
+        if (stampBuilder_ == null) {
+          return stamp_;
+        } else {
+          return stampBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>required .gazebo.msgs.Time stamp = 1;</code>
+       */
+      public Builder setStamp(gazebo.msgs.GzTime.Time value) {
+        if (stampBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          stamp_ = value;
+          onChanged();
+        } else {
+          stampBuilder_.setMessage(value);
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>required .gazebo.msgs.Time stamp = 1;</code>
+       */
+      public Builder setStamp(
+          gazebo.msgs.GzTime.Time.Builder builderForValue) {
+        if (stampBuilder_ == null) {
+          stamp_ = builderForValue.build();
+          onChanged();
+        } else {
+          stampBuilder_.setMessage(builderForValue.build());
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>required .gazebo.msgs.Time stamp = 1;</code>
+       */
+      public Builder mergeStamp(gazebo.msgs.GzTime.Time value) {
+        if (stampBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+              stamp_ != gazebo.msgs.GzTime.Time.getDefaultInstance()) {
+            stamp_ =
+              gazebo.msgs.GzTime.Time.newBuilder(stamp_).mergeFrom(value).buildPartial();
+          } else {
+            stamp_ = value;
+          }
+          onChanged();
+        } else {
+          stampBuilder_.mergeFrom(value);
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>required .gazebo.msgs.Time stamp = 1;</code>
+       */
+      public Builder clearStamp() {
+        if (stampBuilder_ == null) {
+          stamp_ = gazebo.msgs.GzTime.Time.getDefaultInstance();
+          onChanged();
+        } else {
+          stampBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+      /**
+       * <code>required .gazebo.msgs.Time stamp = 1;</code>
+       */
+      public gazebo.msgs.GzTime.Time.Builder getStampBuilder() {
+        bitField0_ |= 0x00000001;
+        onChanged();
+        return getStampFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>required .gazebo.msgs.Time stamp = 1;</code>
+       */
+      public gazebo.msgs.GzTime.TimeOrBuilder getStampOrBuilder() {
+        if (stampBuilder_ != null) {
+          return stampBuilder_.getMessageOrBuilder();
+        } else {
+          return stamp_;
+        }
+      }
+      /**
+       * <code>required .gazebo.msgs.Time stamp = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          gazebo.msgs.GzTime.Time, gazebo.msgs.GzTime.Time.Builder, gazebo.msgs.GzTime.TimeOrBuilder> 
+          getStampFieldBuilder() {
+        if (stampBuilder_ == null) {
+          stampBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              gazebo.msgs.GzTime.Time, gazebo.msgs.GzTime.Time.Builder, gazebo.msgs.GzTime.TimeOrBuilder>(
+                  stamp_,
+                  getParentForChildren(),
+                  isClean());
+          stamp_ = null;
+        }
+        return stampBuilder_;
+      }
+
+      // required string type = 2;
+      private java.lang.Object type_ = "";
+      /**
+       * <code>required string type = 2;</code>
+       */
+      public boolean hasType() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>required string type = 2;</code>
+       */
+      public java.lang.String getType() {
+        java.lang.Object ref = type_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          type_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string type = 2;</code>
+       */
+      public com.google.protobuf.ByteString
+          getTypeBytes() {
+        java.lang.Object ref = type_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          type_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string type = 2;</code>
+       */
+      public Builder setType(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        type_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string type = 2;</code>
+       */
+      public Builder clearType() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        type_ = getDefaultInstance().getType();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string type = 2;</code>
+       */
+      public Builder setTypeBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        type_ = value;
+        onChanged();
+        return this;
+      }
+
+      // required bytes serialized_data = 3;
+      private com.google.protobuf.ByteString serializedData_ = com.google.protobuf.ByteString.EMPTY;
+      /**
+       * <code>required bytes serialized_data = 3;</code>
+       */
+      public boolean hasSerializedData() {
+        return ((bitField0_ & 0x00000004) == 0x00000004);
+      }
+      /**
+       * <code>required bytes serialized_data = 3;</code>
+       */
+      public com.google.protobuf.ByteString getSerializedData() {
+        return serializedData_;
+      }
+      /**
+       * <code>required bytes serialized_data = 3;</code>
+       */
+      public Builder setSerializedData(com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000004;
+        serializedData_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required bytes serialized_data = 3;</code>
+       */
+      public Builder clearSerializedData() {
+        bitField0_ = (bitField0_ & ~0x00000004);
+        serializedData_ = getDefaultInstance().getSerializedData();
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:gazebo.msgs.Packet)
+    }
+
+    static {
+      defaultInstance = new Packet(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:gazebo.msgs.Packet)
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_gazebo_msgs_Packet_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_gazebo_msgs_Packet_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\014packet.proto\022\013gazebo.msgs\032\ntime.proto\"" +
+      "Q\n\006Packet\022 \n\005stamp\030\001 \002(\0132\021.gazebo.msgs.T" +
+      "ime\022\014\n\004type\030\002 \002(\t\022\027\n\017serialized_data\030\003 \002" +
+      "(\014B\nB\010GzPacket"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          internal_static_gazebo_msgs_Packet_descriptor =
+            getDescriptor().getMessageTypes().get(0);
+          internal_static_gazebo_msgs_Packet_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_gazebo_msgs_Packet_descriptor,
+              new java.lang.String[] { "Stamp", "Type", "SerializedData", });
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          gazebo.msgs.GzTime.getDescriptor(),
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzPublish.java b/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzPublish.java
new file mode 100644
index 0000000..4e1fea2
--- /dev/null
+++ b/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzPublish.java
@@ -0,0 +1,947 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: gazebo/src/msgs/publish.proto
+
+package gazebo.msgs;
+
+public final class GzPublish {
+  private GzPublish() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface PublishOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required string topic = 1;
+    /**
+     * <code>required string topic = 1;</code>
+     */
+    boolean hasTopic();
+    /**
+     * <code>required string topic = 1;</code>
+     */
+    java.lang.String getTopic();
+    /**
+     * <code>required string topic = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getTopicBytes();
+
+    // required string msg_type = 2;
+    /**
+     * <code>required string msg_type = 2;</code>
+     */
+    boolean hasMsgType();
+    /**
+     * <code>required string msg_type = 2;</code>
+     */
+    java.lang.String getMsgType();
+    /**
+     * <code>required string msg_type = 2;</code>
+     */
+    com.google.protobuf.ByteString
+        getMsgTypeBytes();
+
+    // required string host = 3;
+    /**
+     * <code>required string host = 3;</code>
+     */
+    boolean hasHost();
+    /**
+     * <code>required string host = 3;</code>
+     */
+    java.lang.String getHost();
+    /**
+     * <code>required string host = 3;</code>
+     */
+    com.google.protobuf.ByteString
+        getHostBytes();
+
+    // required uint32 port = 4;
+    /**
+     * <code>required uint32 port = 4;</code>
+     */
+    boolean hasPort();
+    /**
+     * <code>required uint32 port = 4;</code>
+     */
+    int getPort();
+  }
+  /**
+   * Protobuf type {@code gazebo.msgs.Publish}
+   */
+  public static final class Publish extends
+      com.google.protobuf.GeneratedMessage
+      implements PublishOrBuilder {
+    // Use Publish.newBuilder() to construct.
+    private Publish(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private Publish(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final Publish defaultInstance;
+    public static Publish getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public Publish getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private Publish(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              bitField0_ |= 0x00000001;
+              topic_ = input.readBytes();
+              break;
+            }
+            case 18: {
+              bitField0_ |= 0x00000002;
+              msgType_ = input.readBytes();
+              break;
+            }
+            case 26: {
+              bitField0_ |= 0x00000004;
+              host_ = input.readBytes();
+              break;
+            }
+            case 32: {
+              bitField0_ |= 0x00000008;
+              port_ = input.readUInt32();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return gazebo.msgs.GzPublish.internal_static_gazebo_msgs_Publish_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return gazebo.msgs.GzPublish.internal_static_gazebo_msgs_Publish_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              gazebo.msgs.GzPublish.Publish.class, gazebo.msgs.GzPublish.Publish.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<Publish> PARSER =
+        new com.google.protobuf.AbstractParser<Publish>() {
+      public Publish parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new Publish(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<Publish> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required string topic = 1;
+    public static final int TOPIC_FIELD_NUMBER = 1;
+    private java.lang.Object topic_;
+    /**
+     * <code>required string topic = 1;</code>
+     */
+    public boolean hasTopic() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required string topic = 1;</code>
+     */
+    public java.lang.String getTopic() {
+      java.lang.Object ref = topic_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          topic_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string topic = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getTopicBytes() {
+      java.lang.Object ref = topic_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        topic_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // required string msg_type = 2;
+    public static final int MSG_TYPE_FIELD_NUMBER = 2;
+    private java.lang.Object msgType_;
+    /**
+     * <code>required string msg_type = 2;</code>
+     */
+    public boolean hasMsgType() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>required string msg_type = 2;</code>
+     */
+    public java.lang.String getMsgType() {
+      java.lang.Object ref = msgType_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          msgType_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string msg_type = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getMsgTypeBytes() {
+      java.lang.Object ref = msgType_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        msgType_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // required string host = 3;
+    public static final int HOST_FIELD_NUMBER = 3;
+    private java.lang.Object host_;
+    /**
+     * <code>required string host = 3;</code>
+     */
+    public boolean hasHost() {
+      return ((bitField0_ & 0x00000004) == 0x00000004);
+    }
+    /**
+     * <code>required string host = 3;</code>
+     */
+    public java.lang.String getHost() {
+      java.lang.Object ref = host_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          host_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string host = 3;</code>
+     */
+    public com.google.protobuf.ByteString
+        getHostBytes() {
+      java.lang.Object ref = host_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        host_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // required uint32 port = 4;
+    public static final int PORT_FIELD_NUMBER = 4;
+    private int port_;
+    /**
+     * <code>required uint32 port = 4;</code>
+     */
+    public boolean hasPort() {
+      return ((bitField0_ & 0x00000008) == 0x00000008);
+    }
+    /**
+     * <code>required uint32 port = 4;</code>
+     */
+    public int getPort() {
+      return port_;
+    }
+
+    private void initFields() {
+      topic_ = "";
+      msgType_ = "";
+      host_ = "";
+      port_ = 0;
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasTopic()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasMsgType()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasHost()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasPort()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBytes(1, getTopicBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeBytes(2, getMsgTypeBytes());
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        output.writeBytes(3, getHostBytes());
+      }
+      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        output.writeUInt32(4, port_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(1, getTopicBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(2, getMsgTypeBytes());
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(3, getHostBytes());
+      }
+      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeUInt32Size(4, port_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static gazebo.msgs.GzPublish.Publish parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static gazebo.msgs.GzPublish.Publish parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static gazebo.msgs.GzPublish.Publish parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static gazebo.msgs.GzPublish.Publish parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static gazebo.msgs.GzPublish.Publish parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static gazebo.msgs.GzPublish.Publish parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static gazebo.msgs.GzPublish.Publish parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static gazebo.msgs.GzPublish.Publish parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static gazebo.msgs.GzPublish.Publish parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static gazebo.msgs.GzPublish.Publish parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(gazebo.msgs.GzPublish.Publish prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code gazebo.msgs.Publish}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements gazebo.msgs.GzPublish.PublishOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return gazebo.msgs.GzPublish.internal_static_gazebo_msgs_Publish_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return gazebo.msgs.GzPublish.internal_static_gazebo_msgs_Publish_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                gazebo.msgs.GzPublish.Publish.class, gazebo.msgs.GzPublish.Publish.Builder.class);
+      }
+
+      // Construct using gazebo.msgs.GzPublish.Publish.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        topic_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
+        msgType_ = "";
+        bitField0_ = (bitField0_ & ~0x00000002);
+        host_ = "";
+        bitField0_ = (bitField0_ & ~0x00000004);
+        port_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000008);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return gazebo.msgs.GzPublish.internal_static_gazebo_msgs_Publish_descriptor;
+      }
+
+      public gazebo.msgs.GzPublish.Publish getDefaultInstanceForType() {
+        return gazebo.msgs.GzPublish.Publish.getDefaultInstance();
+      }
+
+      public gazebo.msgs.GzPublish.Publish build() {
+        gazebo.msgs.GzPublish.Publish result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public gazebo.msgs.GzPublish.Publish buildPartial() {
+        gazebo.msgs.GzPublish.Publish result = new gazebo.msgs.GzPublish.Publish(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.topic_ = topic_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.msgType_ = msgType_;
+        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+          to_bitField0_ |= 0x00000004;
+        }
+        result.host_ = host_;
+        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+          to_bitField0_ |= 0x00000008;
+        }
+        result.port_ = port_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof gazebo.msgs.GzPublish.Publish) {
+          return mergeFrom((gazebo.msgs.GzPublish.Publish)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(gazebo.msgs.GzPublish.Publish other) {
+        if (other == gazebo.msgs.GzPublish.Publish.getDefaultInstance()) return this;
+        if (other.hasTopic()) {
+          bitField0_ |= 0x00000001;
+          topic_ = other.topic_;
+          onChanged();
+        }
+        if (other.hasMsgType()) {
+          bitField0_ |= 0x00000002;
+          msgType_ = other.msgType_;
+          onChanged();
+        }
+        if (other.hasHost()) {
+          bitField0_ |= 0x00000004;
+          host_ = other.host_;
+          onChanged();
+        }
+        if (other.hasPort()) {
+          setPort(other.getPort());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasTopic()) {
+          
+          return false;
+        }
+        if (!hasMsgType()) {
+          
+          return false;
+        }
+        if (!hasHost()) {
+          
+          return false;
+        }
+        if (!hasPort()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        gazebo.msgs.GzPublish.Publish parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (gazebo.msgs.GzPublish.Publish) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required string topic = 1;
+      private java.lang.Object topic_ = "";
+      /**
+       * <code>required string topic = 1;</code>
+       */
+      public boolean hasTopic() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required string topic = 1;</code>
+       */
+      public java.lang.String getTopic() {
+        java.lang.Object ref = topic_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          topic_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string topic = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getTopicBytes() {
+        java.lang.Object ref = topic_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          topic_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string topic = 1;</code>
+       */
+      public Builder setTopic(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        topic_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string topic = 1;</code>
+       */
+      public Builder clearTopic() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        topic_ = getDefaultInstance().getTopic();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string topic = 1;</code>
+       */
+      public Builder setTopicBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        topic_ = value;
+        onChanged();
+        return this;
+      }
+
+      // required string msg_type = 2;
+      private java.lang.Object msgType_ = "";
+      /**
+       * <code>required string msg_type = 2;</code>
+       */
+      public boolean hasMsgType() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>required string msg_type = 2;</code>
+       */
+      public java.lang.String getMsgType() {
+        java.lang.Object ref = msgType_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          msgType_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string msg_type = 2;</code>
+       */
+      public com.google.protobuf.ByteString
+          getMsgTypeBytes() {
+        java.lang.Object ref = msgType_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          msgType_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string msg_type = 2;</code>
+       */
+      public Builder setMsgType(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        msgType_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string msg_type = 2;</code>
+       */
+      public Builder clearMsgType() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        msgType_ = getDefaultInstance().getMsgType();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string msg_type = 2;</code>
+       */
+      public Builder setMsgTypeBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        msgType_ = value;
+        onChanged();
+        return this;
+      }
+
+      // required string host = 3;
+      private java.lang.Object host_ = "";
+      /**
+       * <code>required string host = 3;</code>
+       */
+      public boolean hasHost() {
+        return ((bitField0_ & 0x00000004) == 0x00000004);
+      }
+      /**
+       * <code>required string host = 3;</code>
+       */
+      public java.lang.String getHost() {
+        java.lang.Object ref = host_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          host_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string host = 3;</code>
+       */
+      public com.google.protobuf.ByteString
+          getHostBytes() {
+        java.lang.Object ref = host_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          host_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string host = 3;</code>
+       */
+      public Builder setHost(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000004;
+        host_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string host = 3;</code>
+       */
+      public Builder clearHost() {
+        bitField0_ = (bitField0_ & ~0x00000004);
+        host_ = getDefaultInstance().getHost();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string host = 3;</code>
+       */
+      public Builder setHostBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000004;
+        host_ = value;
+        onChanged();
+        return this;
+      }
+
+      // required uint32 port = 4;
+      private int port_ ;
+      /**
+       * <code>required uint32 port = 4;</code>
+       */
+      public boolean hasPort() {
+        return ((bitField0_ & 0x00000008) == 0x00000008);
+      }
+      /**
+       * <code>required uint32 port = 4;</code>
+       */
+      public int getPort() {
+        return port_;
+      }
+      /**
+       * <code>required uint32 port = 4;</code>
+       */
+      public Builder setPort(int value) {
+        bitField0_ |= 0x00000008;
+        port_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required uint32 port = 4;</code>
+       */
+      public Builder clearPort() {
+        bitField0_ = (bitField0_ & ~0x00000008);
+        port_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:gazebo.msgs.Publish)
+    }
+
+    static {
+      defaultInstance = new Publish(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:gazebo.msgs.Publish)
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_gazebo_msgs_Publish_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_gazebo_msgs_Publish_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\035gazebo/src/msgs/publish.proto\022\013gazebo." +
+      "msgs\"F\n\007Publish\022\r\n\005topic\030\001 \002(\t\022\020\n\010msg_ty" +
+      "pe\030\002 \002(\t\022\014\n\004host\030\003 \002(\t\022\014\n\004port\030\004 \002(\rB\013B\t" +
+      "GzPublish"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          internal_static_gazebo_msgs_Publish_descriptor =
+            getDescriptor().getMessageTypes().get(0);
+          internal_static_gazebo_msgs_Publish_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_gazebo_msgs_Publish_descriptor,
+              new java.lang.String[] { "Topic", "MsgType", "Host", "Port", });
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzPublishers.java b/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzPublishers.java
new file mode 100644
index 0000000..a3bed6e
--- /dev/null
+++ b/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzPublishers.java
@@ -0,0 +1,737 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: publishers.proto
+
+package gazebo.msgs;
+
+public final class GzPublishers {
+  private GzPublishers() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface PublishersOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // repeated .gazebo.msgs.Publish publisher = 1;
+    /**
+     * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+     */
+    java.util.List<gazebo.msgs.GzPublish.Publish> 
+        getPublisherList();
+    /**
+     * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+     */
+    gazebo.msgs.GzPublish.Publish getPublisher(int index);
+    /**
+     * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+     */
+    int getPublisherCount();
+    /**
+     * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+     */
+    java.util.List<? extends gazebo.msgs.GzPublish.PublishOrBuilder> 
+        getPublisherOrBuilderList();
+    /**
+     * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+     */
+    gazebo.msgs.GzPublish.PublishOrBuilder getPublisherOrBuilder(
+        int index);
+  }
+  /**
+   * Protobuf type {@code gazebo.msgs.Publishers}
+   */
+  public static final class Publishers extends
+      com.google.protobuf.GeneratedMessage
+      implements PublishersOrBuilder {
+    // Use Publishers.newBuilder() to construct.
+    private Publishers(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private Publishers(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final Publishers defaultInstance;
+    public static Publishers getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public Publishers getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private Publishers(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+                publisher_ = new java.util.ArrayList<gazebo.msgs.GzPublish.Publish>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              publisher_.add(input.readMessage(gazebo.msgs.GzPublish.Publish.PARSER, extensionRegistry));
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+          publisher_ = java.util.Collections.unmodifiableList(publisher_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return gazebo.msgs.GzPublishers.internal_static_gazebo_msgs_Publishers_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return gazebo.msgs.GzPublishers.internal_static_gazebo_msgs_Publishers_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              gazebo.msgs.GzPublishers.Publishers.class, gazebo.msgs.GzPublishers.Publishers.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<Publishers> PARSER =
+        new com.google.protobuf.AbstractParser<Publishers>() {
+      public Publishers parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new Publishers(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<Publishers> getParserForType() {
+      return PARSER;
+    }
+
+    // repeated .gazebo.msgs.Publish publisher = 1;
+    public static final int PUBLISHER_FIELD_NUMBER = 1;
+    private java.util.List<gazebo.msgs.GzPublish.Publish> publisher_;
+    /**
+     * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+     */
+    public java.util.List<gazebo.msgs.GzPublish.Publish> getPublisherList() {
+      return publisher_;
+    }
+    /**
+     * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+     */
+    public java.util.List<? extends gazebo.msgs.GzPublish.PublishOrBuilder> 
+        getPublisherOrBuilderList() {
+      return publisher_;
+    }
+    /**
+     * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+     */
+    public int getPublisherCount() {
+      return publisher_.size();
+    }
+    /**
+     * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+     */
+    public gazebo.msgs.GzPublish.Publish getPublisher(int index) {
+      return publisher_.get(index);
+    }
+    /**
+     * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+     */
+    public gazebo.msgs.GzPublish.PublishOrBuilder getPublisherOrBuilder(
+        int index) {
+      return publisher_.get(index);
+    }
+
+    private void initFields() {
+      publisher_ = java.util.Collections.emptyList();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      for (int i = 0; i < getPublisherCount(); i++) {
+        if (!getPublisher(i).isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      for (int i = 0; i < publisher_.size(); i++) {
+        output.writeMessage(1, publisher_.get(i));
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      for (int i = 0; i < publisher_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, publisher_.get(i));
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static gazebo.msgs.GzPublishers.Publishers parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static gazebo.msgs.GzPublishers.Publishers parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static gazebo.msgs.GzPublishers.Publishers parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static gazebo.msgs.GzPublishers.Publishers parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static gazebo.msgs.GzPublishers.Publishers parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static gazebo.msgs.GzPublishers.Publishers parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static gazebo.msgs.GzPublishers.Publishers parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static gazebo.msgs.GzPublishers.Publishers parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static gazebo.msgs.GzPublishers.Publishers parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static gazebo.msgs.GzPublishers.Publishers parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(gazebo.msgs.GzPublishers.Publishers prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code gazebo.msgs.Publishers}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements gazebo.msgs.GzPublishers.PublishersOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return gazebo.msgs.GzPublishers.internal_static_gazebo_msgs_Publishers_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return gazebo.msgs.GzPublishers.internal_static_gazebo_msgs_Publishers_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                gazebo.msgs.GzPublishers.Publishers.class, gazebo.msgs.GzPublishers.Publishers.Builder.class);
+      }
+
+      // Construct using gazebo.msgs.GzPublishers.Publishers.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getPublisherFieldBuilder();
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        if (publisherBuilder_ == null) {
+          publisher_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+        } else {
+          publisherBuilder_.clear();
+        }
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return gazebo.msgs.GzPublishers.internal_static_gazebo_msgs_Publishers_descriptor;
+      }
+
+      public gazebo.msgs.GzPublishers.Publishers getDefaultInstanceForType() {
+        return gazebo.msgs.GzPublishers.Publishers.getDefaultInstance();
+      }
+
+      public gazebo.msgs.GzPublishers.Publishers build() {
+        gazebo.msgs.GzPublishers.Publishers result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public gazebo.msgs.GzPublishers.Publishers buildPartial() {
+        gazebo.msgs.GzPublishers.Publishers result = new gazebo.msgs.GzPublishers.Publishers(this);
+        int from_bitField0_ = bitField0_;
+        if (publisherBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+            publisher_ = java.util.Collections.unmodifiableList(publisher_);
+            bitField0_ = (bitField0_ & ~0x00000001);
+          }
+          result.publisher_ = publisher_;
+        } else {
+          result.publisher_ = publisherBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof gazebo.msgs.GzPublishers.Publishers) {
+          return mergeFrom((gazebo.msgs.GzPublishers.Publishers)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(gazebo.msgs.GzPublishers.Publishers other) {
+        if (other == gazebo.msgs.GzPublishers.Publishers.getDefaultInstance()) return this;
+        if (publisherBuilder_ == null) {
+          if (!other.publisher_.isEmpty()) {
+            if (publisher_.isEmpty()) {
+              publisher_ = other.publisher_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+            } else {
+              ensurePublisherIsMutable();
+              publisher_.addAll(other.publisher_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.publisher_.isEmpty()) {
+            if (publisherBuilder_.isEmpty()) {
+              publisherBuilder_.dispose();
+              publisherBuilder_ = null;
+              publisher_ = other.publisher_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+              publisherBuilder_ = 
+                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+                   getPublisherFieldBuilder() : null;
+            } else {
+              publisherBuilder_.addAllMessages(other.publisher_);
+            }
+          }
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        for (int i = 0; i < getPublisherCount(); i++) {
+          if (!getPublisher(i).isInitialized()) {
+            
+            return false;
+          }
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        gazebo.msgs.GzPublishers.Publishers parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (gazebo.msgs.GzPublishers.Publishers) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // repeated .gazebo.msgs.Publish publisher = 1;
+      private java.util.List<gazebo.msgs.GzPublish.Publish> publisher_ =
+        java.util.Collections.emptyList();
+      private void ensurePublisherIsMutable() {
+        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+          publisher_ = new java.util.ArrayList<gazebo.msgs.GzPublish.Publish>(publisher_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilder<
+          gazebo.msgs.GzPublish.Publish, gazebo.msgs.GzPublish.Publish.Builder, gazebo.msgs.GzPublish.PublishOrBuilder> publisherBuilder_;
+
+      /**
+       * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+       */
+      public java.util.List<gazebo.msgs.GzPublish.Publish> getPublisherList() {
+        if (publisherBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(publisher_);
+        } else {
+          return publisherBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+       */
+      public int getPublisherCount() {
+        if (publisherBuilder_ == null) {
+          return publisher_.size();
+        } else {
+          return publisherBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+       */
+      public gazebo.msgs.GzPublish.Publish getPublisher(int index) {
+        if (publisherBuilder_ == null) {
+          return publisher_.get(index);
+        } else {
+          return publisherBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+       */
+      public Builder setPublisher(
+          int index, gazebo.msgs.GzPublish.Publish value) {
+        if (publisherBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensurePublisherIsMutable();
+          publisher_.set(index, value);
+          onChanged();
+        } else {
+          publisherBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+       */
+      public Builder setPublisher(
+          int index, gazebo.msgs.GzPublish.Publish.Builder builderForValue) {
+        if (publisherBuilder_ == null) {
+          ensurePublisherIsMutable();
+          publisher_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          publisherBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+       */
+      public Builder addPublisher(gazebo.msgs.GzPublish.Publish value) {
+        if (publisherBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensurePublisherIsMutable();
+          publisher_.add(value);
+          onChanged();
+        } else {
+          publisherBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+       */
+      public Builder addPublisher(
+          int index, gazebo.msgs.GzPublish.Publish value) {
+        if (publisherBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensurePublisherIsMutable();
+          publisher_.add(index, value);
+          onChanged();
+        } else {
+          publisherBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+       */
+      public Builder addPublisher(
+          gazebo.msgs.GzPublish.Publish.Builder builderForValue) {
+        if (publisherBuilder_ == null) {
+          ensurePublisherIsMutable();
+          publisher_.add(builderForValue.build());
+          onChanged();
+        } else {
+          publisherBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+       */
+      public Builder addPublisher(
+          int index, gazebo.msgs.GzPublish.Publish.Builder builderForValue) {
+        if (publisherBuilder_ == null) {
+          ensurePublisherIsMutable();
+          publisher_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          publisherBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+       */
+      public Builder addAllPublisher(
+          java.lang.Iterable<? extends gazebo.msgs.GzPublish.Publish> values) {
+        if (publisherBuilder_ == null) {
+          ensurePublisherIsMutable();
+          super.addAll(values, publisher_);
+          onChanged();
+        } else {
+          publisherBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+       */
+      public Builder clearPublisher() {
+        if (publisherBuilder_ == null) {
+          publisher_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+          onChanged();
+        } else {
+          publisherBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+       */
+      public Builder removePublisher(int index) {
+        if (publisherBuilder_ == null) {
+          ensurePublisherIsMutable();
+          publisher_.remove(index);
+          onChanged();
+        } else {
+          publisherBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+       */
+      public gazebo.msgs.GzPublish.Publish.Builder getPublisherBuilder(
+          int index) {
+        return getPublisherFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+       */
+      public gazebo.msgs.GzPublish.PublishOrBuilder getPublisherOrBuilder(
+          int index) {
+        if (publisherBuilder_ == null) {
+          return publisher_.get(index);  } else {
+          return publisherBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+       */
+      public java.util.List<? extends gazebo.msgs.GzPublish.PublishOrBuilder> 
+           getPublisherOrBuilderList() {
+        if (publisherBuilder_ != null) {
+          return publisherBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(publisher_);
+        }
+      }
+      /**
+       * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+       */
+      public gazebo.msgs.GzPublish.Publish.Builder addPublisherBuilder() {
+        return getPublisherFieldBuilder().addBuilder(
+            gazebo.msgs.GzPublish.Publish.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+       */
+      public gazebo.msgs.GzPublish.Publish.Builder addPublisherBuilder(
+          int index) {
+        return getPublisherFieldBuilder().addBuilder(
+            index, gazebo.msgs.GzPublish.Publish.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .gazebo.msgs.Publish publisher = 1;</code>
+       */
+      public java.util.List<gazebo.msgs.GzPublish.Publish.Builder> 
+           getPublisherBuilderList() {
+        return getPublisherFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilder<
+          gazebo.msgs.GzPublish.Publish, gazebo.msgs.GzPublish.Publish.Builder, gazebo.msgs.GzPublish.PublishOrBuilder> 
+          getPublisherFieldBuilder() {
+        if (publisherBuilder_ == null) {
+          publisherBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+              gazebo.msgs.GzPublish.Publish, gazebo.msgs.GzPublish.Publish.Builder, gazebo.msgs.GzPublish.PublishOrBuilder>(
+                  publisher_,
+                  ((bitField0_ & 0x00000001) == 0x00000001),
+                  getParentForChildren(),
+                  isClean());
+          publisher_ = null;
+        }
+        return publisherBuilder_;
+      }
+
+      // @@protoc_insertion_point(builder_scope:gazebo.msgs.Publishers)
+    }
+
+    static {
+      defaultInstance = new Publishers(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:gazebo.msgs.Publishers)
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_gazebo_msgs_Publishers_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_gazebo_msgs_Publishers_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\020publishers.proto\022\013gazebo.msgs\032\rpublish" +
+      ".proto\"5\n\nPublishers\022\'\n\tpublisher\030\001 \003(\0132" +
+      "\024.gazebo.msgs.PublishB\016B\014GzPublishers"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          internal_static_gazebo_msgs_Publishers_descriptor =
+            getDescriptor().getMessageTypes().get(0);
+          internal_static_gazebo_msgs_Publishers_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_gazebo_msgs_Publishers_descriptor,
+              new java.lang.String[] { "Publisher", });
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          gazebo.msgs.GzPublish.getDescriptor(),
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzString.java b/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzString.java
new file mode 100644
index 0000000..54b5752
--- /dev/null
+++ b/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzString.java
@@ -0,0 +1,528 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: gz_string.proto
+
+package gazebo.msgs;
+
+public final class GzString {
+  private GzString() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface StringOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required string data = 1;
+    /**
+     * <code>required string data = 1;</code>
+     */
+    boolean hasData();
+    /**
+     * <code>required string data = 1;</code>
+     */
+    java.lang.String getData();
+    /**
+     * <code>required string data = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getDataBytes();
+  }
+  /**
+   * Protobuf type {@code gazebo.msgs.String}
+   */
+  public static final class String extends
+      com.google.protobuf.GeneratedMessage
+      implements StringOrBuilder {
+    // Use String.newBuilder() to construct.
+    private String(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private String(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final String defaultInstance;
+    public static String getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public String getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private String(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              bitField0_ |= 0x00000001;
+              data_ = input.readBytes();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return gazebo.msgs.GzString.internal_static_gazebo_msgs_String_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return gazebo.msgs.GzString.internal_static_gazebo_msgs_String_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              gazebo.msgs.GzString.String.class, gazebo.msgs.GzString.String.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<String> PARSER =
+        new com.google.protobuf.AbstractParser<String>() {
+      public String parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new String(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<String> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required string data = 1;
+    public static final int DATA_FIELD_NUMBER = 1;
+    private java.lang.Object data_;
+    /**
+     * <code>required string data = 1;</code>
+     */
+    public boolean hasData() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required string data = 1;</code>
+     */
+    public java.lang.String getData() {
+      java.lang.Object ref = data_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          data_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string data = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getDataBytes() {
+      java.lang.Object ref = data_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        data_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    private void initFields() {
+      data_ = "";
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasData()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBytes(1, getDataBytes());
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(1, getDataBytes());
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static gazebo.msgs.GzString.String parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static gazebo.msgs.GzString.String parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static gazebo.msgs.GzString.String parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static gazebo.msgs.GzString.String parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static gazebo.msgs.GzString.String parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static gazebo.msgs.GzString.String parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static gazebo.msgs.GzString.String parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static gazebo.msgs.GzString.String parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static gazebo.msgs.GzString.String parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static gazebo.msgs.GzString.String parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(gazebo.msgs.GzString.String prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code gazebo.msgs.String}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements gazebo.msgs.GzString.StringOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return gazebo.msgs.GzString.internal_static_gazebo_msgs_String_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return gazebo.msgs.GzString.internal_static_gazebo_msgs_String_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                gazebo.msgs.GzString.String.class, gazebo.msgs.GzString.String.Builder.class);
+      }
+
+      // Construct using gazebo.msgs.GzString.String.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        data_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return gazebo.msgs.GzString.internal_static_gazebo_msgs_String_descriptor;
+      }
+
+      public gazebo.msgs.GzString.String getDefaultInstanceForType() {
+        return gazebo.msgs.GzString.String.getDefaultInstance();
+      }
+
+      public gazebo.msgs.GzString.String build() {
+        gazebo.msgs.GzString.String result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public gazebo.msgs.GzString.String buildPartial() {
+        gazebo.msgs.GzString.String result = new gazebo.msgs.GzString.String(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.data_ = data_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof gazebo.msgs.GzString.String) {
+          return mergeFrom((gazebo.msgs.GzString.String)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(gazebo.msgs.GzString.String other) {
+        if (other == gazebo.msgs.GzString.String.getDefaultInstance()) return this;
+        if (other.hasData()) {
+          bitField0_ |= 0x00000001;
+          data_ = other.data_;
+          onChanged();
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasData()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        gazebo.msgs.GzString.String parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (gazebo.msgs.GzString.String) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required string data = 1;
+      private java.lang.Object data_ = "";
+      /**
+       * <code>required string data = 1;</code>
+       */
+      public boolean hasData() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required string data = 1;</code>
+       */
+      public java.lang.String getData() {
+        java.lang.Object ref = data_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          data_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string data = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getDataBytes() {
+        java.lang.Object ref = data_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          data_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string data = 1;</code>
+       */
+      public Builder setData(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        data_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string data = 1;</code>
+       */
+      public Builder clearData() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        data_ = getDefaultInstance().getData();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string data = 1;</code>
+       */
+      public Builder setDataBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        data_ = value;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:gazebo.msgs.String)
+    }
+
+    static {
+      defaultInstance = new String(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:gazebo.msgs.String)
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_gazebo_msgs_String_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_gazebo_msgs_String_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\017gz_string.proto\022\013gazebo.msgs\"\026\n\006String" +
+      "\022\014\n\004data\030\001 \002(\t"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          internal_static_gazebo_msgs_String_descriptor =
+            getDescriptor().getMessageTypes().get(0);
+          internal_static_gazebo_msgs_String_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_gazebo_msgs_String_descriptor,
+              new java.lang.String[] { "Data", });
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzSubscribe.java b/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzSubscribe.java
new file mode 100644
index 0000000..b29c447
--- /dev/null
+++ b/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzSubscribe.java
@@ -0,0 +1,1028 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: subscribe.proto
+
+package gazebo.msgs;
+
+public final class GzSubscribe {
+  private GzSubscribe() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface SubscribeOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required string topic = 1;
+    /**
+     * <code>required string topic = 1;</code>
+     */
+    boolean hasTopic();
+    /**
+     * <code>required string topic = 1;</code>
+     */
+    java.lang.String getTopic();
+    /**
+     * <code>required string topic = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getTopicBytes();
+
+    // required string host = 2;
+    /**
+     * <code>required string host = 2;</code>
+     */
+    boolean hasHost();
+    /**
+     * <code>required string host = 2;</code>
+     */
+    java.lang.String getHost();
+    /**
+     * <code>required string host = 2;</code>
+     */
+    com.google.protobuf.ByteString
+        getHostBytes();
+
+    // required uint32 port = 3;
+    /**
+     * <code>required uint32 port = 3;</code>
+     */
+    boolean hasPort();
+    /**
+     * <code>required uint32 port = 3;</code>
+     */
+    int getPort();
+
+    // required string msg_type = 4;
+    /**
+     * <code>required string msg_type = 4;</code>
+     */
+    boolean hasMsgType();
+    /**
+     * <code>required string msg_type = 4;</code>
+     */
+    java.lang.String getMsgType();
+    /**
+     * <code>required string msg_type = 4;</code>
+     */
+    com.google.protobuf.ByteString
+        getMsgTypeBytes();
+
+    // optional bool latching = 5 [default = true];
+    /**
+     * <code>optional bool latching = 5 [default = true];</code>
+     */
+    boolean hasLatching();
+    /**
+     * <code>optional bool latching = 5 [default = true];</code>
+     */
+    boolean getLatching();
+  }
+  /**
+   * Protobuf type {@code gazebo.msgs.Subscribe}
+   */
+  public static final class Subscribe extends
+      com.google.protobuf.GeneratedMessage
+      implements SubscribeOrBuilder {
+    // Use Subscribe.newBuilder() to construct.
+    private Subscribe(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private Subscribe(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final Subscribe defaultInstance;
+    public static Subscribe getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public Subscribe getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private Subscribe(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              bitField0_ |= 0x00000001;
+              topic_ = input.readBytes();
+              break;
+            }
+            case 18: {
+              bitField0_ |= 0x00000002;
+              host_ = input.readBytes();
+              break;
+            }
+            case 24: {
+              bitField0_ |= 0x00000004;
+              port_ = input.readUInt32();
+              break;
+            }
+            case 34: {
+              bitField0_ |= 0x00000008;
+              msgType_ = input.readBytes();
+              break;
+            }
+            case 40: {
+              bitField0_ |= 0x00000010;
+              latching_ = input.readBool();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return gazebo.msgs.GzSubscribe.internal_static_gazebo_msgs_Subscribe_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return gazebo.msgs.GzSubscribe.internal_static_gazebo_msgs_Subscribe_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              gazebo.msgs.GzSubscribe.Subscribe.class, gazebo.msgs.GzSubscribe.Subscribe.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<Subscribe> PARSER =
+        new com.google.protobuf.AbstractParser<Subscribe>() {
+      public Subscribe parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new Subscribe(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<Subscribe> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required string topic = 1;
+    public static final int TOPIC_FIELD_NUMBER = 1;
+    private java.lang.Object topic_;
+    /**
+     * <code>required string topic = 1;</code>
+     */
+    public boolean hasTopic() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required string topic = 1;</code>
+     */
+    public java.lang.String getTopic() {
+      java.lang.Object ref = topic_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          topic_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string topic = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getTopicBytes() {
+      java.lang.Object ref = topic_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        topic_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // required string host = 2;
+    public static final int HOST_FIELD_NUMBER = 2;
+    private java.lang.Object host_;
+    /**
+     * <code>required string host = 2;</code>
+     */
+    public boolean hasHost() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>required string host = 2;</code>
+     */
+    public java.lang.String getHost() {
+      java.lang.Object ref = host_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          host_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string host = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getHostBytes() {
+      java.lang.Object ref = host_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        host_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // required uint32 port = 3;
+    public static final int PORT_FIELD_NUMBER = 3;
+    private int port_;
+    /**
+     * <code>required uint32 port = 3;</code>
+     */
+    public boolean hasPort() {
+      return ((bitField0_ & 0x00000004) == 0x00000004);
+    }
+    /**
+     * <code>required uint32 port = 3;</code>
+     */
+    public int getPort() {
+      return port_;
+    }
+
+    // required string msg_type = 4;
+    public static final int MSG_TYPE_FIELD_NUMBER = 4;
+    private java.lang.Object msgType_;
+    /**
+     * <code>required string msg_type = 4;</code>
+     */
+    public boolean hasMsgType() {
+      return ((bitField0_ & 0x00000008) == 0x00000008);
+    }
+    /**
+     * <code>required string msg_type = 4;</code>
+     */
+    public java.lang.String getMsgType() {
+      java.lang.Object ref = msgType_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          msgType_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string msg_type = 4;</code>
+     */
+    public com.google.protobuf.ByteString
+        getMsgTypeBytes() {
+      java.lang.Object ref = msgType_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        msgType_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // optional bool latching = 5 [default = true];
+    public static final int LATCHING_FIELD_NUMBER = 5;
+    private boolean latching_;
+    /**
+     * <code>optional bool latching = 5 [default = true];</code>
+     */
+    public boolean hasLatching() {
+      return ((bitField0_ & 0x00000010) == 0x00000010);
+    }
+    /**
+     * <code>optional bool latching = 5 [default = true];</code>
+     */
+    public boolean getLatching() {
+      return latching_;
+    }
+
+    private void initFields() {
+      topic_ = "";
+      host_ = "";
+      port_ = 0;
+      msgType_ = "";
+      latching_ = true;
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasTopic()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasHost()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasPort()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasMsgType()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBytes(1, getTopicBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeBytes(2, getHostBytes());
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        output.writeUInt32(3, port_);
+      }
+      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        output.writeBytes(4, getMsgTypeBytes());
+      }
+      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+        output.writeBool(5, latching_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(1, getTopicBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(2, getHostBytes());
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeUInt32Size(3, port_);
+      }
+      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(4, getMsgTypeBytes());
+      }
+      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(5, latching_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static gazebo.msgs.GzSubscribe.Subscribe parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static gazebo.msgs.GzSubscribe.Subscribe parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static gazebo.msgs.GzSubscribe.Subscribe parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static gazebo.msgs.GzSubscribe.Subscribe parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static gazebo.msgs.GzSubscribe.Subscribe parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static gazebo.msgs.GzSubscribe.Subscribe parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static gazebo.msgs.GzSubscribe.Subscribe parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static gazebo.msgs.GzSubscribe.Subscribe parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static gazebo.msgs.GzSubscribe.Subscribe parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static gazebo.msgs.GzSubscribe.Subscribe parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(gazebo.msgs.GzSubscribe.Subscribe prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code gazebo.msgs.Subscribe}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements gazebo.msgs.GzSubscribe.SubscribeOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return gazebo.msgs.GzSubscribe.internal_static_gazebo_msgs_Subscribe_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return gazebo.msgs.GzSubscribe.internal_static_gazebo_msgs_Subscribe_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                gazebo.msgs.GzSubscribe.Subscribe.class, gazebo.msgs.GzSubscribe.Subscribe.Builder.class);
+      }
+
+      // Construct using gazebo.msgs.GzSubscribe.Subscribe.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        topic_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
+        host_ = "";
+        bitField0_ = (bitField0_ & ~0x00000002);
+        port_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000004);
+        msgType_ = "";
+        bitField0_ = (bitField0_ & ~0x00000008);
+        latching_ = true;
+        bitField0_ = (bitField0_ & ~0x00000010);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return gazebo.msgs.GzSubscribe.internal_static_gazebo_msgs_Subscribe_descriptor;
+      }
+
+      public gazebo.msgs.GzSubscribe.Subscribe getDefaultInstanceForType() {
+        return gazebo.msgs.GzSubscribe.Subscribe.getDefaultInstance();
+      }
+
+      public gazebo.msgs.GzSubscribe.Subscribe build() {
+        gazebo.msgs.GzSubscribe.Subscribe result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public gazebo.msgs.GzSubscribe.Subscribe buildPartial() {
+        gazebo.msgs.GzSubscribe.Subscribe result = new gazebo.msgs.GzSubscribe.Subscribe(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.topic_ = topic_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.host_ = host_;
+        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+          to_bitField0_ |= 0x00000004;
+        }
+        result.port_ = port_;
+        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+          to_bitField0_ |= 0x00000008;
+        }
+        result.msgType_ = msgType_;
+        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
+          to_bitField0_ |= 0x00000010;
+        }
+        result.latching_ = latching_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof gazebo.msgs.GzSubscribe.Subscribe) {
+          return mergeFrom((gazebo.msgs.GzSubscribe.Subscribe)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(gazebo.msgs.GzSubscribe.Subscribe other) {
+        if (other == gazebo.msgs.GzSubscribe.Subscribe.getDefaultInstance()) return this;
+        if (other.hasTopic()) {
+          bitField0_ |= 0x00000001;
+          topic_ = other.topic_;
+          onChanged();
+        }
+        if (other.hasHost()) {
+          bitField0_ |= 0x00000002;
+          host_ = other.host_;
+          onChanged();
+        }
+        if (other.hasPort()) {
+          setPort(other.getPort());
+        }
+        if (other.hasMsgType()) {
+          bitField0_ |= 0x00000008;
+          msgType_ = other.msgType_;
+          onChanged();
+        }
+        if (other.hasLatching()) {
+          setLatching(other.getLatching());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasTopic()) {
+          
+          return false;
+        }
+        if (!hasHost()) {
+          
+          return false;
+        }
+        if (!hasPort()) {
+          
+          return false;
+        }
+        if (!hasMsgType()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        gazebo.msgs.GzSubscribe.Subscribe parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (gazebo.msgs.GzSubscribe.Subscribe) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required string topic = 1;
+      private java.lang.Object topic_ = "";
+      /**
+       * <code>required string topic = 1;</code>
+       */
+      public boolean hasTopic() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required string topic = 1;</code>
+       */
+      public java.lang.String getTopic() {
+        java.lang.Object ref = topic_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          topic_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string topic = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getTopicBytes() {
+        java.lang.Object ref = topic_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          topic_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string topic = 1;</code>
+       */
+      public Builder setTopic(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        topic_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string topic = 1;</code>
+       */
+      public Builder clearTopic() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        topic_ = getDefaultInstance().getTopic();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string topic = 1;</code>
+       */
+      public Builder setTopicBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        topic_ = value;
+        onChanged();
+        return this;
+      }
+
+      // required string host = 2;
+      private java.lang.Object host_ = "";
+      /**
+       * <code>required string host = 2;</code>
+       */
+      public boolean hasHost() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>required string host = 2;</code>
+       */
+      public java.lang.String getHost() {
+        java.lang.Object ref = host_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          host_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string host = 2;</code>
+       */
+      public com.google.protobuf.ByteString
+          getHostBytes() {
+        java.lang.Object ref = host_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          host_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string host = 2;</code>
+       */
+      public Builder setHost(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        host_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string host = 2;</code>
+       */
+      public Builder clearHost() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        host_ = getDefaultInstance().getHost();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string host = 2;</code>
+       */
+      public Builder setHostBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        host_ = value;
+        onChanged();
+        return this;
+      }
+
+      // required uint32 port = 3;
+      private int port_ ;
+      /**
+       * <code>required uint32 port = 3;</code>
+       */
+      public boolean hasPort() {
+        return ((bitField0_ & 0x00000004) == 0x00000004);
+      }
+      /**
+       * <code>required uint32 port = 3;</code>
+       */
+      public int getPort() {
+        return port_;
+      }
+      /**
+       * <code>required uint32 port = 3;</code>
+       */
+      public Builder setPort(int value) {
+        bitField0_ |= 0x00000004;
+        port_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required uint32 port = 3;</code>
+       */
+      public Builder clearPort() {
+        bitField0_ = (bitField0_ & ~0x00000004);
+        port_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // required string msg_type = 4;
+      private java.lang.Object msgType_ = "";
+      /**
+       * <code>required string msg_type = 4;</code>
+       */
+      public boolean hasMsgType() {
+        return ((bitField0_ & 0x00000008) == 0x00000008);
+      }
+      /**
+       * <code>required string msg_type = 4;</code>
+       */
+      public java.lang.String getMsgType() {
+        java.lang.Object ref = msgType_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          msgType_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string msg_type = 4;</code>
+       */
+      public com.google.protobuf.ByteString
+          getMsgTypeBytes() {
+        java.lang.Object ref = msgType_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          msgType_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string msg_type = 4;</code>
+       */
+      public Builder setMsgType(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000008;
+        msgType_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string msg_type = 4;</code>
+       */
+      public Builder clearMsgType() {
+        bitField0_ = (bitField0_ & ~0x00000008);
+        msgType_ = getDefaultInstance().getMsgType();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string msg_type = 4;</code>
+       */
+      public Builder setMsgTypeBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000008;
+        msgType_ = value;
+        onChanged();
+        return this;
+      }
+
+      // optional bool latching = 5 [default = true];
+      private boolean latching_ = true;
+      /**
+       * <code>optional bool latching = 5 [default = true];</code>
+       */
+      public boolean hasLatching() {
+        return ((bitField0_ & 0x00000010) == 0x00000010);
+      }
+      /**
+       * <code>optional bool latching = 5 [default = true];</code>
+       */
+      public boolean getLatching() {
+        return latching_;
+      }
+      /**
+       * <code>optional bool latching = 5 [default = true];</code>
+       */
+      public Builder setLatching(boolean value) {
+        bitField0_ |= 0x00000010;
+        latching_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional bool latching = 5 [default = true];</code>
+       */
+      public Builder clearLatching() {
+        bitField0_ = (bitField0_ & ~0x00000010);
+        latching_ = true;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:gazebo.msgs.Subscribe)
+    }
+
+    static {
+      defaultInstance = new Subscribe(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:gazebo.msgs.Subscribe)
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_gazebo_msgs_Subscribe_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_gazebo_msgs_Subscribe_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\017subscribe.proto\022\013gazebo.msgs\"`\n\tSubscr" +
+      "ibe\022\r\n\005topic\030\001 \002(\t\022\014\n\004host\030\002 \002(\t\022\014\n\004port" +
+      "\030\003 \002(\r\022\020\n\010msg_type\030\004 \002(\t\022\026\n\010latching\030\005 \001" +
+      "(\010:\004trueB\rB\013GzSubscribe"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          internal_static_gazebo_msgs_Subscribe_descriptor =
+            getDescriptor().getMessageTypes().get(0);
+          internal_static_gazebo_msgs_Subscribe_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_gazebo_msgs_Subscribe_descriptor,
+              new java.lang.String[] { "Topic", "Host", "Port", "MsgType", "Latching", });
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzTime.java b/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzTime.java
new file mode 100644
index 0000000..faa0a46
--- /dev/null
+++ b/simulation/JavaGazebo/src/main/java/gazebo/msgs/GzTime.java
@@ -0,0 +1,542 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: time.proto
+
+package gazebo.msgs;
+
+public final class GzTime {
+  private GzTime() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface TimeOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required int32 sec = 1;
+    /**
+     * <code>required int32 sec = 1;</code>
+     */
+    boolean hasSec();
+    /**
+     * <code>required int32 sec = 1;</code>
+     */
+    int getSec();
+
+    // required int32 nsec = 2;
+    /**
+     * <code>required int32 nsec = 2;</code>
+     */
+    boolean hasNsec();
+    /**
+     * <code>required int32 nsec = 2;</code>
+     */
+    int getNsec();
+  }
+  /**
+   * Protobuf type {@code gazebo.msgs.Time}
+   */
+  public static final class Time extends
+      com.google.protobuf.GeneratedMessage
+      implements TimeOrBuilder {
+    // Use Time.newBuilder() to construct.
+    private Time(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private Time(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final Time defaultInstance;
+    public static Time getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public Time getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private Time(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 8: {
+              bitField0_ |= 0x00000001;
+              sec_ = input.readInt32();
+              break;
+            }
+            case 16: {
+              bitField0_ |= 0x00000002;
+              nsec_ = input.readInt32();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return gazebo.msgs.GzTime.internal_static_gazebo_msgs_Time_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return gazebo.msgs.GzTime.internal_static_gazebo_msgs_Time_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              gazebo.msgs.GzTime.Time.class, gazebo.msgs.GzTime.Time.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<Time> PARSER =
+        new com.google.protobuf.AbstractParser<Time>() {
+      public Time parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new Time(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<Time> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required int32 sec = 1;
+    public static final int SEC_FIELD_NUMBER = 1;
+    private int sec_;
+    /**
+     * <code>required int32 sec = 1;</code>
+     */
+    public boolean hasSec() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required int32 sec = 1;</code>
+     */
+    public int getSec() {
+      return sec_;
+    }
+
+    // required int32 nsec = 2;
+    public static final int NSEC_FIELD_NUMBER = 2;
+    private int nsec_;
+    /**
+     * <code>required int32 nsec = 2;</code>
+     */
+    public boolean hasNsec() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>required int32 nsec = 2;</code>
+     */
+    public int getNsec() {
+      return nsec_;
+    }
+
+    private void initFields() {
+      sec_ = 0;
+      nsec_ = 0;
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasSec()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasNsec()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeInt32(1, sec_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeInt32(2, nsec_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(1, sec_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(2, nsec_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static gazebo.msgs.GzTime.Time parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static gazebo.msgs.GzTime.Time parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static gazebo.msgs.GzTime.Time parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static gazebo.msgs.GzTime.Time parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static gazebo.msgs.GzTime.Time parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static gazebo.msgs.GzTime.Time parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static gazebo.msgs.GzTime.Time parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static gazebo.msgs.GzTime.Time parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static gazebo.msgs.GzTime.Time parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static gazebo.msgs.GzTime.Time parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(gazebo.msgs.GzTime.Time prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code gazebo.msgs.Time}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements gazebo.msgs.GzTime.TimeOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return gazebo.msgs.GzTime.internal_static_gazebo_msgs_Time_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return gazebo.msgs.GzTime.internal_static_gazebo_msgs_Time_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                gazebo.msgs.GzTime.Time.class, gazebo.msgs.GzTime.Time.Builder.class);
+      }
+
+      // Construct using gazebo.msgs.GzTime.Time.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        sec_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000001);
+        nsec_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000002);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return gazebo.msgs.GzTime.internal_static_gazebo_msgs_Time_descriptor;
+      }
+
+      public gazebo.msgs.GzTime.Time getDefaultInstanceForType() {
+        return gazebo.msgs.GzTime.Time.getDefaultInstance();
+      }
+
+      public gazebo.msgs.GzTime.Time build() {
+        gazebo.msgs.GzTime.Time result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public gazebo.msgs.GzTime.Time buildPartial() {
+        gazebo.msgs.GzTime.Time result = new gazebo.msgs.GzTime.Time(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.sec_ = sec_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.nsec_ = nsec_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof gazebo.msgs.GzTime.Time) {
+          return mergeFrom((gazebo.msgs.GzTime.Time)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(gazebo.msgs.GzTime.Time other) {
+        if (other == gazebo.msgs.GzTime.Time.getDefaultInstance()) return this;
+        if (other.hasSec()) {
+          setSec(other.getSec());
+        }
+        if (other.hasNsec()) {
+          setNsec(other.getNsec());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasSec()) {
+          
+          return false;
+        }
+        if (!hasNsec()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        gazebo.msgs.GzTime.Time parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (gazebo.msgs.GzTime.Time) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required int32 sec = 1;
+      private int sec_ ;
+      /**
+       * <code>required int32 sec = 1;</code>
+       */
+      public boolean hasSec() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required int32 sec = 1;</code>
+       */
+      public int getSec() {
+        return sec_;
+      }
+      /**
+       * <code>required int32 sec = 1;</code>
+       */
+      public Builder setSec(int value) {
+        bitField0_ |= 0x00000001;
+        sec_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int32 sec = 1;</code>
+       */
+      public Builder clearSec() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        sec_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // required int32 nsec = 2;
+      private int nsec_ ;
+      /**
+       * <code>required int32 nsec = 2;</code>
+       */
+      public boolean hasNsec() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>required int32 nsec = 2;</code>
+       */
+      public int getNsec() {
+        return nsec_;
+      }
+      /**
+       * <code>required int32 nsec = 2;</code>
+       */
+      public Builder setNsec(int value) {
+        bitField0_ |= 0x00000002;
+        nsec_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int32 nsec = 2;</code>
+       */
+      public Builder clearNsec() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        nsec_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:gazebo.msgs.Time)
+    }
+
+    static {
+      defaultInstance = new Time(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:gazebo.msgs.Time)
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_gazebo_msgs_Time_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_gazebo_msgs_Time_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\ntime.proto\022\013gazebo.msgs\"!\n\004Time\022\013\n\003sec" +
+      "\030\001 \002(\005\022\014\n\004nsec\030\002 \002(\005B\010B\006GzTime"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          internal_static_gazebo_msgs_Time_descriptor =
+            getDescriptor().getMessageTypes().get(0);
+          internal_static_gazebo_msgs_Time_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_gazebo_msgs_Time_descriptor,
+              new java.lang.String[] { "Sec", "Nsec", });
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/simulation/JavaGazebo/src/main/java/gazebo/msgs/StringV.java b/simulation/JavaGazebo/src/main/java/gazebo/msgs/StringV.java
new file mode 100644
index 0000000..5945d1e
--- /dev/null
+++ b/simulation/JavaGazebo/src/main/java/gazebo/msgs/StringV.java
@@ -0,0 +1,546 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: string_v.proto
+
+package gazebo.msgs;
+
+public final class StringV {
+  private StringV() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface String_VOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // repeated string data = 1;
+    /**
+     * <code>repeated string data = 1;</code>
+     */
+    java.util.List<java.lang.String>
+    getDataList();
+    /**
+     * <code>repeated string data = 1;</code>
+     */
+    int getDataCount();
+    /**
+     * <code>repeated string data = 1;</code>
+     */
+    java.lang.String getData(int index);
+    /**
+     * <code>repeated string data = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getDataBytes(int index);
+  }
+  /**
+   * Protobuf type {@code gazebo.msgs.String_V}
+   */
+  public static final class String_V extends
+      com.google.protobuf.GeneratedMessage
+      implements String_VOrBuilder {
+    // Use String_V.newBuilder() to construct.
+    private String_V(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private String_V(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final String_V defaultInstance;
+    public static String_V getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public String_V getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private String_V(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+                data_ = new com.google.protobuf.LazyStringArrayList();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              data_.add(input.readBytes());
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+          data_ = new com.google.protobuf.UnmodifiableLazyStringList(data_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return gazebo.msgs.StringV.internal_static_gazebo_msgs_String_V_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return gazebo.msgs.StringV.internal_static_gazebo_msgs_String_V_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              gazebo.msgs.StringV.String_V.class, gazebo.msgs.StringV.String_V.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<String_V> PARSER =
+        new com.google.protobuf.AbstractParser<String_V>() {
+      public String_V parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new String_V(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<String_V> getParserForType() {
+      return PARSER;
+    }
+
+    // repeated string data = 1;
+    public static final int DATA_FIELD_NUMBER = 1;
+    private com.google.protobuf.LazyStringList data_;
+    /**
+     * <code>repeated string data = 1;</code>
+     */
+    public java.util.List<java.lang.String>
+        getDataList() {
+      return data_;
+    }
+    /**
+     * <code>repeated string data = 1;</code>
+     */
+    public int getDataCount() {
+      return data_.size();
+    }
+    /**
+     * <code>repeated string data = 1;</code>
+     */
+    public java.lang.String getData(int index) {
+      return data_.get(index);
+    }
+    /**
+     * <code>repeated string data = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getDataBytes(int index) {
+      return data_.getByteString(index);
+    }
+
+    private void initFields() {
+      data_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      for (int i = 0; i < data_.size(); i++) {
+        output.writeBytes(1, data_.getByteString(i));
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      {
+        int dataSize = 0;
+        for (int i = 0; i < data_.size(); i++) {
+          dataSize += com.google.protobuf.CodedOutputStream
+            .computeBytesSizeNoTag(data_.getByteString(i));
+        }
+        size += dataSize;
+        size += 1 * getDataList().size();
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static gazebo.msgs.StringV.String_V parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static gazebo.msgs.StringV.String_V parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static gazebo.msgs.StringV.String_V parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static gazebo.msgs.StringV.String_V parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static gazebo.msgs.StringV.String_V parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static gazebo.msgs.StringV.String_V parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static gazebo.msgs.StringV.String_V parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static gazebo.msgs.StringV.String_V parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static gazebo.msgs.StringV.String_V parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static gazebo.msgs.StringV.String_V parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(gazebo.msgs.StringV.String_V prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code gazebo.msgs.String_V}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements gazebo.msgs.StringV.String_VOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return gazebo.msgs.StringV.internal_static_gazebo_msgs_String_V_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return gazebo.msgs.StringV.internal_static_gazebo_msgs_String_V_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                gazebo.msgs.StringV.String_V.class, gazebo.msgs.StringV.String_V.Builder.class);
+      }
+
+      // Construct using gazebo.msgs.StringV.String_V.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        data_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return gazebo.msgs.StringV.internal_static_gazebo_msgs_String_V_descriptor;
+      }
+
+      public gazebo.msgs.StringV.String_V getDefaultInstanceForType() {
+        return gazebo.msgs.StringV.String_V.getDefaultInstance();
+      }
+
+      public gazebo.msgs.StringV.String_V build() {
+        gazebo.msgs.StringV.String_V result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public gazebo.msgs.StringV.String_V buildPartial() {
+        gazebo.msgs.StringV.String_V result = new gazebo.msgs.StringV.String_V(this);
+        int from_bitField0_ = bitField0_;
+        if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          data_ = new com.google.protobuf.UnmodifiableLazyStringList(
+              data_);
+          bitField0_ = (bitField0_ & ~0x00000001);
+        }
+        result.data_ = data_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof gazebo.msgs.StringV.String_V) {
+          return mergeFrom((gazebo.msgs.StringV.String_V)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(gazebo.msgs.StringV.String_V other) {
+        if (other == gazebo.msgs.StringV.String_V.getDefaultInstance()) return this;
+        if (!other.data_.isEmpty()) {
+          if (data_.isEmpty()) {
+            data_ = other.data_;
+            bitField0_ = (bitField0_ & ~0x00000001);
+          } else {
+            ensureDataIsMutable();
+            data_.addAll(other.data_);
+          }
+          onChanged();
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        gazebo.msgs.StringV.String_V parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (gazebo.msgs.StringV.String_V) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // repeated string data = 1;
+      private com.google.protobuf.LazyStringList data_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+      private void ensureDataIsMutable() {
+        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+          data_ = new com.google.protobuf.LazyStringArrayList(data_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+      /**
+       * <code>repeated string data = 1;</code>
+       */
+      public java.util.List<java.lang.String>
+          getDataList() {
+        return java.util.Collections.unmodifiableList(data_);
+      }
+      /**
+       * <code>repeated string data = 1;</code>
+       */
+      public int getDataCount() {
+        return data_.size();
+      }
+      /**
+       * <code>repeated string data = 1;</code>
+       */
+      public java.lang.String getData(int index) {
+        return data_.get(index);
+      }
+      /**
+       * <code>repeated string data = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getDataBytes(int index) {
+        return data_.getByteString(index);
+      }
+      /**
+       * <code>repeated string data = 1;</code>
+       */
+      public Builder setData(
+          int index, java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  ensureDataIsMutable();
+        data_.set(index, value);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated string data = 1;</code>
+       */
+      public Builder addData(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  ensureDataIsMutable();
+        data_.add(value);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated string data = 1;</code>
+       */
+      public Builder addAllData(
+          java.lang.Iterable<java.lang.String> values) {
+        ensureDataIsMutable();
+        super.addAll(values, data_);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated string data = 1;</code>
+       */
+      public Builder clearData() {
+        data_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+        bitField0_ = (bitField0_ & ~0x00000001);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated string data = 1;</code>
+       */
+      public Builder addDataBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  ensureDataIsMutable();
+        data_.add(value);
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:gazebo.msgs.String_V)
+    }
+
+    static {
+      defaultInstance = new String_V(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:gazebo.msgs.String_V)
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_gazebo_msgs_String_V_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_gazebo_msgs_String_V_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\016string_v.proto\022\013gazebo.msgs\"\030\n\010String_" +
+      "V\022\014\n\004data\030\001 \003(\t"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          internal_static_gazebo_msgs_String_V_descriptor =
+            getDescriptor().getMessageTypes().get(0);
+          internal_static_gazebo_msgs_String_V_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_gazebo_msgs_String_V_descriptor,
+              new java.lang.String[] { "Data", });
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/Connection.java b/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/Connection.java
new file mode 100644
index 0000000..994c78f
--- /dev/null
+++ b/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/Connection.java
@@ -0,0 +1,159 @@
+package org.gazebosim.transport;
+
+import gazebo.msgs.GzPacket.Packet;
+import gazebo.msgs.GzTime.Time;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.InetAddress;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.logging.Logger;
+import java.util.logging.Level;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.Message;
+
+/**
+ * Manages a Gazebo protocol connection.
+ *
+ * This can connect to either the Gazebo server, or to a data
+ * publisher. Additionally, it can act as the TCP client, or as a
+ * server. In either case, it provides methods to read and write
+ * structured data on the socket.
+ */
+public class Connection {
+	private static int HEADER_SIZE = 8;
+	
+	public String host;
+	public int port;
+	
+	private Socket socket;
+	private ServerSocket ssocket;
+	private InputStream is;
+	private OutputStream os;
+	
+	private static final Logger LOG = Logger.getLogger("Gazebo Transport");
+
+	public void connect(String host, int port) throws UnknownHostException, IOException {
+		this.host = host;
+		this.port = port;
+		socket = new Socket(host, port);
+		is = socket.getInputStream();
+		os = socket.getOutputStream();
+	}
+
+	public void connectAndWait(String host, int port) throws IOException, InterruptedException {
+		this.host = host;
+		this.port = port;
+		while (true) {
+			try {
+				socket = new Socket(host, port);
+				break;
+			} catch (ConnectException ex) {
+				// Retry.
+				LOG.log(Level.WARNING, "Cannot connect, retrying in five seconds.", ex);
+				Thread.sleep(5000);
+			}
+		}
+		is = socket.getInputStream();
+		os = socket.getOutputStream();
+	}
+
+	public void serve(final ServerCallback cb) throws IOException {
+		ssocket = new ServerSocket(0);
+		host = ssocket.getInetAddress().getHostAddress();
+		port = ssocket.getLocalPort();
+
+		//enable user to change master uri via environment variable GAZEBO_MASTER_URI
+		//TODO : allow for automatic guesing of IP. Look at Connection.cc in gazebo for C++ example
+		String user_defined_ip = System.getenv("GAZEBO_IP");
+        if (user_defined_ip != null) {
+          host = InetAddress.getByName(user_defined_ip).getHostAddress();;
+          LOG.warning("Using custom host: "+host);
+        }
+
+		new Thread("Gazebo Server Thread") {
+			@Override
+			public void run() {
+				LOG.config("Listening on "+host+":"+port);
+				while (true) {
+					Connection conn = new Connection();
+					try {
+						conn.socket = ssocket.accept();
+						conn.is = conn.socket.getInputStream();
+						conn.os = conn.socket.getOutputStream();
+						LOG.info("Handling connect from "+conn.socket.getInetAddress());
+						cb.handle(conn);
+					} catch (IOException e) {
+						LOG.log(Level.WARNING, "Cannot handle client", e);
+					}
+				}
+			}
+		}.start();
+	}
+
+	public void close() throws IOException {
+		LOG.info("Closing connection");
+		if (socket != null) {
+			socket.close();
+			socket = null;
+		}
+		if (ssocket != null) {
+			ssocket.close();
+			ssocket = null;
+		}
+	}
+	
+	public byte[] rawRead() throws IOException {
+		synchronized (is) {
+			// Figure out the message size
+			byte[] buff= new byte[HEADER_SIZE];
+			int n = is.read(buff);
+			if (n != HEADER_SIZE) {
+				LOG.severe("Only read "+n+" bytes instead of 8 for header.");
+				return null;
+			}
+			int size = Integer.parseInt(new String(buff), 16);
+		
+			// Read in the actual message
+			buff = new byte[size];
+			n = is.read(buff);
+			if (n != size) {
+				throw new IOException("Failed to read whole message");
+			}
+			
+			return buff;
+		}
+	}
+	
+	public Packet read() throws IOException {
+		byte[] buff = rawRead();
+		if (buff == null) {
+			return null;
+		}
+		return Packet.parseFrom(buff);
+	}
+
+	public void write(Message msg) throws IOException {
+        ByteString data = msg.toByteString();
+        ByteString header = ByteString.copyFromUtf8(String.format("%08X", data.size()));
+        ByteString bytes = header.concat(data);
+
+        synchronized (os) {
+			os.write(bytes.toByteArray());
+		}
+	}
+
+	public void writePacket(String name, Message req) throws IOException {
+		long ms = System.currentTimeMillis();
+		Time t = Time.newBuilder().setSec((int) (ms / 1000)).setNsec((int) ((ms%1000)*1000)).build();
+		Packet pack = Packet.newBuilder().setType(name).setStamp(t)
+							.setSerializedData(req.toByteString()).build();
+		write(pack);
+	}
+
+}
diff --git a/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/Msgs.java b/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/Msgs.java
new file mode 100644
index 0000000..5062408
--- /dev/null
+++ b/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/Msgs.java
@@ -0,0 +1,31 @@
+package org.gazebosim.transport;
+
+import gazebo.msgs.GzBool.Bool;
+import gazebo.msgs.GzFloat64;
+import gazebo.msgs.GzString;
+
+public class Msgs {
+	public static GzString.String String() {
+		return GzString.String.getDefaultInstance();
+	}
+	
+	public static GzString.String String(String s) {
+		return GzString.String.newBuilder().setData(s).build();
+	}
+	
+	public static GzFloat64.Float64 Float64() {
+		return GzFloat64.Float64.getDefaultInstance();
+	}
+	
+	public static GzFloat64.Float64 Float64(double d) {
+		return GzFloat64.Float64.newBuilder().setData(d).build();
+	}
+	
+	public static Bool Bool() {
+		return Bool.getDefaultInstance();
+	}
+	
+	public static Bool Bool(boolean b) {
+		return Bool.newBuilder().setData(b).build();
+	}
+}
diff --git a/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/Node.java b/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/Node.java
new file mode 100644
index 0000000..455d452
--- /dev/null
+++ b/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/Node.java
@@ -0,0 +1,246 @@
+package org.gazebosim.transport;
+
+import gazebo.msgs.GzPacket.Packet;
+import gazebo.msgs.GzPublish.Publish;
+import gazebo.msgs.GzPublishers.Publishers;
+import gazebo.msgs.GzString;
+import gazebo.msgs.GzSubscribe.Subscribe;
+import gazebo.msgs.StringV.String_V;
+
+import java.io.IOException;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Formatter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.google.protobuf.Message;
+
+public class Node implements Runnable, ServerCallback {
+	private final String name;
+	private final Connection master = new Connection();
+	private final Connection server = new Connection();
+	private final List<String> namespaces = new LinkedList<>();
+	private final Map<String, PublisherRecord> publishers = new HashMap<>();
+	@SuppressWarnings("rawtypes")
+	private final Map<String, Subscriber> subscriptions = new HashMap<>();
+	private static final Logger LOG = Logger.getLogger("Gazebo Transport");
+	static {
+		// Get rid of the excess information
+		LOG.setLevel(Level.WARNING);
+		Handler[] handlers = LOG.getParent().getHandlers();
+		if (handlers[0] instanceof ConsoleHandler) {
+			((ConsoleHandler) handlers[0]).setFormatter(new Formatter() {
+				@Override
+				public String format(LogRecord record) {
+					return String.format("%s|%s: %s\n", record.getLevel(), record.getLoggerName(), record.getMessage());
+				}
+			});
+		}
+	}
+
+	public Node(String name) {
+		this.name = name;
+	}
+
+	public void waitForConnection() throws IOException, InterruptedException {
+		//enable user to change master uri via environment variable GAZEBO_MASTER_URI
+		String user_defined_uri = System.getenv("GAZEBO_MASTER_URI");
+		String gazebo_master_uri = "localhost";
+		int port = 11345;
+		if (user_defined_uri != null) {
+			String[] parts = user_defined_uri.split(":");
+			if (parts.length != 2){
+				LOG.severe("invalid GAZEBO_MASTER_URI " + user_defined_uri+ ". URI must be of the form HOSTNAME:PORT");
+				LOG.warning("using default GAZEBO_MASTER_URI=localhost:11345");
+			}
+			else {
+				gazebo_master_uri = parts[0];
+				port = Integer.parseInt(parts[1]);
+			}
+		}
+
+		server.serve(this);
+
+		LOG.info("GAZEBO_MASTER_URI is host=" + gazebo_master_uri + " port="+port);
+
+		master.connectAndWait(gazebo_master_uri, port);
+
+		initializeConnection();
+
+		new Thread(this).start();
+		LOG.info("Serving on: "+server.host+":"+server.port);
+	}
+
+	public synchronized <T extends Message> Publisher<T> advertise(String topic, T defaultMessage) {
+		topic = fixTopic(topic);
+		LOG.info("ADV "+topic);
+		String type = defaultMessage.getDescriptorForType().getFullName();
+		Publisher<T> pub = new Publisher<T>(topic, type, server.host, server.port);
+		publishers.put(topic, pub);
+
+		Publish req = Publish.newBuilder().setTopic(topic).setMsgType(type)
+						.setHost(server.host).setPort(server.port).build();
+		try {
+			master.writePacket("advertise", req);
+		} catch (IOException e) {
+			e.printStackTrace(); // FIXME: Shouldn't happen, should probably complain louder
+		}
+		return pub;
+	}
+
+	public synchronized <T extends Message> Subscriber<T>
+			subscribe(String topic, T defaultMessage, SubscriberCallback<T> cb) {
+		topic = fixTopic(topic);
+		LOG.info("SUB "+topic);
+		if (subscriptions.containsKey(topic)) {
+			throw new RuntimeException("Multiple subscribers for: "+topic);
+		}
+
+		String type = defaultMessage.getDescriptorForType().getFullName();
+		Subscribe req = Subscribe.newBuilder().setTopic(topic).setMsgType(type)
+							.setHost(server.host).setPort(server.port).setLatching(false).build();
+		try {
+			master.writePacket("subscribe", req);
+		} catch (IOException e) {
+			e.printStackTrace(); // FIXME: Shouldn't happen, should probably complain louder
+		}
+
+		Subscriber<T> s = new Subscriber<>(topic, type, cb, defaultMessage,
+				server.host, server.port);
+		subscriptions.put(topic, s);
+		for (PublisherRecord p : publishers.values()) {
+			if (p.getTopic().equals(topic)) {
+				s.connect(p);
+			}
+		}
+		return s;
+	}
+
+	@Override
+	public void run() {
+		try {
+			while (true) {
+				Packet packet = master.read();
+				if (packet == null) {
+					LOG.severe("Received null packet, shutting down connection to master.");
+					master.close();
+					return;
+				}
+				processPacket(packet);
+			}
+		} catch (IOException e ) {
+			LOG.severe("I/O error: " + e);
+			e.printStackTrace(); // FIXME: Log
+		}
+	}
+
+	private synchronized void initializeConnection() throws IOException {
+		Packet initData = master.read();
+		if (!initData.getType().equals("version_init")) {
+			throw new IOException("Expected 'version_init' packet, got '"+initData.getType()+"'.");
+		}
+		GzString.String version = GzString.String.parseFrom(initData.getSerializedData());
+		LOG.info("Version: "+version.getData()); // TODO: Check version
+
+		Packet namespaceData = master.read();
+		String_V ns = String_V.parseFrom(namespaceData.getSerializedData());
+		namespaces.addAll(ns.getDataList());
+		LOG.info(namespaces.toString());
+
+		Packet publisherData = master.read();
+		if (publisherData.getType().equals("publishers_init")) {
+			Publishers pubs = Publishers.parseFrom(publisherData.getSerializedData());
+			for (Publish pub : pubs.getPublisherList()) {
+				PublisherRecord record = new RemotePublisherRecord(pub);
+				publishers.put(record.getTopic(), record);
+			}
+			LOG.info(publishers.toString());
+		} else {
+			LOG.severe("No publisher data received.");
+		}
+	}
+
+	public synchronized void processPacket(Packet packet) throws InvalidProtocolBufferException {
+		if (packet.getType().equals("publisher_add")) {
+			PublisherRecord pub = new RemotePublisherRecord(Publish.parseFrom(packet.getSerializedData()));
+
+			if (pub.getHost().equals(server.host) && pub.getPort() == server.port) {
+				LOG.info("ACK "+pub.getTopic());
+				return; // This is us
+			}
+
+			LOG.info("New Publisher: "+pub.getTopic());
+			LOG.fine("Publisher: "+Publish.parseFrom(packet.getSerializedData()));
+			publishers.put(pub.getTopic(), pub);
+		} else if (packet.getType().equals("publisher_subscribe") ||
+				   packet.getType().equals("publisher_advertise")) {
+			PublisherRecord pub = new RemotePublisherRecord(Publish.parseFrom(packet.getSerializedData()));
+
+			if (pub.getHost().equals(server.host) && pub.getPort() == server.port) {
+				LOG.info("Ignoring subscription request on (local) "+pub.getTopic());
+				return; // This is us
+			}
+
+			LOG.info("PUBSUB found for "+pub.getTopic());
+			LOG.fine("Publisher: "+Publish.parseFrom(packet.getSerializedData()));
+			subscriptions.get(pub.getTopic()).connect(pub);
+		} else if (packet.getType().equals("topic_namespace_add")) {
+			namespaces.add(GzString.String.parseFrom(packet.getSerializedData()).getData());
+			LOG.info("New Namespace: "+namespaces.get(namespaces.size()-1));
+		} else if (packet.getType().equals("unsubscribe")) {
+			Subscribe sub = Subscribe.parseFrom(packet.getSerializedData());
+			LOG.warning("Ignoring unsubscribe: "+sub);
+		} else {
+			LOG.warning("Can't handle "+packet.getType());
+		}
+	}
+
+	@Override
+	/**
+	 * This is called when another node requests subscription to a topic we are publishing
+	 */
+	public void handle(Connection conn) throws IOException {
+		LOG.fine("Handling new connection");
+		Packet msg = conn.read();
+		if (msg == null) {
+			LOG.warning("Read null message.");
+			return;
+		}
+
+		if (msg.getType().equals("sub")) {
+			Subscribe sub = Subscribe.parseFrom(msg.getSerializedData());
+			if (!publishers.containsKey(sub.getTopic())) {
+				LOG.severe("Subscription for unknown topic: "
+						+ sub.getTopic());
+				return;
+			}
+			LOG.fine("New connection for topic="+sub.getTopic());
+
+			PublisherRecord pub = publishers.get(sub.getTopic());
+			if (!pub.getMsgType().equals(sub.getMsgType())) {
+				LOG.severe(String.format("Message type mismatch requested=%d publishing=%s\n",
+										 pub.getMsgType(), sub.getMsgType()));
+				return;
+			}
+
+			LOG.info("CONN " + sub.getTopic());
+			//Tell the publisher that it has recieved a connection from a subscriver
+			pub.connect(conn);
+		} else {
+			LOG.warning("Unknown message type: " + msg.getType());
+		}
+	}
+
+	private String fixTopic(String topic) {
+		return "/gazebo/" + name + "/" + topic;
+	}
+}
diff --git a/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/Publisher.java b/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/Publisher.java
new file mode 100644
index 0000000..ebf9749
--- /dev/null
+++ b/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/Publisher.java
@@ -0,0 +1,112 @@
+package org.gazebosim.transport;
+
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.logging.Logger;
+
+import com.google.protobuf.Message;
+
+public class Publisher<T extends Message> implements PublisherRecord {
+	private String topic, msgType;
+	private String localHost;
+	private int localPort;
+	private List<Connection> listeners;
+	private boolean latching = false;
+	private T lastMsg = null;
+	
+	private static final Logger LOG = Logger.getLogger("Gazebo Transport");
+	
+	public Publisher(String topic, String msgType, String localHost, int localPort) {
+		this.topic = topic;
+		this.msgType = msgType;
+		this.localHost = localHost;
+		this.localPort = localPort;
+		listeners = new LinkedList<>();
+	}
+
+	public synchronized void publish(T msg) {
+		lastMsg = msg;
+		List<Connection> toRemove = new LinkedList<>();
+		for (Connection listener : listeners) {
+			try {
+				listener.write(msg);
+			} catch (IOException e) {
+				toRemove.add(listener);
+			}
+		}
+		for (Connection listener : toRemove) {
+			LOG.info("Removing listener from topic="+topic);
+			try {
+				listener.close();
+			} catch (IOException e1) { /* Closing failed, probably not a big deal. */}
+			listeners.remove(listener);
+		}
+	}
+
+	@Override
+	public String getTopic() {
+		return topic;
+	}
+
+	@Override
+	public String getHost() {
+		return localHost;
+	}
+
+	@Override
+	public int getPort() {
+		return localPort;
+	}
+
+	@Override
+	public String getMsgType() {
+		return msgType;
+	}
+
+	@Override
+	/**
+	 * This function is called when another topic requests a subscription to a topic I am publishing
+	 * Called in Node.java in the handle() function
+	 */
+	public synchronized void connect(Connection conn) {
+		LOG.fine("Handling subscriber connection for topic: "+topic);
+		if (latching && lastMsg != null) {
+			try {
+				conn.write(lastMsg);
+			} catch (IOException e) {
+				LOG.warning("Writing latched message failed on topic="+topic);
+				try {
+					conn.close();
+				} catch (IOException e1) { /* Closing failed, probably not a big deal. */}
+				return;
+			}
+		}
+		listeners.add(conn);
+		this.notifyAll();
+	}
+
+	public synchronized void waitForConnection() throws InterruptedException {
+		while (this.listeners.isEmpty()) {
+			this.wait();
+		}
+	}
+
+	public synchronized boolean waitForConnection(long timeout_millis) throws InterruptedException {
+		long start = System.currentTimeMillis();
+
+		while (this.listeners.isEmpty()) {
+			long remain = timeout_millis - (System.currentTimeMillis() - start);
+			if (remain <= 0) {
+				break;
+			}
+			this.wait(remain);
+		}
+
+		return !this.listeners.isEmpty();
+	}
+
+	public void setLatchMode(boolean b) {
+		latching = b;
+	}
+}
diff --git a/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/PublisherRecord.java b/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/PublisherRecord.java
new file mode 100644
index 0000000..90ab604
--- /dev/null
+++ b/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/PublisherRecord.java
@@ -0,0 +1,9 @@
+package org.gazebosim.transport;
+
+public interface PublisherRecord {
+	String getTopic();
+	String getHost();
+	int getPort();
+	String getMsgType();
+	void connect(Connection conn);
+}
diff --git a/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/RemotePublisherRecord.java b/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/RemotePublisherRecord.java
new file mode 100644
index 0000000..83d290e
--- /dev/null
+++ b/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/RemotePublisherRecord.java
@@ -0,0 +1,40 @@
+package org.gazebosim.transport;
+
+import gazebo.msgs.GzPublish.Publish;
+
+public class RemotePublisherRecord implements PublisherRecord {
+	private Publish pub;
+
+	public RemotePublisherRecord(Publish pub) {
+		this.pub = pub;
+	}
+
+	@Override
+	public String getTopic() {
+		return pub.getTopic();
+	}
+
+	@Override
+	public String getHost() {
+		return pub.getHost();
+	}
+
+	@Override
+	public int getPort() {
+		return pub.getPort();
+	}
+
+	@Override
+	public String getMsgType() {
+		return pub.getMsgType();
+	}
+	
+	public String toString() {
+		return String.format("%s (%s) %s:%s", getTopic(), getMsgType(), getHost(), getPort()); 
+	}
+
+	@Override
+	public void connect(Connection conn) {
+		throw new RuntimeException("Someone thinks we're a remote server, can't connect.");
+	}
+}
diff --git a/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/ServerCallback.java b/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/ServerCallback.java
new file mode 100644
index 0000000..b9a6576
--- /dev/null
+++ b/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/ServerCallback.java
@@ -0,0 +1,7 @@
+package org.gazebosim.transport;
+
+import java.io.IOException;
+
+public interface ServerCallback {
+	void handle(Connection conn) throws IOException;
+}
diff --git a/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/Subscriber.java b/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/Subscriber.java
new file mode 100644
index 0000000..12770ee
--- /dev/null
+++ b/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/Subscriber.java
@@ -0,0 +1,77 @@
+package org.gazebosim.transport;
+
+import gazebo.msgs.GzSubscribe.Subscribe;
+
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.logging.Logger;
+
+import com.google.protobuf.Message;
+import com.google.protobuf.Parser;
+
+public class Subscriber<T extends Message> {
+	private String topic, msgType;
+	private SubscriberCallback<T> cb;
+	private Parser<T> deserializer;
+	@SuppressWarnings("unused")
+	private String localHost;
+	@SuppressWarnings("unused")
+	private int localPort;
+	private List<Connection> connections;
+	private static final Logger LOG = Logger.getLogger("Gazebo Transport");
+
+	@SuppressWarnings("unchecked")
+	public Subscriber(String topic, String msgType, SubscriberCallback<T> cb,
+			T deserializer, String localHost, int localPort) {
+		this.topic = topic;
+		this.msgType = msgType;
+		this.cb = cb;
+		this.deserializer = (Parser<T>) deserializer.getParserForType();
+		this.localHost = localHost;
+		this.localPort = localPort;
+		connections = new LinkedList<>();
+	}
+
+	public void connect(final PublisherRecord pub) {
+		new Thread(new Runnable() {
+			@Override
+			public void run() {
+				handle_connect(pub);
+			}
+		}).start();
+	}
+
+	private void handle_connect(PublisherRecord pub) {
+		LOG.fine(String.format("CONN for %s from %s:%s\n", topic, pub.getHost(),
+									pub.getPort()));
+		Connection conn = new Connection();
+		try {
+			conn.connect(pub.getHost(), pub.getPort());
+			connections.add(conn);
+
+			Subscribe sub = Subscribe.newBuilder().setTopic(topic)
+					.setMsgType(msgType).setHost(pub.getHost())
+					.setPort(pub.getPort()).setLatching(false).build();
+			conn.writePacket("sub", sub);
+
+			while (true) {
+				byte[] data = conn.rawRead();
+				if (data == null) {
+					connections.remove(conn);
+					return;
+				}
+				T msg = deserializer.parseFrom(data);
+				cb.callback(msg);
+			}
+		} catch (IOException e) {
+			// FIXME: Connection lost, let's make sure it's closed and complain.
+			// Hopefully they try to reconnect, maybe we should try to recover better?
+			try {
+				conn.close();
+			} catch (IOException e1) {
+			}
+			e.printStackTrace();
+		}
+	}
+}
diff --git a/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/SubscriberCallback.java b/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/SubscriberCallback.java
new file mode 100644
index 0000000..5ed5269
--- /dev/null
+++ b/simulation/JavaGazebo/src/main/java/org/gazebosim/transport/SubscriberCallback.java
@@ -0,0 +1,5 @@
+package org.gazebosim.transport;
+
+public interface SubscriberCallback<T> {
+	void callback(T msg);
+}
