Skip to content

Commit b06805e

Browse files
docs: synchronize and standardize core and blender docstrings
Signed-off-by: arounamounchili <patouossa.mounchili@gmail.com>
1 parent 4e8bb8c commit b06805e

15 files changed

Lines changed: 117 additions & 34 deletions

File tree

core/src/linkforge_core/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
It can be used standalone or integrated into various platforms (Blender, Unity, Web, etc.).
55
66
Modules:
7-
models: Data structures for robots, links, joints, geometry
7+
models: Data structures for robots, links, joints, geometry, and SRDF
88
physics: Inertia and mass calculations
9-
parsers: URDF and XACRO file parsing
10-
generators: URDF and XACRO file generation
9+
parsers: URDF, XACRO, and SRDF file parsing
10+
generators: URDF, XACRO, and SRDF file generation
1111
"""
1212

1313
from __future__ import annotations

core/src/linkforge_core/generators/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
"""URDF and XACRO generators for converting robot models to file formats."""
1+
"""URDF, XACRO, and SRDF generators for converting robot models to file formats."""
22

33
from .srdf_generator import SRDFGenerator
44
from .urdf_generator import URDFGenerator

core/src/linkforge_core/models/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
"""Core data models for robot descriptions.
22
33
This sub-package defines the foundational data structures that represent
4-
a robot's physical, kinematic, and sensor properties. These models are
5-
designed to be simulator-agnostic and form the central API for all
6-
LinkForge operations.
4+
a robot's physical, kinematic, sensor, and semantic (SRDF) properties.
5+
These models are designed to be simulator-agnostic and form the central API
6+
for all LinkForge operations.
77
"""
88

99
from .gazebo import GazeboElement, GazeboPlugin

core/src/linkforge_core/models/graph.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def __init__(self, links: Iterable[Link], joints: Iterable[Joint]) -> None:
3131
joints: Collection of Joint objects forming the edges of the graph.
3232
3333
Raises:
34-
RobotModelError: If a joint references a link not present in the links collection.
34+
RobotValidationError: If a joint references a link not present in the links collection.
3535
"""
3636
self.link_names = {link.name for link in links}
3737
self.joints = list(joints)
@@ -149,7 +149,7 @@ def get_topological_order(self) -> list[str]:
149149
List of link names
150150
151151
Raises:
152-
RobotModelError: If a cycle is detected
152+
RobotValidationError: If a cycle is detected
153153
"""
154154
if self.has_cycle():
155155
raise RobotValidationError("CyclicGraph", None, "Graph contains cycles")

core/src/linkforge_core/parsers/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
"""URDF/XACRO parsers for importing robot models."""
1+
"""URDF, XACRO, and SRDF parsers for importing robot models."""
22

33
from __future__ import annotations
44

core/src/linkforge_core/parsers/urdf_parser.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -785,7 +785,10 @@ def parse(self, filepath: Path, **_kwargs: Any) -> Robot:
785785
The generic Robot model (Intermediate Representation)
786786
787787
Raises:
788-
RobotParserError: If parsing fails
788+
RobotParserIOError: If file cannot be read or exceeds size limit
789+
XacroDetectedError: If a XACRO file is passed instead of URDF
790+
RobotParserXMLRootError: If root tag is not <robot>
791+
RobotParserUnexpectedError: If XML is malformed or internal error occurs
789792
"""
790793
if not filepath.exists():
791794
raise RobotParserIOError(filepath=filepath, reason="File not found")
@@ -835,7 +838,22 @@ def parse_string(
835838
urdf_directory: Path | None = None,
836839
**_kwargs: Any,
837840
) -> Robot:
838-
"""Parse URDF from string."""
841+
"""Parse URDF from string.
842+
843+
Args:
844+
urdf_string: URDF XML content as string
845+
urdf_directory: Base directory for relative mesh path resolution
846+
**kwargs: Additional parsing options
847+
848+
Returns:
849+
The generic Robot model (Intermediate Representation)
850+
851+
Raises:
852+
RobotParserIOError: If string exceeds size limit
853+
XacroDetectedError: If string contains XACRO markers
854+
RobotParserXMLRootError: If root tag is not <robot>
855+
RobotParserUnexpectedError: If XML parsing fails
856+
"""
839857
string_size = len(urdf_string.encode("utf-8"))
840858
if string_size > self.max_file_size:
841859
raise RobotParserIOError(filepath=Path("string"), reason="URDF string too large")

core/src/linkforge_core/parsers/xacro_parser.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,8 @@ def resolve_file(self, filepath: Path) -> str:
145145
The fully resolved URDF XML as a string.
146146
147147
Raises:
148-
RobotParserError: If resolution fails or circular dependencies are found.
148+
RobotXacroError: If resolution fails or internal error occurs
149+
RobotXacroRecursionError: If circular dependencies are found
149150
"""
150151
# Deeply nested XACRO files can exceed Python's default recursion limit (usually 1000)
151152
# We temporarily boost it to ensure we can handle complex industrial robots
@@ -206,6 +207,9 @@ def resolve_string(self, xml_string: str) -> str:
206207
207208
Returns:
208209
The fully resolved XML as a string.
210+
211+
Raises:
212+
RobotXacroError: If XML is malformed or resolution fails
209213
"""
210214
old_limit = sys.getrecursionlimit()
211215
if old_limit < RECURSION_LIMIT_BOOST:
@@ -233,6 +237,10 @@ def _get_structural_template(self, filepath: Path) -> XacroTemplate:
233237
234238
Returns:
235239
The cached or newly built structural template.
240+
241+
Raises:
242+
RobotXacroRecursionError: If circular includes are detected
243+
RobotXacroError: If XML parsing fails or files cannot be located
236244
"""
237245
filepath = filepath.resolve()
238246
if filepath in TEMPLATE_CACHE:
@@ -336,7 +344,7 @@ def resolve_element(self, element: ET.Element) -> ET.Element:
336344
The resolved XML element or a container.
337345
338346
Raises:
339-
RobotParserError: If maximum recursion depth is exceeded.
347+
RobotXacroRecursionError: If maximum recursion depth is exceeded
340348
"""
341349
self._current_depth += 1
342350
if self._current_depth > self.max_depth:

core/src/linkforge_core/physics/inertia.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ def calculate_inertia(geometry: Geometry, mass: float) -> InertiaTensor:
425425
Inertia tensor about the center of mass
426426
427427
Raises:
428-
RobotModelError: If geometry type is not supported
428+
RobotPhysicsError: If geometry type is not supported
429429
430430
"""
431431
if mass <= 0:

core/src/linkforge_core/utils/xml_utils.py

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,21 @@ def parse_int(
154154
default: int | None = None,
155155
check_name: str | None = None,
156156
) -> int:
157-
"""Parse integer value from XML with comprehensive validation."""
157+
"""Parse integer value from XML with comprehensive validation.
158+
159+
Args:
160+
text: String to parse
161+
attribute_name: Context for error messages
162+
default: Default value if text is None
163+
check_name: Alias for attribute_name for consistent reporting
164+
165+
Returns:
166+
Parsed integer
167+
168+
Raises:
169+
RobotMathError: If input format is invalid or value is out of range
170+
RobotValidationError: If attribute is missing and no default is provided
171+
"""
158172
report_name = check_name or attribute_name
159173

160174
if text is not None and not text.strip():
@@ -178,7 +192,18 @@ def parse_int(
178192

179193

180194
def parse_vector3(text: str) -> Vector3:
181-
"""Parse space-separated vector3 string."""
195+
"""Parse space-separated vector3 string.
196+
197+
Args:
198+
text: Space-separated string (e.g. "1.0 2.0 3.0")
199+
200+
Returns:
201+
Vector3 model
202+
203+
Raises:
204+
RobotValidationError: If vector format is invalid or components are missing
205+
RobotMathError: If component values are invalid
206+
"""
182207
parts = text.strip().split()
183208
if len(parts) != 3:
184209
raise RobotValidationError(check_name="Vector3", value=text, reason="Expected 3 values")
@@ -194,14 +219,36 @@ def parse_vector3(text: str) -> Vector3:
194219

195220

196221
def parse_optional_bool(elem: ET.Element, tag: str, default: str = "false") -> bool | None:
197-
"""Parse optional boolean element."""
222+
"""Parse optional boolean element.
223+
224+
Args:
225+
elem: Parent XML element
226+
tag: Sub-element tag to find
227+
default: Default string value if tag is found but content is empty
228+
229+
Returns:
230+
Boolean value if tag exists, else None
231+
"""
198232
if elem.find(tag) is not None:
199233
return elem.findtext(tag, default).lower() == "true"
200234
return None
201235

202236

203237
def parse_optional_float(elem: ET.Element, tag: str, default: float | None = 0.0) -> float | None:
204-
"""Parse optional float element."""
238+
"""Parse optional float element.
239+
240+
Args:
241+
elem: Parent XML element
242+
tag: Sub-element tag to find
243+
default: Default float value if tag content is missing
244+
245+
Returns:
246+
Parsed float if tag exists, else None
247+
248+
Raises:
249+
RobotMathError: If input value is invalid or out of range
250+
RobotValidationError: If parsing logic fails
251+
"""
205252
if elem.find(tag) is not None:
206253
text = elem.findtext(tag)
207254
return parse_float(text, tag, default=default)

core/src/linkforge_core/validation/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
33
This sub-package provides the logic for ensuring robot models are structurally
44
sound and safe for export. It includes checks for kinematic connectivity,
5-
physics validity, and security validation for external assets.
5+
physics validity, and semantic validation (e.g. SRDF collision matrices),
6+
as well as security validation for external assets.
67
"""
78

89
from __future__ import annotations

0 commit comments

Comments
 (0)