CI/CD in Robots Testing
KYIV 2018
Aliaksei Boole, Head of QA
KYIV 2018
Engineer.
Worked in:
I test robots in Rozum
Today we are talking only about software
Today we are talking only about software
KYIV 2018
Safety Board
C/C++
(emergency stop, power control,
LEDS, etc.)
PC with Linux
REST API
Java App
(trajectory builders, inverse kinematics etc.)
UI
x 6
+ wrist
C/С++
(build trajectories, protective systems, etc.)
CAN adapters
CI/CD
Code
Build
Test
Release
Deploy
Operate
Plan
CI
CD
Our CI/CD
Code
Build
Test
Release
Deploy
Operate
Plan
CI
CD
Deploy
Operate
What's the problem?
Deploy
Operate
What solutions do we have?
Deploy
How does it work?
Release
Code
Build
Build
Use firmware collected only from the master
Why?
Build
Build
Build result is DEB packages with dependencies
Unit test
C/C++ should be compatible with x86-64
Why?
Unit test
Our testing stack:
Test
Our best friends:
Test
Docker
Component test
REST API
Java App
(trajectory builders, inverse kinematics etc.)
UI
Tests
Robot simulation
Component test
public interface Robot extends … {
void setPose(...) throws IOException, RobotException;
void setPosition(...) throws IOException, RobotException;
void relax() throws IOException;
void freeze() throws IOException;
void softFreeze() throws IOException;
...
void initializationCompleted() throws IOException;
}
Component test
POINT_1 = pose([20, -100, 80, 20, 70, 0])
…
@fixture(params=[POINT_1, POINT_2, POINT_3])
def position(request):
return request.param
def set_pose(robot, position):
robot.set_pose(pose(position.angles), SPEED)
robot.await_stop()
return robot.get_pose().angles
def test_run_pose(robot, position):
assert_that(set_pose(robot, position),
pose_close_to(position.angles))
Component test
Component test
Our HIL today:
+
Component test
USB-CAN-ETH testing stand
Component test
...
EMCY_FRAME = 0x09
@fixture
def interface_with_emcy():
interface = API.init_interface(ETH_INTERFACE_ADDRESS)
interface.emcy_log_clear()
with SerialInterface(USB_INTERFACE) as usb_interface:
payload = pack("<BBHBBBBBB", EMCY_FRAME, … )
usb_interface.write(payload)
yield interface
interface.emcy_log_clear()
API.deinit_interface(ETH_INTERFACE_ADDRESS)
def test_emcy_code(interface_with_emcy):
emcy = interface_with_emcy.emcy_log_pop()
assert_that(emcy.code, equal_to(EMCY_ERROR_CODE))
Control box testing stand
Simulation is best friend of robotics
Integration test
Stands!
Stands!
Stands!
Stands!
Stands!
+
Servomotors testing stand
Integration test
def test_add_motion_point(servo_in_0_pos_with_interface):
servo, interface = servo_in_0_pos_with_interface
servo.add_motion_point(30, 0, 1000)
interface.start_motion(0)
wait_that(servo.position, position_equals(30))
Integration test
Robot testing stand
Integration test
Test
All these stands are available on CI as gitlab-runners
Test
...
test:
stage: test
tags:
- servo-testbench
...
We have manual tests too :)
Code
Build
Test
Review
&
Code check
Unit Tests
Simulation
Integration
HIL
Build
Manual testing
.gitlab-ci.yml + Multi-project pipelines
KYIV 2018
Questions?
Алексей Буль (Aliaksei Boole)
Email: aliaksei.boole@gmail.com
Slack: qaguild-slack.herokuapp.com
Twitter: @Alex_Koul