Skip to content

Commit

Permalink
fix: adaptions for v2.1
Browse files Browse the repository at this point in the history
  • Loading branch information
mbeutelspacher committed Sep 23, 2024
1 parent 86f5191 commit 6f177f5
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 19 deletions.
111 changes: 111 additions & 0 deletions test_against_schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import json
import re
import os
import sys
import vda5050_msgs.msg as vda


def dromedary(non_dromedary_string) -> str:
x = camely(non_dromedary_string)
return x[0].lower() + x[1:]


def camely(non_camel_string) -> str:
return "".join(word[0].upper() + word[1:] for word in non_camel_string.split("_"))


def snakey(non_snake_string) -> str:
pattern = re.compile(r"(?<!^)(?=[A-Z])")
return pattern.sub("_", non_snake_string).lower()


def convert_type(ros_type: str) -> str:
if ros_type == "uint32":
return "integer"
if ros_type == "double":
return "number"
if ros_type.startswith("sequence"):
return "array"
if ros_type.startswith("vda5050_msgs"):
return "object"
return ros_type


def inferType(schema_type):
try:
return getattr(vda, camely(schema_type))
except AttributeError:
if schema_type == "information":
return vda.Info
raise KeyError(f"Could not infer type for {schema_type}")


def checkSchemaAgainstType(schema, type, global_definitions):
for field, data_type in type.get_fields_and_field_types().items():
dromedary_field = dromedary(field)
field_description = f"'{dromedary_field}' of ROS message '{type.__name__}'"
if dromedary_field not in schema:
raise KeyError(f"{field_description} not in schema")
schema_type = schema[dromedary_field]["type"]
if isinstance(schema_type, list):
print(f"Skip type checking for '{field_description}' as it is a variant ")
continue
if schema_type != convert_type(data_type):
raise TypeError(
f"{field_description} should have type {schema_type} but has type {convert_type(data_type)}"
)
for field, data in schema.items():
if snakey(field) not in type.get_fields_and_field_types():
raise KeyError(
f"Field '{snakey(field)}' not in ROS message '{type.__name__}'"
)
if data["type"] == "array":
if "$ref" in data["items"]:
key = data["items"]["$ref"].split("/")[-1]
checkSchemaAgainstType(
global_definitions[key]["properties"],
inferType(key),
global_definitions,
)
else:
# if it has a title use title otherwise infer it from field name (removing the plural s)
type_guess = data["items"].get("title", field.rstrip("s"))
checkSchemaAgainstType(
data["items"]["properties"],
inferType(type_guess),
global_definitions,
)
elif data["type"] == "object":
for sub_field, sub_data in data["properties"].items():
if sub_data["type"] == "object":
checkSchemaAgainstType(
sub_data, inferType(sub_data["type"]), global_definitions
)
elif sub_data["type"] == "array":
if sub_data["items"]["type"] == "object":
type_guess = sub_data["items"].get(
"title", sub_field.rstrip("s")
)
checkSchemaAgainstType(
sub_data["items"]["properties"],
inferType(type_guess),
global_definitions,
)


def checkSchemaFile(schema_file, type):
with open(schema_file) as f:
schema = json.load(f)
checkSchemaAgainstType(schema["properties"], type, schema.get("definitions", {}))


if __name__ == "__main__":
folder = sys.argv[1]
for schema_file in os.listdir(folder):
if schema_file == "factsheet.schema":
print("Skip Checking Factsheet for now")
continue
checkSchemaFile(
os.path.join(folder, schema_file),
getattr(vda, camely(os.path.splitext(schema_file)[0])),
)
6 changes: 4 additions & 2 deletions vda5050_msgs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,18 @@ set(msg_files
"msg/BoundingBoxReference.msg"
"msg/Connection.msg"
"msg/ControlPoint.msg"
"msg/Corridor.msg"
"msg/Edge.msg"
"msg/EdgeState.msg"
"msg/Error.msg"
"msg/ErrorReference.msg"
"msg/Header.msg"
"msg/Info.msg"
"msg/InfoReference.msg"
"msg/Header.msg"
"msg/InstantActions.msg"
"msg/Load.msg"
"msg/LoadDimensions.msg"
"msg/Map.msg"
"msg/Node.msg"
"msg/NodePosition.msg"
"msg/NodeState.msg"
Expand All @@ -46,7 +48,7 @@ set(msg_files
)
rosidl_generate_interfaces(${PROJECT_NAME}
${msg_files}
DEPENDENCIES
DEPENDENCIES
std_msgs
builtin_interfaces
)
Expand Down
4 changes: 0 additions & 4 deletions vda5050_msgs/msg/ControlPoint.msg
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,5 @@ float64 x # X coordinate described in the world coordinate system.

float64 y # Y coordinate described in the world coordinate system.

float64 orientation # [rad] Range [-pi...pi] Orientation of the AGV on this position of the curve.
# The orientation is in world coordinates.
# When not defined the orientation of the AGV will be tangential to the curve.

float64 weight # Range [0..infinity) The weight with which this control point pulls on the curve.
# When not defined, the default will be 1.0
7 changes: 7 additions & 0 deletions vda5050_msgs/msg/Corridor.msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
float64 left_width # Defines the width of the corridor in meters to the left related to the trajectory of the vehicle.
float64 right_width # Defines the width of the corridor in meters to the right related to the trajectory of the vehicle.
string corridor_ref_point # Defines whether the boundaries are valid for the kinematic center or the contour of the vehicle.

#Enums for corridor_ref_point
string KINEMATICCENTER="KINEMATICCENTER"
string CONTOUR="CONTOUR"
7 changes: 7 additions & 0 deletions vda5050_msgs/msg/Edge.msg
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ float64 orientation # [rad] Orientation of the AGV on the edge r
# If a trajectory with orientation is defined, follow the trajectories orientation.
# If a trajectory without orientation and the orientation field here is defined,
# apply the orientation to the tangent of the trajectory.
string orientation_type # "GLOBAL"- relative to the global project specific map coordinate system;
# "TANGENTIAL"- tangential to the edge. If not defined, the default value is "TANGENTIAL"

string direction # Sets direction at junctions for line-guided vehicles, to be defined initially
# (vehicle individual) Example: left, right, straight, 433MHz
Expand All @@ -39,10 +41,15 @@ float64 max_rotation_speed # [rad/s] Maximum rotation speed Optional: N
vda5050_msgs/Trajectory trajectory # Trajectory JSON-object for this edge as a NURBS. Defines the curve on which the
# AGV should move between start_node and end_node. Optional: Can be omitted if AGV
# cannot process trajectories or if AGV plans its own trajectory.
vda5050_msgs/Corridor corridor # Definition of boundaries in which a vehicle can deviate from its trajectory, e. g. to avoid obstacles.
float64 length # [m] Length of the path from startNode to endNode. Optional: This value is used
# by lineguided AGVs to decrease their speed before reaching a stop position.

vda5050_msgs/Action[] actions # Array of action_ids to be executed on the edge. An action triggered by an edge will
# only be active for the time that the AGV is traversing the edge which triggered
# the action. When the AGV leaves the edge, the action will stop and the state
# before entering the edge will be restored.

# Enum for orientation_type
string GLOBAL="GLOBAL"
string TANGENTIAL="TANGENTIAL"
5 changes: 3 additions & 2 deletions vda5050_msgs/msg/Error.msg
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ string error_description # Error description
string error_level # Enum {warning, fatal} warning: AGV is ready to start (e.g. maintenance
# cycle expiration warning) fatal: AGV is not in running condition, user
# intervention required (e.g. laser scanner is contaminated)
string error_hint # Hint on how to approach or solve the reported error.

# Enums for error_level
string WARNING="warning"
string FATAL="fatal"
string WARNING="WARNING"
string FATAL="FATAL"
2 changes: 1 addition & 1 deletion vda5050_msgs/msg/InstantActions.msg
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ string manufacturer # Manufacturer of the AGV

string serial_number # Serial Number of the AGV

Action[] instant_actions # List of actions to execute
Action[] actions # List of actions to execute
2 changes: 1 addition & 1 deletion vda5050_msgs/msg/Load.msg
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ vda5050_msgs/BoundingBoxReference bounding_box_reference # Point of reference f

vda5050_msgs/LoadDimensions load_dimensions # Dimensions of the load’s bounding box in meters.

uint32 weight # Absolute weight of the load measured in kg.
float64 weight # Absolute weight of the load measured in kg.
8 changes: 8 additions & 0 deletions vda5050_msgs/msg/Map.msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
string map_id # ID of the map describing a defined area of the vehicle's workspace.
string map_version # Version of the map.
string map_description # Additional information on the map.
string map_status # Information on the status of the map indicating, if a map version is currently used on the vehicle. ENABLED: Indicates this map is currently active / used on the AGV. At most one map with the same mapId can have its status set to ENABLED.<br>DISABLED: Indicates this map version is currently not enabled on the AGV and thus could be enabled or deleted by request.

# Enums for map status
string ENABLED="ENABLED"
string DISABLED="DISABLED"
13 changes: 4 additions & 9 deletions vda5050_msgs/msg/State.msg
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,6 @@ vda5050_msgs/AGVPosition agv_position # Current position of the A

vda5050_msgs/Velocity velocity # AGV's velocity in vehicle coordinates

vda5050_msgs/Trajectory trajectory # The trajectory is to be communicated as a NURBS and is defined in
# chapter 5.1. Optional: AGVs that plan their own path are to
# communicate their path via a trajectory object.

vda5050_msgs/Load[] loads # Loads that are currently handled by the AGV.
# Optional: If AGV cannot determine load state, leave the array out of the state.
# If the AGV can determine the load state, but the array is empty, the AGV is considered unloaded.
Expand All @@ -72,11 +68,10 @@ vda5050_msgs/Error[] errors # Array of errorobjects. Em

vda5050_msgs/SafetyState safety_state # Contains all safetyrelated information.

vda5050_msgs/Info[] informations # Array of info-objects. An empty array indicates that the AGV has no information.
# This should only be used for visualization or debugging – it must not be used for logic in master control
# Changed to information with 2.0


vda5050_msgs/Info[] information # Array of info-objects. An empty array indicates that the AGV has no information.
# This should only be used for visualization or debugging – it must not be used for logic in master control
# Changed to information with 2.0
vda5050_msgs/Map[] maps #Array of map-objects that are currently stored on the vehicle.

# Enums for operatingMode
string AUTOMATIC="AUTOMATIC"
Expand Down

0 comments on commit 6f177f5

Please sign in to comment.