The robot
The .core file declares one robot: a chassis, and the parts placed on it.
Robot diff_bot {
intent "Two-wheel differential base with a rear caster and a top lidar"
Diff_two_caster chassis(ref = "diff_base")
Standard wheel_l(ref = "standard_80", glue = (0, 0.12, -0.02, 0, 1, 0))
Standard wheel_r(ref = "standard_80", glue = (0, -0.12, -0.02, 0, -1, 0))
Caster ball(ref = "caster_ball", glue = (-0.15, 0, -0.035, 0, 0, -1))
Lidar top_lidar(ref = "lidar_ld06", glue = (0, 0, 0.06, 0, 0, 1))
}Each line is a component: its type, its name, and its arguments. intent is an optional sentence for people and for the tools that generate programs.
The chassis
Exactly one component is the chassis. Its type says how the robot drives, and its ref names the chassis part in a library:
Diff_two_caster chassis(ref = "diff_base")The chassis type decides which wheel mounts must be filled, which of them drive, and what the base can do:
| Chassis type | Wheels | Can spin in place | Holonomic |
|---|---|---|---|
Diff_two_caster | two Standard, plus a caster | yes | no |
Diff_drive | four Standard, skid steer | yes | no |
Tracked | two Track, skid steer | yes | no |
Mecanum_four_wheel | four Mecanum | yes | yes |
Omni_drive | four Omni_wheel | yes | yes |
Omni_three_wheel | three Omni_wheel | yes | yes |
Tricycle | one steered driven front wheel, two free rear wheels | no | no |
Ackermann | two steered front wheels, driven or free, and two driven rear wheels | no | no |
Legged | none: it stands on the feet of its legs, its own links or Leg parts placed on it, where their servos hold them | each way its gait turns | to each side its gait moves aside |
A Legged chassis is a part with legs of its own, or a body that carries legs: its file names the gait its walking controller takes and, when its legs are its own, the shapes of its links it stands on (Component library format), and may state that controller, the policy or the gait its legs walk by (Walking controller). A body's legs are Leg parts, each placed by glue where a hip goes; the chassis's gait walks them all (Legs as parts), or a walker trained for that body on those legs, placed so, which the library registers, walks it, whatever the body states (Walkers). The mjcf target writes a legged base by its controller or its walker; the ROS targets do not write one yet.
Drive types says what the compiler emits for each.
Parts and glue
Every other component is a part placed by glue: the point and the direction of a connector, in the chassis frame. The connector is one of the chassis' own, or one of a part already placed: a wheel's glue is the end of its motor's shaft.
Motor motor_l(ref = "gearmotor_37d", glue = (0, 0.1, -0.02, 0, 1, 0))
Standard wheel_l(ref = "standard_80", glue = (0, 0.12, -0.02, 0, 1, 0))
// x y z nx ny nzThe glue must match one connector within 1 mm and 0.01 in direction; one that matches two is an error, and a part that mates onto that part is not placed either. The part's own connector is then mated to it, the two directions facing each other. A seventh number, (x, y, z, nx, ny, nz, roll), turns the part about the direction.
You do not have to look the values up. A glue that matches no connector is reported with the nearest one and the exact glue to write:
error[validation.assembly.glue_on_connector]: the glue of 'wheel_lf' matches no connector of the chassis or of a placed part; the nearest is 'motor_lf.shaft', 0.008 m away with direction cosine 1.00
--> demo.core:17:52
|
17 | Mecanum wheel_lf(ref = "mecanum_black", glue = (0.12, 0.1494, -0.0216, 0, 1, 0))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ matches no connector
|
= help: to mount on 'motor_lf.shaft' write glue = (0.1275, 0.1494, -0.0216, 0, 1, 0)
= help: the free connectors are: chassis.front_mount, motor_lf.shaftA connector holds one part. Every mount the chassis type drives carries one wheel of the right type: on the shaft of a Motor on the mount, which then bounds the wheel's speed and torque, or straight on the mount, driven within no stated limits when no motor is declared for it (a kit whose motors are built into its chassis). A wheel glued straight onto a mount the type does not drive rolls freely, such as a tricycle's rear wheels. See Drive types. A Caster is passive and may sit on any other connector.
Power and command
A power or a command connection is not a place, so it is not a glue but a reference to another component. A MotorDriver names the Battery that feeds it with power, and a Motor names the driver that drives it with command. The battery and the driver are themselves parts glued onto connectors.
Battery pack(ref = "lipo_3s_2200", glue = (-0.1, 0, 0.0344, 0, 0, -1))
MotorDriver driver(ref = "driver_vnh5019", glue = (0, 0.1, 0.0344, 0, 0, -1), power = @core/pack)
Motor motor_l(ref = "gearmotor_37d", glue = (0, 0.1, -0.02, 0, 1, 0), command = @core/driver)A motor like this one has two terminals, which go to one channel of its driver: the channel that commands it also powers it, so it names no power. A motor that carries its driver, a smart servo, is commanded over a bus and powered on a line of its own, and names both: power = @core/pack, command = @core/board.
From what the parts state, the compiler then checks that the driver accepts the pack's voltage full and run down, that this voltage includes the one the motor's ratings hold at, that one channel delivers the current the motor draws stalled, and that the driver has a channel, or speaks the bus, for each motor it commands. Validation lists the rules. A program that names no power and no command still compiles: the rules that would judge them are undecided, without a warning.
Component types
| Kind | Types |
|---|---|
| Motors | Motor: on a drive mount, with the wheel it drives on its shaft; command names its driver |
| Power | Battery: a pack on any free connector. MotorDriver: a board on any free connector; power names its battery |
| Wheels | Standard, Mecanum, Omni_wheel, Caster |
| Legs | Leg: a leg of its own, on servos, ending in the feet it stands on, placed on a Legged chassis that has no legs of its own |
| Tracks | Track: a belt with its sprockets and road wheels as one part, where a Tracked chassis has a wheel's place |
| Sensors | Lidar, Lidar3D, Camera, DepthCamera, RGBD, IMU, Ultrasonic, Range, Bumper |
| Other | Attachment: an arm, a gripper, a tray; it adds mass and shape, and the compiler does nothing else with it |
A part can be used as a type when its library entry lists that type. The vocabulary lists every type with what it means.
Names
Component names are how the task and the evaluation refer to parts: @core/wheel_l. Two components cannot share a name, and the names of the links the targets add are reserved: base_footprint, base_link, <link>_contact_<n> for a ground contact a part declares, and <wheel>_steer for a steered wheel's knuckle.
Next
The world places the robot among obstacles and goals.