lookout-config 1.3.6__py3-none-any.whl → 1.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,7 +15,9 @@ from lookout_config.types import (
15
15
  Point,
16
16
  Polygon,
17
17
  CameraExtended,
18
+ PositioningSystem,
18
19
  )
20
+ from lookout_config.helpers import YamlDumper
19
21
 
20
22
 
21
23
  LOOKOUT_CONFIG_FILE_NAME = "lookout.yml"
@@ -32,7 +34,7 @@ def get_path():
32
34
 
33
35
 
34
36
  def parse(config: dict[str, Any]) -> LookoutConfig:
35
- return LookoutConfig(**config)
37
+ return LookoutConfig(**config or {})
36
38
 
37
39
 
38
40
  def read() -> LookoutConfig:
@@ -45,10 +47,11 @@ def write(config: LookoutConfig):
45
47
  path = get_path()
46
48
  # Make the parent dir if it doesn't exist
47
49
  os.makedirs(path.parent, exist_ok=True)
50
+ json_string = config.model_dump(mode="json")
48
51
  with open(path, "w") as stream:
49
52
  print(f"Writing: {path}")
50
53
  headers = f"# yaml-language-server: $schema={LOOKOUT_SCHEMA_URL}"
51
- data = "\n".join([headers, yaml.dump(config.model_dump(mode="json"))])
54
+ data = "\n".join([headers, yaml.dump(json_string, Dumper=YamlDumper, sort_keys=True)])
52
55
  stream.write(data)
53
56
 
54
57
 
@@ -67,4 +70,5 @@ __all__ = [
67
70
  "Point",
68
71
  "Polygon",
69
72
  "CameraExtended",
73
+ "PositioningSystem",
70
74
  ]
@@ -1,44 +1,58 @@
1
- from typing import List
2
1
  from lookout_config import LookoutConfig
3
- from greenstream_config import Camera, Offsets, get_cameras_urdf
4
- from gr_urchin import URDF, Joint, Material, Link, xyz_rpy_to_matrix, Visual, Mesh, Geometry
2
+ from greenstream_config import Offsets, get_cameras_urdf
3
+ from gr_urchin import URDF, Joint, Material, Link, xyz_rpy_to_matrix, Visual, Mesh, Geometry, Box
5
4
  from math import radians
6
5
 
7
6
 
7
+ def joint_from_offsets(offsets: Offsets, parent: str, child: str) -> Joint:
8
+ return Joint(
9
+ name=f"{parent}_to_{child}",
10
+ parent=parent,
11
+ child=child,
12
+ joint_type="fixed",
13
+ origin=xyz_rpy_to_matrix(
14
+ [
15
+ offsets.forward or 0.0,
16
+ offsets.left or 0.0,
17
+ offsets.up or 0.0,
18
+ offsets.roll or 0.0,
19
+ offsets.pitch or 0.0,
20
+ offsets.yaw or 0.0,
21
+ ]
22
+ ),
23
+ )
24
+
25
+
8
26
  def generate_urdf(
9
27
  config: LookoutConfig,
10
- cameras: List[Camera],
11
- ins_offset: Offsets,
12
- mesh_path: str,
13
- waterline=0.0, # meters between the waterline and the base_link
14
28
  add_optical_frame: bool = True,
15
29
  ):
16
-
30
+ mesh_path = f"package://lookout_bringup/meshes/{config.offsets.name}"
17
31
  file_path = f"/tmp/vessel_{config.mode.value}.urdf"
18
-
19
- # generate links and joints for all vessel cameras
20
- camera_links, camera_joints = get_cameras_urdf(
21
- cameras, [None], add_optical_frame, namespace=config.namespace_vessel
22
- )
23
- namespace_prefix = f"{config.namespace_vessel}_" if config.namespace_vessel != "" else ""
32
+ camera_links, camera_joints = get_cameras_urdf(config.cameras, [], add_optical_frame) # type: ignore
24
33
 
25
34
  urdf = URDF(
26
35
  name="origins",
27
36
  materials=[
28
- Material(name="grey", color=[0.75, 0.75, 0.75, 1]),
29
- Material(name="blue", color=[0, 0, 1, 1]),
37
+ Material(name="grey", color=[0.75, 0.75, 0.75, 0.6]),
38
+ Material(name="blue", color=[0, 0.12, 0.25, 0.9]),
30
39
  ],
31
40
  links=[
32
- Link(name=f"{namespace_prefix}ins_link", inertial=None, visuals=None, collisions=None),
41
+ Link(name="ins", inertial=None, visuals=None, collisions=None),
33
42
  Link(
34
- name=f"{namespace_prefix}waterline_link",
43
+ name="waterline",
44
+ visuals=[
45
+ Visual(
46
+ name="waterline",
47
+ geometry=Geometry(box=Box([10.0, 10.0, 0.01])),
48
+ material=Material(name="blue"),
49
+ )
50
+ ],
35
51
  inertial=None,
36
- visuals=None,
37
52
  collisions=None,
38
53
  ),
39
54
  Link(
40
- name=f"{namespace_prefix}base_link",
41
- inertial=None,
55
+ name="base_link",
42
56
  visuals=[
43
57
  Visual(
44
58
  name="visual",
@@ -47,43 +61,22 @@ def generate_urdf(
47
61
  ),
48
62
  origin=xyz_rpy_to_matrix([0, 0, 0, radians(-90), 0, 0]),
49
63
  material=Material(name="grey"),
50
- )
64
+ ),
51
65
  ],
66
+ inertial=None,
52
67
  collisions=None,
53
68
  ),
54
69
  *camera_links,
55
70
  ],
56
71
  joints=[
57
- Joint(
58
- name=f"{namespace_prefix}base_to_ins",
59
- parent=f"{namespace_prefix}base_link",
60
- child=f"{namespace_prefix}ins_link",
61
- joint_type="fixed",
62
- origin=xyz_rpy_to_matrix(
63
- [
64
- ins_offset.forward,
65
- ins_offset.left,
66
- ins_offset.up,
67
- ins_offset.roll,
68
- ins_offset.pitch,
69
- ins_offset.yaw,
70
- ]
71
- ),
72
- ),
73
- Joint(
74
- name=f"{namespace_prefix}base_to_{namespace_prefix}waterline",
75
- parent=f"{namespace_prefix}base_link",
76
- child=f"{namespace_prefix}waterline_link",
77
- joint_type="fixed",
78
- origin=xyz_rpy_to_matrix([0, 0, -waterline, 0, 0, 0]),
79
- ),
72
+ joint_from_offsets(config.offsets.baselink_to_ins, "base_link", "ins"),
73
+ joint_from_offsets(config.offsets.baselink_to_waterline, "base_link", "waterline"),
80
74
  *camera_joints,
81
75
  ],
82
76
  )
83
77
 
84
78
  urdf.save(file_path)
85
79
 
86
- # stringify urdf response for robot description
87
80
  with open(file_path) as infp:
88
81
  robot_description = infp.read()
89
82
 
@@ -0,0 +1,18 @@
1
+ import yaml
2
+
3
+
4
+ class YamlDumper(yaml.Dumper):
5
+ """
6
+ A YAML dumpler that show lists on the same line if they do not contain dicts or list
7
+ """
8
+
9
+ def represent_sequence(self, tag, sequence, flow_style=None):
10
+ if isinstance(sequence, list) and all(
11
+ [not isinstance(item, (dict, list)) for item in sequence]
12
+ ):
13
+ flow_style = True
14
+ return super().represent_sequence(tag, sequence, flow_style)
15
+
16
+ def represent_mapping(self, tag, mapping, flow_style=None):
17
+ flow_style = False
18
+ return super().represent_mapping(tag, mapping, flow_style)
@@ -0,0 +1,9 @@
1
+ # Generated by 'python3 -m parameter_persistence.generate_models'
2
+
3
+ from __future__ import annotations
4
+
5
+ from pydantic import BaseModel
6
+
7
+
8
+ class LaunchParameters(BaseModel):
9
+ pass
@@ -442,17 +442,6 @@
442
442
  "title": "Password",
443
443
  "type": "string"
444
444
  },
445
- "joystick_topic": {
446
- "anyOf": [
447
- {
448
- "type": "string"
449
- },
450
- {
451
- "type": "null"
452
- }
453
- ],
454
- "title": "Joystick Topic"
455
- },
456
445
  "ptz_components": {
457
446
  "items": {
458
447
  "$ref": "#/$defs/PTZComponent"
@@ -478,7 +467,6 @@
478
467
  "port",
479
468
  "username",
480
469
  "password",
481
- "joystick_topic",
482
470
  "ptz_components"
483
471
  ],
484
472
  "title": "PTZOnvif",
@@ -517,6 +505,19 @@
517
505
  ],
518
506
  "title": "Polygon",
519
507
  "type": "object"
508
+ },
509
+ "PositioningSystem": {
510
+ "enum": [
511
+ "none",
512
+ "septentrio_ins",
513
+ "advanced_navigation_ins",
514
+ "nmea_2000_sat_compass",
515
+ "nmea_2000_compass",
516
+ "nmea_0183_sat_compass",
517
+ "nmea_0183_compass"
518
+ ],
519
+ "title": "PositioningSystem",
520
+ "type": "string"
520
521
  }
521
522
  },
522
523
  "properties": {
@@ -533,7 +534,7 @@
533
534
  "type": "array"
534
535
  },
535
536
  "namespace_vessel": {
536
- "default": "vessel",
537
+ "default": "vessel_1",
537
538
  "title": "Namespace Vessel",
538
539
  "type": "string"
539
540
  },
@@ -544,7 +545,7 @@
544
545
  },
545
546
  "mode": {
546
547
  "$ref": "#/$defs/Mode",
547
- "default": "stubs"
548
+ "default": "hardware"
548
549
  },
549
550
  "log_level": {
550
551
  "$ref": "#/$defs/LogLevel",
@@ -562,7 +563,7 @@
562
563
  "default": "host"
563
564
  },
564
565
  "gpu": {
565
- "default": false,
566
+ "default": true,
566
567
  "title": "Gpu",
567
568
  "type": "boolean"
568
569
  },
@@ -570,10 +571,27 @@
570
571
  "$ref": "#/$defs/GeolocationMode",
571
572
  "default": "none"
572
573
  },
574
+ "positioning_system": {
575
+ "$ref": "#/$defs/PositioningSystem",
576
+ "default": "none"
577
+ },
578
+ "components": {
579
+ "title": "Components"
580
+ },
573
581
  "prod": {
574
582
  "default": true,
575
583
  "title": "Prod",
576
584
  "type": "boolean"
585
+ },
586
+ "log_directory": {
587
+ "default": "~/greenroom/lookout/logs",
588
+ "title": "Log Directory",
589
+ "type": "string"
590
+ },
591
+ "recording_directory": {
592
+ "default": "~/greenroom/lookout/recordings",
593
+ "title": "Recording Directory",
594
+ "type": "string"
577
595
  }
578
596
  },
579
597
  "title": "LookoutConfig",
lookout_config/types.py CHANGED
@@ -2,11 +2,12 @@
2
2
  # * lookout_interfaces/msg/Config.msg
3
3
  # * lookout_config_manager/mappers.py
4
4
 
5
+ from typing import Optional, Any
5
6
  from enum import Enum
6
7
  from pydantic import BaseModel, field_validator, ConfigDict
7
8
  from pydantic.fields import Field
8
9
 
9
- from greenstream_config.types import Camera
10
+ from greenstream_config.types import Camera, Offsets
10
11
 
11
12
 
12
13
  class Mode(str, Enum):
@@ -19,6 +20,19 @@ class Mode(str, Enum):
19
20
  return self.value
20
21
 
21
22
 
23
+ class PositioningSystem(str, Enum):
24
+ NONE = "none"
25
+ SEPTENTRIO_INS = "septentrio_ins"
26
+ ADNAV_INS = "advanced_navigation_ins"
27
+ NMEA_2000_SAT_COMPASS = "nmea_2000_sat_compass"
28
+ NMEA_2000_COMPASS = "nmea_2000_compass"
29
+ NMEA_0183_SAT_COMPASS = "nmea_0183_sat_compass"
30
+ NMEA_0183_COMPASS = "nmea_0183_compass"
31
+
32
+ def __str__(self):
33
+ return self.value
34
+
35
+
22
36
  class LogLevel(str, Enum):
23
37
  INFO = "info"
24
38
  DEBUG = "debug"
@@ -73,6 +87,12 @@ class CameraExtended(Camera):
73
87
  return ignore_regions
74
88
 
75
89
 
90
+ class VesselOffsets(BaseModel):
91
+ name: str
92
+ baselink_to_ins: Offsets
93
+ baselink_to_waterline: Offsets
94
+
95
+
76
96
  class LookoutConfig(BaseModel):
77
97
  # So enum values are written and read to the yml correctly
78
98
  model_config = ConfigDict(
@@ -82,6 +102,7 @@ class LookoutConfig(BaseModel):
82
102
  LogLevel: lambda v: v.value,
83
103
  Network: lambda v: v.value,
84
104
  GeolocationMode: lambda v: v.value,
105
+ PositioningSystem: lambda v: v.value,
85
106
  },
86
107
  )
87
108
  ros_domain_id: int = 0
@@ -94,6 +115,15 @@ class LookoutConfig(BaseModel):
94
115
  network: Network = Network.HOST
95
116
  gpu: bool = True
96
117
  geolocation_mode: GeolocationMode = GeolocationMode.NONE
118
+ positioning_system: PositioningSystem = PositioningSystem.NONE
119
+ offsets: VesselOffsets = VesselOffsets(
120
+ name="mars.stl",
121
+ baselink_to_ins=Offsets(forward=1.4160, left=0.153, up=0.184),
122
+ baselink_to_waterline=Offsets(
123
+ up=0.3,
124
+ ),
125
+ )
126
+ components: Any = Field(default_factory=dict)
97
127
  prod: bool = True
98
128
  log_directory: str = "~/greenroom/lookout/logs"
99
129
  recording_directory: str = "~/greenroom/lookout/recordings"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lookout_config
3
- Version: 1.3.6
3
+ Version: 1.5.0
4
4
  Summary: A library for reading / writing Lookout config files
5
5
  Home-page: https://github.com/Greenroom-Robotics/lookout
6
6
  Author: Greenroom Robotics
@@ -19,7 +19,7 @@ Requires-Dist: setuptools
19
19
  Requires-Dist: dacite
20
20
  Requires-Dist: PyYAML
21
21
  Requires-Dist: dc-schema
22
- Requires-Dist: greenstream-config==3.5.3
22
+ Requires-Dist: greenstream-config==3.6.2
23
23
  Requires-Dist: gr-urchin
24
24
 
25
25
  # Lookout Config
@@ -0,0 +1,13 @@
1
+ lookout_config/__init__.py,sha256=3D-vqwfTPSuvLVBo4wiYQglpPUm4Fj6Y5MYGIS-e0fI,1738
2
+ lookout_config/generate_schemas.py,sha256=yFNvrZ6gie1tnTM_1TO8_wBa0lFHJAABSI3ZAZqw_Wg,457
3
+ lookout_config/generate_urdf.py,sha256=Emve-fVAjCT89Lz2wyyat5t3Yjxa-SdWPgnT9Pu4KPs,2723
4
+ lookout_config/helpers.py,sha256=3GkGRPDzQ67I5srwcWoI8PI1dgrWvTsUwA8-yRUttLM,603
5
+ lookout_config/launch_parameters.py,sha256=1q49Abigr6WQ3MCJtRcS-h5wQLFNW0yx-zHXOkjn3QM,180
6
+ lookout_config/types.py,sha256=RUc34rXcYp3262n9FZIBjSxft5-688A8ArDJwrqzVIU,3596
7
+ lookout_config/schemas/lookout.schema.json,sha256=wg7hK6vFLk90w4B5cCtOwYYfKMNcggli0S3c1P-vTDs,12750
8
+ lookout_config/test/lookout_config_test.py,sha256=TdOzIEWnyrckhmK7OtShtoWwSAP8QDCiKalNhvScd2U,73
9
+ lookout_config-1.5.0.dist-info/METADATA,sha256=GNSI8f2OpVkYqHENIOOTH7gUwhPpFNqWt6bkbyDFdFA,1436
10
+ lookout_config-1.5.0.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
11
+ lookout_config-1.5.0.dist-info/top_level.txt,sha256=IiZRgJhNrNL87uLMQm9lQRrMCqJnTOl7aYlA7zRSYyg,15
12
+ lookout_config-1.5.0.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
13
+ lookout_config-1.5.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.2.0)
2
+ Generator: setuptools (75.3.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,11 +0,0 @@
1
- lookout_config/__init__.py,sha256=uI1hfXYaCT5lddPGVoIhcKAB523XQodgk-Y2_nVCLcc,1573
2
- lookout_config/generate_schemas.py,sha256=yFNvrZ6gie1tnTM_1TO8_wBa0lFHJAABSI3ZAZqw_Wg,457
3
- lookout_config/generate_urdf.py,sha256=_LaBPlp6BDFP68DMxF-VQS1SDt4iX1pmb0kITQM-I9E,3103
4
- lookout_config/types.py,sha256=FfRVOsXpgX0yufAAS9VQtPdC4fVQ6sRXAUFYUp_Kbhc,2681
5
- lookout_config/schemas/lookout.schema.json,sha256=GSQSlV5TlCznq3uANgdd4a7ogG5cOjOMY0YmuwKuuOI,12245
6
- lookout_config/test/lookout_config_test.py,sha256=TdOzIEWnyrckhmK7OtShtoWwSAP8QDCiKalNhvScd2U,73
7
- lookout_config-1.3.6.dist-info/METADATA,sha256=hB0Hc8iDhqcjlDIP9kYtU-hL1rSoPYsRSYzLoQSGXGw,1436
8
- lookout_config-1.3.6.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
9
- lookout_config-1.3.6.dist-info/top_level.txt,sha256=IiZRgJhNrNL87uLMQm9lQRrMCqJnTOl7aYlA7zRSYyg,15
10
- lookout_config-1.3.6.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
11
- lookout_config-1.3.6.dist-info/RECORD,,