{-# LANGUAGE DuplicateRecordFields #-}

module URDF where

import           Linear.V3
import           Shared

data Orientation = Orientation {
                r :: Angle,
                p :: Angle,
                y :: Angle
            };


data Color = Color {
                r :: ColorChannel,
                g :: ColorChannel,
                b :: ColorChannel,
                a :: ColorChannel
            };


newtype Texture = Texture {
                filename :: Filename
            };

data InertiaMatrix = InertiaMatrix {
                ixx :: Inertia,
                ixy :: Inertia,
                ixz :: Inertia,
                iyy :: Inertia,
                iyz :: Inertia,
                izz :: Inertia
            };


data Geometry = Box {
                size :: Length
            } |
            Cylinder {
                radius :: Radius,
                length :: Length
            } |
            Sphere {
                radius :: Radius
            } |
            Mesh {
                filename :: Filename,
                scale    :: Maybe Scale
            };

data PrismaticDynamics = PrismaticDynamics {
                damping  :: Maybe Damping,
                friction :: Maybe Friction
            };

data RevoluteDynamics = RevoluteDynamics {
                damping  :: Maybe RevoluteDamping,
                friction :: Maybe RevoluteFriction
            };

data Origin = Origin {
                xyz :: Maybe Position,
                rpy :: Maybe Orientation
            };

data Material = Material {
                name    :: UrdfName,
                color   :: Maybe Color,
                texture :: Maybe Texture
            };

data Inertial = Inertial {
                mass    :: Mass,
                inertia :: InertiaMatrix,
                origin  :: Maybe Origin
            };

data Visual = Visual {
                v_geometry :: Geometry,
                name       :: Maybe UrdfName,
                origin     :: Maybe Origin,
                material   :: Maybe Material
            };


data Collision = Collision {
                geometry :: Geometry,
                name     :: Maybe UrdfName,
                origin   :: Maybe Origin
            };

data Calibration = Calibration {
                rising  :: Maybe Angle,
                falling :: Maybe Angle
            };


data Limit = Limit {
                effort   :: Effort,
                velocity :: AngularVelocity,
                lower    :: Maybe Angle,
                upper    :: Maybe Angle
            };


data Mimic = Mimic {
                joint      :: UrdfName,
                multiplier :: Maybe Multiplier,
                offset     :: Maybe Offset
            };

data SafetyController = SafetyController {
                k_velocity       :: Scale,
                k_position       :: Maybe Scale,
                soft_lower_limit :: Maybe Angle,
                soft_upper_limit :: Maybe Angle
            };

data JointType = Revolute {
                limit        :: Limit,
                axis         :: Maybe Axis,
                rev_dynamics :: Maybe RevoluteDynamics
            } |
            Continuous {
                axis         :: Maybe Axis,
                rev_dynamics :: Maybe RevoluteDynamics
            } |
            Prismatic {
                axis         :: Maybe Axis,
                limit        :: Limit,
                pri_dynamics :: Maybe PrismaticDynamics
            } |
            Fixed |
            Floating |
            Planar {
                axis              :: Maybe Axis
            };

data Link = Link {
                name      :: UrdfName,
                visuals   :: [Visual],
                inertial  :: Maybe Inertial,
                collision :: [Collision]
            };


data Joint = Joint {
                name              :: UrdfName,
                jtype             :: JointType,
                parent            :: UrdfName,
                child             :: UrdfName,
                origin            :: Maybe Origin,
                calibration       :: Maybe Calibration,
                mimic             :: Maybe Mimic,
                safety_controller :: Maybe SafetyController
            };

data Transmission = Transmission {
		name :: UrdfName,
                ttype :: String,
                joint :: String,
                interface :: String,
                actuator :: String
	    };

data URDF = URDF {
                name   :: UrdfName,
                joints :: [Joint],
                links  :: [Link],
		transmissions :: [Transmission]	
            };

