diff --git a/ros_foxglove_msgs/ros1/CameraCalibration.msg b/ros_foxglove_msgs/ros1/CameraCalibration.msg
index eed8d50..fad3d78 100644
--- a/ros_foxglove_msgs/ros1/CameraCalibration.msg
+++ b/ros_foxglove_msgs/ros1/CameraCalibration.msg
@@ -6,6 +6,9 @@
# Timestamp of calibration data
time timestamp
+# Frame of reference for the camera. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image.
+string frame_id
+
# Image width
uint32 width
diff --git a/ros_foxglove_msgs/ros1/CompressedImage.msg b/ros_foxglove_msgs/ros1/CompressedImage.msg
index f19cc78..f049b77 100644
--- a/ros_foxglove_msgs/ros1/CompressedImage.msg
+++ b/ros_foxglove_msgs/ros1/CompressedImage.msg
@@ -6,6 +6,9 @@
# Timestamp of image
time timestamp
+# Frame of reference for the image. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image.
+string frame_id
+
# Compressed image data
uint8[] data
diff --git a/ros_foxglove_msgs/ros1/RawImage.msg b/ros_foxglove_msgs/ros1/RawImage.msg
index 7a85e17..64b86ae 100644
--- a/ros_foxglove_msgs/ros1/RawImage.msg
+++ b/ros_foxglove_msgs/ros1/RawImage.msg
@@ -6,6 +6,9 @@
# Timestamp of image
time timestamp
+# Frame of reference for the image. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image.
+string frame_id
+
# Image width
uint32 width
diff --git a/ros_foxglove_msgs/ros2/CameraCalibration.msg b/ros_foxglove_msgs/ros2/CameraCalibration.msg
index 38894b5..8dabdf1 100644
--- a/ros_foxglove_msgs/ros2/CameraCalibration.msg
+++ b/ros_foxglove_msgs/ros2/CameraCalibration.msg
@@ -6,6 +6,9 @@
# Timestamp of calibration data
builtin_interfaces/Time timestamp
+# Frame of reference for the camera. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image.
+string frame_id
+
# Image width
uint32 width
diff --git a/ros_foxglove_msgs/ros2/CompressedImage.msg b/ros_foxglove_msgs/ros2/CompressedImage.msg
index 8c0a6f1..afba021 100644
--- a/ros_foxglove_msgs/ros2/CompressedImage.msg
+++ b/ros_foxglove_msgs/ros2/CompressedImage.msg
@@ -6,6 +6,9 @@
# Timestamp of image
builtin_interfaces/Time timestamp
+# Frame of reference for the image. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image.
+string frame_id
+
# Compressed image data
uint8[] data
diff --git a/ros_foxglove_msgs/ros2/RawImage.msg b/ros_foxglove_msgs/ros2/RawImage.msg
index dd0343a..f6310c1 100644
--- a/ros_foxglove_msgs/ros2/RawImage.msg
+++ b/ros_foxglove_msgs/ros2/RawImage.msg
@@ -6,6 +6,9 @@
# Timestamp of image
builtin_interfaces/Time timestamp
+# Frame of reference for the image. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image.
+string frame_id
+
# Image width
uint32 width
diff --git a/schemas/README.md b/schemas/README.md
index 13ad6d9..a15be44 100644
--- a/schemas/README.md
+++ b/schemas/README.md
@@ -244,6 +244,19 @@ time
Timestamp of calibration data
+
+
+
+frame_id |
+
+
+string
+
+ |
+
+
+Frame of reference for the camera. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image.
+
|
@@ -552,6 +565,19 @@ time
Timestamp of image
+
+
+
+frame_id |
+
+
+string
+
+ |
+
+
+Frame of reference for the image. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image.
+
|
@@ -2066,6 +2092,19 @@ time
Timestamp of image
+
+
+
+frame_id |
+
+
+string
+
+ |
+
+
+Frame of reference for the image. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image.
+
|
diff --git a/schemas/jsonschema/CameraCalibration.json b/schemas/jsonschema/CameraCalibration.json
index 2f52f77..ebef038 100644
--- a/schemas/jsonschema/CameraCalibration.json
+++ b/schemas/jsonschema/CameraCalibration.json
@@ -20,6 +20,10 @@
},
"description": "Timestamp of calibration data"
},
+ "frame_id": {
+ "type": "string",
+ "description": "Frame of reference for the camera. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image."
+ },
"width": {
"type": "integer",
"minimum": 0,
diff --git a/schemas/jsonschema/CompressedImage.json b/schemas/jsonschema/CompressedImage.json
index 09c6a69..cffb874 100644
--- a/schemas/jsonschema/CompressedImage.json
+++ b/schemas/jsonschema/CompressedImage.json
@@ -20,6 +20,10 @@
},
"description": "Timestamp of image"
},
+ "frame_id": {
+ "type": "string",
+ "description": "Frame of reference for the image. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image."
+ },
"data": {
"type": "string",
"contentEncoding": "base64",
diff --git a/schemas/jsonschema/RawImage.json b/schemas/jsonschema/RawImage.json
index f2eab54..03ea61a 100644
--- a/schemas/jsonschema/RawImage.json
+++ b/schemas/jsonschema/RawImage.json
@@ -20,6 +20,10 @@
},
"description": "Timestamp of image"
},
+ "frame_id": {
+ "type": "string",
+ "description": "Frame of reference for the image. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image."
+ },
"width": {
"type": "integer",
"minimum": 0,
diff --git a/schemas/proto/foxglove/CameraCalibration.proto b/schemas/proto/foxglove/CameraCalibration.proto
index bbfdfc8..d257f17 100644
--- a/schemas/proto/foxglove/CameraCalibration.proto
+++ b/schemas/proto/foxglove/CameraCalibration.proto
@@ -11,6 +11,9 @@ message CameraCalibration {
// Timestamp of calibration data
google.protobuf.Timestamp timestamp = 1;
+ // Frame of reference for the camera. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image.
+ string frame_id = 9;
+
// Image width
fixed32 width = 2;
diff --git a/schemas/proto/foxglove/CompressedImage.proto b/schemas/proto/foxglove/CompressedImage.proto
index 10e533b..a30296e 100644
--- a/schemas/proto/foxglove/CompressedImage.proto
+++ b/schemas/proto/foxglove/CompressedImage.proto
@@ -11,6 +11,9 @@ message CompressedImage {
// Timestamp of image
google.protobuf.Timestamp timestamp = 1;
+ // Frame of reference for the image. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image.
+ string frame_id = 4;
+
// Compressed image data
bytes data = 2;
diff --git a/schemas/proto/foxglove/RawImage.proto b/schemas/proto/foxglove/RawImage.proto
index 275d442..40f4b89 100644
--- a/schemas/proto/foxglove/RawImage.proto
+++ b/schemas/proto/foxglove/RawImage.proto
@@ -11,6 +11,9 @@ message RawImage {
// Timestamp of image
google.protobuf.Timestamp timestamp = 1;
+ // Frame of reference for the image. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image.
+ string frame_id = 7;
+
// Image width
fixed32 width = 2;
diff --git a/schemas/ros1/CameraCalibration.msg b/schemas/ros1/CameraCalibration.msg
index eed8d50..fad3d78 100644
--- a/schemas/ros1/CameraCalibration.msg
+++ b/schemas/ros1/CameraCalibration.msg
@@ -6,6 +6,9 @@
# Timestamp of calibration data
time timestamp
+# Frame of reference for the camera. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image.
+string frame_id
+
# Image width
uint32 width
diff --git a/schemas/ros1/CompressedImage.msg b/schemas/ros1/CompressedImage.msg
index f19cc78..f049b77 100644
--- a/schemas/ros1/CompressedImage.msg
+++ b/schemas/ros1/CompressedImage.msg
@@ -6,6 +6,9 @@
# Timestamp of image
time timestamp
+# Frame of reference for the image. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image.
+string frame_id
+
# Compressed image data
uint8[] data
diff --git a/schemas/ros1/RawImage.msg b/schemas/ros1/RawImage.msg
index 7a85e17..64b86ae 100644
--- a/schemas/ros1/RawImage.msg
+++ b/schemas/ros1/RawImage.msg
@@ -6,6 +6,9 @@
# Timestamp of image
time timestamp
+# Frame of reference for the image. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image.
+string frame_id
+
# Image width
uint32 width
diff --git a/schemas/ros2/CameraCalibration.msg b/schemas/ros2/CameraCalibration.msg
index 38894b5..8dabdf1 100644
--- a/schemas/ros2/CameraCalibration.msg
+++ b/schemas/ros2/CameraCalibration.msg
@@ -6,6 +6,9 @@
# Timestamp of calibration data
builtin_interfaces/Time timestamp
+# Frame of reference for the camera. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image.
+string frame_id
+
# Image width
uint32 width
diff --git a/schemas/ros2/CompressedImage.msg b/schemas/ros2/CompressedImage.msg
index 8c0a6f1..afba021 100644
--- a/schemas/ros2/CompressedImage.msg
+++ b/schemas/ros2/CompressedImage.msg
@@ -6,6 +6,9 @@
# Timestamp of image
builtin_interfaces/Time timestamp
+# Frame of reference for the image. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image.
+string frame_id
+
# Compressed image data
uint8[] data
diff --git a/schemas/ros2/RawImage.msg b/schemas/ros2/RawImage.msg
index dd0343a..f6310c1 100644
--- a/schemas/ros2/RawImage.msg
+++ b/schemas/ros2/RawImage.msg
@@ -6,6 +6,9 @@
# Timestamp of image
builtin_interfaces/Time timestamp
+# Frame of reference for the image. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image.
+string frame_id
+
# Image width
uint32 width
diff --git a/schemas/typescript/CameraCalibration.ts b/schemas/typescript/CameraCalibration.ts
index 519c11c..d70509d 100644
--- a/schemas/typescript/CameraCalibration.ts
+++ b/schemas/typescript/CameraCalibration.ts
@@ -7,6 +7,9 @@ export type CameraCalibration = {
/** Timestamp of calibration data */
timestamp: Time;
+ /** Frame of reference for the camera. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image. */
+ frame_id: string;
+
/** Image width */
width: number;
diff --git a/schemas/typescript/CompressedImage.ts b/schemas/typescript/CompressedImage.ts
index f23d91b..cf3084b 100644
--- a/schemas/typescript/CompressedImage.ts
+++ b/schemas/typescript/CompressedImage.ts
@@ -7,6 +7,9 @@ export type CompressedImage = {
/** Timestamp of image */
timestamp: Time;
+ /** Frame of reference for the image. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image. */
+ frame_id: string;
+
/** Compressed image data */
data: Uint8Array;
diff --git a/schemas/typescript/RawImage.ts b/schemas/typescript/RawImage.ts
index e50350a..690fcce 100644
--- a/schemas/typescript/RawImage.ts
+++ b/schemas/typescript/RawImage.ts
@@ -7,6 +7,9 @@ export type RawImage = {
/** Timestamp of image */
timestamp: Time;
+ /** Frame of reference for the image. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image. */
+ frame_id: string;
+
/** Image width */
width: number;
diff --git a/src/generateProto.test.ts b/src/generateProto.test.ts
index 58fbc4e..99b7b78 100644
--- a/src/generateProto.test.ts
+++ b/src/generateProto.test.ts
@@ -37,67 +37,67 @@ describe("generateProto", () => {
bool field_boolean = 3;
// bytes field
- bytes field_bytes = 4;
+ bytes field_bytes = 5;
// float64 field
- double field_float64 = 5;
+ double field_float64 = 6;
// uint32 field
- fixed32 field_uint32 = 6;
+ fixed32 field_uint32 = 7;
// string field
- string field_string = 7;
+ string field_string = 8;
// duration array field
- repeated google.protobuf.Duration field_duration_array = 8;
+ repeated google.protobuf.Duration field_duration_array = 9;
// time array field
- repeated google.protobuf.Timestamp field_time_array = 9;
+ repeated google.protobuf.Timestamp field_time_array = 10;
// boolean array field
- repeated bool field_boolean_array = 10;
+ repeated bool field_boolean_array = 11;
// bytes array field
- repeated bytes field_bytes_array = 11;
+ repeated bytes field_bytes_array = 12;
// float64 array field
- repeated double field_float64_array = 12;
+ repeated double field_float64_array = 13;
// uint32 array field
- repeated fixed32 field_uint32_array = 13;
+ repeated fixed32 field_uint32_array = 14;
// string array field
- repeated string field_string_array = 14;
+ repeated string field_string_array = 15;
// duration fixed-length array field
- repeated google.protobuf.Duration field_duration_fixed_array = 15; // length 3
+ repeated google.protobuf.Duration field_duration_fixed_array = 16; // length 3
// time fixed-length array field
- repeated google.protobuf.Timestamp field_time_fixed_array = 16; // length 3
+ repeated google.protobuf.Timestamp field_time_fixed_array = 17; // length 3
// boolean fixed-length array field
- repeated bool field_boolean_fixed_array = 17; // length 3
+ repeated bool field_boolean_fixed_array = 18; // length 3
// bytes fixed-length array field
- repeated bytes field_bytes_fixed_array = 18; // length 3
+ repeated bytes field_bytes_fixed_array = 19; // length 3
// float64 fixed-length array field
- repeated double field_float64_fixed_array = 19; // length 3
+ repeated double field_float64_fixed_array = 20; // length 3
// uint32 fixed-length array field
- repeated fixed32 field_uint32_fixed_array = 20; // length 3
+ repeated fixed32 field_uint32_fixed_array = 21; // length 3
// string fixed-length array field
- repeated string field_string_fixed_array = 21; // length 3
+ repeated string field_string_fixed_array = 22; // length 3
// An enum field
- ExampleProtoEnum field_enum = 22;
+ ExampleProtoEnum field_enum = 23;
// An enum array field
- repeated ExampleProtoEnum field_enum_array = 23;
+ repeated ExampleProtoEnum field_enum_array = 24;
// A nested field
- foxglove.NestedMessage field_nested = 24;
+ foxglove.NestedMessage field_nested = 25;
// A nested array field
// With
@@ -105,7 +105,7 @@ describe("generateProto", () => {
// very
// long
// description
- repeated foxglove.NestedMessage field_nested_array = 25;
+ repeated foxglove.NestedMessage field_nested_array = 4;
}
"
`);
diff --git a/src/generateProto.ts b/src/generateProto.ts
index cf09810..5cf6680 100644
--- a/src/generateProto.ts
+++ b/src/generateProto.ts
@@ -1,4 +1,9 @@
-import { FoxgloveEnumSchema, FoxgloveMessageSchema, FoxglovePrimitive } from "./types";
+import {
+ FoxgloveEnumSchema,
+ FoxgloveMessageField,
+ FoxgloveMessageSchema,
+ FoxglovePrimitive,
+} from "./types";
function primitiveToProto(type: Exclude) {
switch (type) {
@@ -35,9 +40,33 @@ export function generateProto(
);
}
- let fieldNumber = 1;
+ const explicitFieldNumbers = new Set();
+ for (const field of schema.fields) {
+ if (field.protobufFieldNumber != undefined) {
+ if (explicitFieldNumbers.has(field.protobufFieldNumber)) {
+ throw new Error(
+ `More than one field with protobufFieldNumber ${field.protobufFieldNumber}`,
+ );
+ }
+ explicitFieldNumbers.add(field.protobufFieldNumber);
+ }
+ }
+
+ let nextFieldNumber = 1;
+ const numberedFields = schema.fields.map(
+ (field): FoxgloveMessageField & { protobufFieldNumber: number } => {
+ if (field.protobufFieldNumber != undefined) {
+ return { ...field, protobufFieldNumber: field.protobufFieldNumber };
+ }
+ while (explicitFieldNumbers.has(nextFieldNumber)) {
+ ++nextFieldNumber;
+ }
+ return { ...field, protobufFieldNumber: nextFieldNumber++ };
+ },
+ );
+
const imports = new Set();
- const fields = schema.fields.map((field) => {
+ const fields = numberedFields.map((field) => {
const lineComments: string[] = [];
const qualifiers: string[] = [];
if (field.array != undefined) {
@@ -70,7 +99,7 @@ export function generateProto(
.trim()
.split("\n")
.map((line) => ` // ${line}\n`)
- .join("")} ${qualifiers.join(" ")} ${field.name} = ${fieldNumber++};${
+ .join("")} ${qualifiers.join(" ")} ${field.name} = ${field.protobufFieldNumber};${
lineComments.length > 0 ? " // " + lineComments.join(", ") : ""
}`;
});
diff --git a/src/schemas.ts b/src/schemas.ts
index 0863c2d..ea9cdbc 100644
--- a/src/schemas.ts
+++ b/src/schemas.ts
@@ -664,6 +664,13 @@ const CameraCalibration: FoxgloveMessageSchema = {
type: { type: "primitive", name: "time" },
description: "Timestamp of calibration data",
},
+ {
+ name: "frame_id",
+ type: { type: "primitive", name: "string" },
+ description:
+ "Frame of reference for the camera. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image.",
+ protobufFieldNumber: 9,
+ },
{
name: "width",
type: { type: "primitive", name: "uint32" },
@@ -754,6 +761,13 @@ const CompressedImage: FoxgloveMessageSchema = {
type: { type: "primitive", name: "time" },
description: "Timestamp of image",
},
+ {
+ name: "frame_id",
+ type: { type: "primitive", name: "string" },
+ description:
+ "Frame of reference for the image. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image.",
+ protobufFieldNumber: 4,
+ },
{
name: "data",
type: { type: "primitive", name: "bytes" },
@@ -777,6 +791,13 @@ const RawImage: FoxgloveMessageSchema = {
type: { type: "primitive", name: "time" },
description: "Timestamp of image",
},
+ {
+ name: "frame_id",
+ type: { type: "primitive", name: "string" },
+ description:
+ "Frame of reference for the image. The origin of the frame is the optical center of the camera. +x points to the right in the image, +y points down, and +z points into the plane of the image.",
+ protobufFieldNumber: 7,
+ },
{
name: "width",
type: { type: "primitive", name: "uint32" },
diff --git a/src/testFixtures.ts b/src/testFixtures.ts
index fc96998..62de11d 100644
--- a/src/testFixtures.ts
+++ b/src/testFixtures.ts
@@ -78,6 +78,7 @@ export const exampleMessage: FoxgloveMessageSchema = {
description: "A nested array field\nWith\na\nvery\nlong\ndescription",
type: { type: "nested", schema: exampleNestedMessage },
array: true,
+ protobufFieldNumber: 4,
},
],
};
diff --git a/src/types.ts b/src/types.ts
index aa35d4d..5f9973c 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -20,21 +20,24 @@ export type FoxgloveEnumSchema = {
}>;
};
+export type FoxgloveMessageField = {
+ name: string;
+ type:
+ | { type: "primitive"; name: FoxglovePrimitive }
+ | { type: "nested"; schema: FoxgloveMessageSchema }
+ | { type: "enum"; enum: FoxgloveEnumSchema };
+ array?: true | number;
+ required?: true;
+ description: string;
+ protobufFieldNumber?: number;
+};
+
export type FoxgloveMessageSchema = {
type: "message";
name: string;
description: string;
rosEquivalent?: keyof typeof import("@foxglove/rosmsg-msgs-common").definitions;
- fields: ReadonlyArray<{
- name: string;
- type:
- | { type: "primitive"; name: FoxglovePrimitive }
- | { type: "nested"; schema: FoxgloveMessageSchema }
- | { type: "enum"; enum: FoxgloveEnumSchema };
- array?: true | number;
- required?: true;
- description: string;
- }>;
+ fields: ReadonlyArray;
};
export type FoxgloveSchema = FoxgloveMessageSchema | FoxgloveEnumSchema;