Basics¶
Project Structure¶
The smallest project contains only two files:
1. main.py
¶
This file logically describes the tasks that the robot must do, and doesn’t deal much with hardware stuff.
Example
You’ve already seen this code in the introduction page.
import cake
import time
robot = cake.Robot()
while True:
robot.wheels.set_speed(2)
time.sleep(5)
robot.wheels.set_speed(-2)
time.sleep(5)
2. props.yaml
¶
This file describes project information, including but not limited to: name, dependencies, and most importantly, hardware.
Note
If you are using the cloud platform (i.e. the website), you don’t have to deal with this file. In that case, the website generates this file behind the scenes, based on the information you enter in the project settings page.
Example
name: An Example Robot Program
pip_requirements:
- numpy
hardware:
camera-1:
type: camera/rgb
location: 10, 0, 5 cm
orientation: front-facing
fov: 60 deg
connection: usb
wheels-1:
type: wheels/ackermann
locations:
front-axis: 3, 0, 0 cm
back-axis: 14, 0, 0 cm
actuated-wheels: back
max-torque: 10 N.cm
max-steering: 20 deg
driver: dca-440
Programming¶
So main.py
contains the main program. What are the rules about it?
As you might have already learned from the example, the main file
should define a class with two methods: init
and loop
.
You might have also guessed what are these methods supposed to do, especially if you’ve
programmed an Arduino before. The init
method should inititate the program. It is called only once,
when the robot boots. After init
finishes, the loop
function is then called again and again indefinitely.
Note
If you are an advanced programmer, you might prefer more sophisticated programming patterns such as multithreaded and async, over the init-loop structure described here. Fortunately, it is totally possible to program the robot in other fashions. However, we prefered not to cover it here in the basics section.
We even provide some useful Python decorators that you can use to make a function trigger upon events like a command from the cloud UI, a sensor threshold pass, a timer, etc.
The code that goes inside these functions is just the old regular Python,
but now you can write import cake
and use the functionalities that it provides.
For example, to start moving forward you can write:
cake.wheels.set_speed(2)
If you want to turn left:
cake.wheels.set_steering_angle(20)
You can also read from sensors:
img = cake.camera.current_image()
And these are just low-level stuff. How about:
target_location = cake.navigation.current_location() + (20, 4)
cake.navigation.go_to(target_location)
In the above code, the robot will move to the specified location, and it will not hit any obstacles in the way!
A set of the features are cloud-based. We may open-source the cloud services in the future, but right now they can only be used if you have a Cake account. For example:
cake.log.config(cloud=True, key="alice/my-blue-robot")
cake.log("Hi!")
To see all the functionalities, libraries, and how to use them, refer to the next section: Full Reference.
Building and Deploying¶
Okay, I’ve created the files. How to make the robot actually run them?
First, cd
to the directory that contains main.py
and props.yaml
. Then run the following command:
cake-bundler .
This will generate a Dockerfile
.
Now you can create a Docker image from it:
docker build --tag=my-cool-robot:v1 .
Note
If you want to perform Docker build on another machine (potentially the target robot), make sure you also copy your project files along with the Dockerfile.
Now you just need to run this Docker image on your robot. In the robot, run:
docker run --rm --privileged my-cool-robot:v1
That’s it! The robot should be moving around already.
Note
With the cloud platform, the program Docker image is transparently built and transfered to the specified target robot. The platform also allows remote monitoring and management of the fleet.
Simulation¶
A simulation build differs from a normal build in that, the docker container doesn’t work with hardware. Instead, it communicates with a separate simulation container. The communication is achieved via DDS on UDP.
In practice, this means that before runnnig the code, you should run a cake simulation container:
docker run --rm -t -p 8080:8080 --name=sim cakerobotics/sim
After running this, you should be able to see the simulation environment at http://localhost:8080/
Then you can run bundler:
cake-bundler --sim .
Build the image:
docker build . --tag=my-cool-robot:v1-sim
Run the container:
docker run --rm --network=container:sim my-cool-robot:v1-sim
Now the robot should be wandering in the simulation world!
Note
You guessed it! The cloud service does that too, with a single click.