Reworked wheels and added first track
This commit is contained in:
		
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@ -44,7 +44,7 @@
 | 
			
		||||
                <max_angle>1.396263</max_angle>
 | 
			
		||||
              </horizontal>
 | 
			
		||||
              <vertical>
 | 
			
		||||
                <samples>128</samples>
 | 
			
		||||
                <samples>32</samples>
 | 
			
		||||
                <resolution>1</resolution>
 | 
			
		||||
                <min_angle>${-10*deg_to_rad}</min_angle>
 | 
			
		||||
                <max_angle>${10*deg_to_rad}</max_angle>
 | 
			
		||||
 | 
			
		||||
@ -131,7 +131,6 @@
 | 
			
		||||
        <geometry>
 | 
			
		||||
          <mesh filename="file://$(find dcaiti_control)/description/assets/ft24_wheel_simplified.dae" />
 | 
			
		||||
        </geometry>
 | 
			
		||||
        <material name="grey" />
 | 
			
		||||
      </visual>
 | 
			
		||||
      <xacro:solid_cylinder_inertial 
 | 
			
		||||
          rpy="0 0 0" xyz="0 0 0"
 | 
			
		||||
@ -296,7 +295,6 @@
 | 
			
		||||
        <geometry>
 | 
			
		||||
          <mesh filename="file://$(find dcaiti_control)/description/assets/ft24_wheel_simplified.dae" />
 | 
			
		||||
        </geometry>
 | 
			
		||||
        <material name="silver" />
 | 
			
		||||
      </visual>
 | 
			
		||||
      <xacro:solid_cylinder_inertial 
 | 
			
		||||
          rpy="0 0 0" xyz="0 0 0"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										6
									
								
								src/dcaiti_control/description/yellow_cone.xacro
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/dcaiti_control/description/yellow_cone.xacro
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<robot xmlns:xacro="http://www.ros.org/wiki/xacro"  name="dcaiti_control">
 | 
			
		||||
 | 
			
		||||
    <model
 | 
			
		||||
 | 
			
		||||
</robot>
 | 
			
		||||
@ -58,6 +58,7 @@ def generate_launch_description():
 | 
			
		||||
        executable='parameter_bridge',
 | 
			
		||||
        arguments=[
 | 
			
		||||
            '/clock@rosgraph_msgs/msg/Clock[ignition.msgs.Clock',
 | 
			
		||||
            '/boxes@vision_msgs/msg/Detection2DArray@ignition.msgs.AnnotatedAxisAligned2DBox_V',
 | 
			
		||||
            '/boxes_image@sensor_msgs/msg/Image@ignition.msgs.Image',
 | 
			
		||||
            '/camera_info@sensor_msgs/msg/CameraInfo@ignition.msgs.CameraInfo',
 | 
			
		||||
            '/lidar@sensor_msgs/msg/LaserScan@ignition.msgs.LaserScan',
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								src/dcaiti_control/track/AU2_skidpad.lyt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/dcaiti_control/track/AU2_skidpad.lyt
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										176
									
								
								src/dcaiti_control/track/readlyt.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								src/dcaiti_control/track/readlyt.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,176 @@
 | 
			
		||||
#!/usr/bin/env python3
 | 
			
		||||
# -*- coding:utf-8 -*-
 | 
			
		||||
"""
 | 
			
		||||
Description: Based on https://www.lfs.net/programmer/lyt
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
from pathlib import Path
 | 
			
		||||
from typing import List, Tuple, Union, cast, Dict
 | 
			
		||||
from struct import Struct
 | 
			
		||||
from enum import IntEnum
 | 
			
		||||
 | 
			
		||||
import numpy as np
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ConeTypes(IntEnum):
 | 
			
		||||
    """
 | 
			
		||||
    Enum for all possible cone types
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    UNKNOWN = 0
 | 
			
		||||
    YELLOW = 1
 | 
			
		||||
    RIGHT = 1
 | 
			
		||||
    BLUE = 2
 | 
			
		||||
    LEFT = 2
 | 
			
		||||
    ORANGE_SMALL = 3
 | 
			
		||||
    START_FINISH_AREA = 3
 | 
			
		||||
    ORANGE_BIG = 4
 | 
			
		||||
    START_FINISH_LINE = 4
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
HEADER_STRUCT = Struct("6sBBhBB")
 | 
			
		||||
BLOCK_STRUCT = Struct("2h4B")
 | 
			
		||||
 | 
			
		||||
LytObjectIndexToConeType: Dict[int, ConeTypes] = {
 | 
			
		||||
    25: ConeTypes.UNKNOWN,
 | 
			
		||||
    29: ConeTypes.YELLOW,
 | 
			
		||||
    30: ConeTypes.YELLOW,
 | 
			
		||||
    23: ConeTypes.BLUE,
 | 
			
		||||
    24: ConeTypes.BLUE,
 | 
			
		||||
    27: ConeTypes.ORANGE_BIG,
 | 
			
		||||
    20: ConeTypes.ORANGE_SMALL,
 | 
			
		||||
}   
 | 
			
		||||
 | 
			
		||||
def split_header_blocks(data: bytes) -> Tuple[bytes, bytes]:
 | 
			
		||||
    """
 | 
			
		||||
    Split the content of the lyt file into header and block. This split is easy because
 | 
			
		||||
    the header has a fixed size
 | 
			
		||||
 | 
			
		||||
    Args:
 | 
			
		||||
        data (bytes): The content of the lyt file
 | 
			
		||||
 | 
			
		||||
    Returns:
 | 
			
		||||
        Tuple[bytes, bytes]: The header and the block
 | 
			
		||||
    """
 | 
			
		||||
    return data[: HEADER_STRUCT.size], data[HEADER_STRUCT.size :]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def verify_lyt_header(header_data: bytes) -> None:
 | 
			
		||||
    """
 | 
			
		||||
    Parse the header and perform some sanity checks suggested by the LFS documentation
 | 
			
		||||
 | 
			
		||||
    Args:
 | 
			
		||||
        header_data (bytes): The header bytes of the `.lyt` file
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    header = cast(
 | 
			
		||||
        Tuple[bytes, int, int, int, int, int], HEADER_STRUCT.unpack(header_data)
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    file_type, version, revision, _, _, _ = header
 | 
			
		||||
    assert file_type == b"LFSLYT"
 | 
			
		||||
    assert version <= 0, version
 | 
			
		||||
    # revision allowed up to 252
 | 
			
		||||
    # https://www.lfs.net/forum/thread/96153-LYT-revision-252-in-W-patch
 | 
			
		||||
    assert revision <= 252, revision
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def extract_cone_lists(blocks_data: bytes) -> List[List[Tuple[float, float]]]:
 | 
			
		||||
    """
 | 
			
		||||
    Extract the cone object positions from the object blocks bytes of a lyt file
 | 
			
		||||
 | 
			
		||||
    Args:
 | 
			
		||||
        blocks_data (bytes): The data in the lyt file that is not the header
 | 
			
		||||
 | 
			
		||||
    Returns:
 | 
			
		||||
        List[List[Tuple[int, int]]]: The cone positions split by cone type
 | 
			
		||||
    """
 | 
			
		||||
    decoded_blocks = BLOCK_STRUCT.iter_unpack(blocks_data)
 | 
			
		||||
    all_cones_per_type: List[List[Tuple[float, float]]] = [[] for _ in ConeTypes]
 | 
			
		||||
 | 
			
		||||
    # cone_info:
 | 
			
		||||
    for cone_info in decoded_blocks:
 | 
			
		||||
        obj_x, obj_y, _, _, lyt_obj_idx, _ = cast(
 | 
			
		||||
            Tuple[int, int, int, int, int, int], cone_info
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            cone_type = LytObjectIndexToConeType[lyt_obj_idx]
 | 
			
		||||
        except KeyError:
 | 
			
		||||
            # not a cone
 | 
			
		||||
            continue
 | 
			
		||||
 | 
			
		||||
        # the stored x,y pos is multiplied by
 | 
			
		||||
        # 16 in the file so we need to convert it back
 | 
			
		||||
        # (and cast to a float by using real div)
 | 
			
		||||
        obj_x_meters = obj_x / 16
 | 
			
		||||
        obj_y_meters = obj_y / 16
 | 
			
		||||
        all_cones_per_type[cone_type].append((obj_x_meters, obj_y_meters))
 | 
			
		||||
    return all_cones_per_type
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def load_lyt_file(filename: Union[Path, str]) -> List[np.ndarray]:
 | 
			
		||||
    """
 | 
			
		||||
    Load a `.lyt` file and return the positions of the cone objects inside it split
 | 
			
		||||
    according to `ConeTypes`
 | 
			
		||||
 | 
			
		||||
    Args:
 | 
			
		||||
        filename (Path): The path to the `.lyt` file
 | 
			
		||||
 | 
			
		||||
    Returns:
 | 
			
		||||
        List[np.ndarray]: A list of 2d np.ndarrays representing the cone positions of
 | 
			
		||||
        for all cone types
 | 
			
		||||
    """
 | 
			
		||||
    if isinstance(filename, str):
 | 
			
		||||
        filename = Path(filename)
 | 
			
		||||
    assert filename.is_file(), filename
 | 
			
		||||
    assert filename.suffix == ".lyt", filename
 | 
			
		||||
    data = filename.read_bytes()
 | 
			
		||||
    header_data, blocks_data = split_header_blocks(data)
 | 
			
		||||
    verify_lyt_header(header_data)
 | 
			
		||||
 | 
			
		||||
    all_cones_per_type = extract_cone_lists(blocks_data)
 | 
			
		||||
 | 
			
		||||
    all_cones_per_type_arrays = [
 | 
			
		||||
        np.array(cone_list) for cone_list in all_cones_per_type
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    return all_cones_per_type_arrays
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def main():
 | 
			
		||||
    # parse arguments
 | 
			
		||||
    import argparse
 | 
			
		||||
    import json
 | 
			
		||||
 | 
			
		||||
    # one argument for the lyt file
 | 
			
		||||
    parser = argparse.ArgumentParser(description="Parse a lyt file")
 | 
			
		||||
    parser.add_argument("lyt_file", type=str, help="The lyt file to parse")
 | 
			
		||||
 | 
			
		||||
    args = parser.parse_args()
 | 
			
		||||
 | 
			
		||||
    # load the lyt file
 | 
			
		||||
    lyt_file = Path(args.lyt_file)
 | 
			
		||||
    cone_positions = [x.reshape(-1,2) for x in load_lyt_file(lyt_file)]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    center = np.mean(cone_positions[ConeTypes.ORANGE_BIG], axis=0)
 | 
			
		||||
 | 
			
		||||
    cone_positions_centered = [x - center for x in cone_positions]
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    cones_dict = {
 | 
			
		||||
        "unknown": cone_positions_centered[ConeTypes.UNKNOWN].tolist(),
 | 
			
		||||
        "yellow": cone_positions_centered[ConeTypes.YELLOW].tolist(),
 | 
			
		||||
        "blue": cone_positions_centered[ConeTypes.BLUE].tolist(),
 | 
			
		||||
        "orange_small": cone_positions_centered[ConeTypes.ORANGE_SMALL].tolist(),
 | 
			
		||||
        "orange_big": cone_positions_centered[ConeTypes.ORANGE_BIG].tolist(),
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    # print the cones as json
 | 
			
		||||
    print(json.dumps(cones_dict, indent=1))
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    main()
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user