Skip to content

Commit 7cdf728

Browse files
committed
Merge branch 'release/1.4.0'
2 parents 380658c + 1ab53eb commit 7cdf728

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+1776
-9378
lines changed

.github/workflows/ci.yml

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -28,59 +28,69 @@ jobs:
2828
uses: actions/setup-python@v3
2929
with:
3030
python-version: "3.10"
31+
cache: "pip"
3132
- name: Install dependencies
3233
run: |
3334
python -m pip install --upgrade pip
34-
pip install pylint pytest pexpect
35+
pip install pylint
3536
- name: Analysing the code with pylint
3637
run: |
37-
pylint ./addon
38+
pylint addon
39+
pylint -d duplicate-code tests
3840
test:
3941
name: "Test"
4042
needs: build
4143
runs-on: ubuntu-latest
4244
strategy:
45+
fail-fast: false
4346
matrix:
44-
blender_version:
45-
- {dir: "2.90", file: blender-2.90.0-linux64, ext: tar.xz}
46-
- {dir: "3.1", file: blender-3.1.0-linux-x64, ext: tar.xz}
47-
- {dir: "3.2", file: blender-3.2.0-linux-x64, ext: tar.xz}
47+
blender:
48+
- {version: "2.90.0", dir: "2.90"}
49+
- {version: "3.1.0", dir: "3.1"}
50+
- {version: "3.5.0", dir: "3.5"}
4851
steps:
4952
- uses: actions/checkout@v3
50-
- name: Cache Blender
51-
id: cache-blender
52-
uses: actions/cache@v3
53-
with:
54-
path: blender
55-
key: ${{ matrix.blender_version.file }}
56-
- name: Set up Python 3.10
53+
- name: Set up Python
5754
uses: actions/setup-python@v3
5855
with:
5956
python-version: "3.10"
6057
cache: "pip"
61-
cache-dependency-path: requirements-dev.txt
6258
- name: Install dependencies
6359
run: |
6460
sudo apt-get update
6561
sudo apt-get install --no-install-recommends -y unzip wget xz-utils libxi6 libxxf86vm1 libxfixes3 libxrender1 libgl1
66-
python -m pip install --upgrade pip
67-
pip install -r requirements-dev.txt
62+
- name: Restore Blender cache
63+
id: restore-blender-cache
64+
uses: actions/cache/restore@v3
65+
with:
66+
path: blender-${{ matrix.blender.version }}
67+
key: blender-${{ matrix.blender.version }}
6868
- name: Download Blender
69-
if: steps.cache-blender.outputs.cache-hit != 'true'
69+
if: steps.restore-blender-cache.outputs.cache-hit != 'true'
7070
run: |
71-
wget https://download.blender.org/release/Blender${{ matrix.blender_version.dir }}/${{ matrix.blender_version.file }}.${{ matrix.blender_version.ext }}
72-
tar xf ${{ matrix.blender_version.file }}.${{ matrix.blender_version.ext }}
73-
mv ${{ matrix.blender_version.file }} blender
71+
python -m pip install --upgrade pip
72+
pip install blender-downloader
73+
blender-downloader ${{ matrix.blender.version }}
74+
mkdir -p blender-${{ matrix.blender.version }}
75+
tar xf *.tar.xz -C blender-${{ matrix.blender.version }} --strip-components 1
76+
- name: Cache Blender
77+
uses: actions/cache/save@v3
78+
if: steps.restore-blender-cache.outputs.cache-hit != 'true'
79+
with:
80+
path: blender-${{ matrix.blender.version }}
81+
key: blender-${{ matrix.blender.version }}
7482
- name: Create Blender symlink
7583
run: |
76-
sudo ln -s "$(pwd)/blender/blender" /usr/bin/blender
77-
- uses: actions/download-artifact@v3
84+
sudo ln -s "$(pwd)/blender-${{ matrix.blender.version }}/blender" /usr/bin/blender
85+
- name: Download add-on
86+
uses: actions/download-artifact@v3
7887
with:
7988
name: blender_servo_animation_addon.zip
8089
- name: Install add-on
8190
run: |
8291
unzip blender_servo_animation_addon.zip
83-
sudo ln -s "$(pwd)/servo_animation" "$(pwd)/blender/${{ matrix.blender_version.dir }}/scripts/addons/servo_animation"
84-
- name: Run tests with pytest
92+
sudo ln -s "$(pwd)/servo_animation" "$(pwd)/blender-${{ matrix.blender.version }}/${{ matrix.blender.dir }}/scripts/addons/servo_animation"
93+
- name: Run tests inside Blender
8594
run: |
86-
pytest ./tests
95+
./tests/prepare.sh
96+
./tests/test.sh

.gitignore

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
__pycache__
2-
.pytest_cache
32
.vscode/*
43
!.vscode/settings.json
54
*.blend1
6-
tests/tmp/*
7-
!tests/tmp/.gitkeep
5+
tests/results.txt

.pylintrc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ ignore-docstrings=yes
389389
ignore-imports=yes
390390

391391
# Minimum lines number of a similarity.
392-
min-similarity-lines=4
392+
min-similarity-lines=6
393393

394394

395395
[FORMAT]
@@ -522,5 +522,5 @@ valid-metaclass-classmethod-first-arg=cls
522522

523523
# Exceptions that will emit a warning when being caught. Defaults to
524524
# "BaseException, Exception".
525-
overgeneral-exceptions=BaseException,
526-
Exception
525+
overgeneral-exceptions=builtins.BaseException,
526+
builtins.Exception

.vscode/settings.json

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,8 @@
22
"python.linting.enabled": true,
33
"python.linting.pylintEnabled": true,
44
"files.exclude": {
5-
"**/__pycache__": true,
6-
".pytest_cache": true
5+
"**/__pycache__": true
76
},
8-
"python.testing.pytestArgs": [
9-
"tests"
10-
],
11-
"python.testing.unittestEnabled": false,
12-
"python.testing.pytestEnabled": true,
13-
"python.analysis.extraPaths": [
14-
"addon/vendor"
15-
],
167
"blender.addon.loadDirectory": "addon",
178
"blender.addon.moduleName": "servo_animation"
189
}

README.md

Lines changed: 64 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@ Animate your robot or animatronic project and take advantage of Blender's animat
66

77
Also check out the [Blender Servo Animation Arduino Library](https://github.com/timhendriks93/blender-servo-animation-arduino) which is specifically designed to work with this add-on.
88

9+
[![Continuous Integration](https://github.com/timhendriks93/blender-servo-animation/actions/workflows/ci.yml/badge.svg)](https://github.com/timhendriks93/blender-servo-animation/actions/workflows/ci.yml)
10+
911
## Features
1012

1113
- Represent servos through armature bones
1214
- Provide individual `Servo Settings` per bone
1315
- Export an animation as servo position values
14-
- Send position values via a serial connection in real-time
16+
- Send position values via a live mode connection in real-time
1517
- Supporting Inverse Kinematics (IK)
1618

1719
## Installation
@@ -31,18 +33,16 @@ After enabling this Add-on, you should see a `Servo Settings` panel within the `
3133

3234
The underlying principle is that each bone represents a servo motor in the real world. To treat a bone as a servo and activate the `Servo Settings`, enable the checkbox in the panel header.
3335

34-
![Servo Settings panel](screenshots/servo_settings.png)
36+
![Servo Settings panel](images/servo_settings.png)
3537

3638
### Servo Setting Properties
3739

3840
| Property | Description |
3941
| -------- | ----------- |
40-
| Servo ID | Unique number between `0` and `255` to identify this servo (used to send serial commands) |
42+
| Servo ID | Unique number between `0` and `255` to identify this servo (used to send live commands) |
4143
| Position Min | The minimum position value to identify this servo physically stops moving |
4244
| Position Max | Same as `Position Min`, but for the maximum value |
43-
| Set Position Limits | Define a position range to limit the calculated position values according to a specific build |
44-
| Position Limit Start | The minimum position value before the servo is supposed to stop moving within a specific build |
45-
| Position Limit End | Same as `Position Limit Start`, but for the end value |
45+
| Threshold | The maximum value change between frames which is also used for frame jump handling in live mode |
4646
| Neutral Angle | The assumed neutral angle of the servo in degrees (typically half the rotation range) which should be adjusted carefully, since the servo will first move to its 'natural' neutral angle when powered |
4747
| Rotation Range | The manufactured rotation range of the servo in degrees (typically `180`) |
4848
| Euler Rotation Axis | The Euler rotation axis (`X`, `Y` or `Z`) of the bone rotation representing the servo movement |
@@ -59,9 +59,7 @@ It is also possible to use a different kind of value range. For example, to use
5959
6060
### Limiting the value range
6161

62-
The possible range of motion of a servo can be influenced by the specific design of your build. In this case, you can measure and use the position limit values to avoid damage to your setup.
63-
64-
You can also take advantage of Blender's functionality and use [bone constraints](https://docs.blender.org/manual/en/latest/animation/constraints/transform/limit_rotation.html) to already limit the bone rotation according to your build. The more precise your 3D model, the easier it will be to apply constraints and get an accurate preview of the real-world setup.
62+
You can take advantage of Blender's functionality and use [bone constraints](https://docs.blender.org/manual/en/latest/animation/constraints/transform/limit_rotation.html) to already limit the bone rotation according to your build. The more precise your 3D model, the easier it will be to apply constraints and get an accurate preview of the real-world setup.
6563

6664
## Animating the Armature
6765

@@ -75,7 +73,7 @@ Once all servo settings are provided and your animation is ready, you can calcul
7573

7674
Make sure to select the armature containing the bones/servos you want to export and choose the desired format in the `File > Export` menu:
7775

78-
![Servo Settings panel](screenshots/export_menu.png)
76+
![Servo Settings panel](images/export_menu.png)
7977

8078
Alternatively, you can also trigger the export via the timeline menu which is shown in the live mode section below.
8179

@@ -92,33 +90,76 @@ For projects which involve an Arduino compatible microcontroller, the easiest wa
9290

9391
Apart from using the library, it is also possible to write use the exported data in any other kind of program. Especially the JSON format simply represents a list of position values which can be easily parsed via code.
9492

95-
## Live Mode via Serial Connection
93+
## Live Mode
94+
95+
To make the animation process even more intuitive, you can enable the `Live mode` to send position commands via one of the following connection types:
96+
97+
- Serial (UART/USB)
98+
- Web socket (TCP)
99+
100+
This will allow you to control your servos in real-time from within Blender.
101+
102+
### Installing dependencies
103+
104+
After enabling the add-on, you can find the `Servo Positions` popover menu in the header of the timeline. Before using the live mode feature of this add-on, you might have to install some Python dependencies first by pressing the `Install dependencies` button. This will automatically install the required `pip` packages and requires an active internet connection. This process can might take a few seconds depending on the speed of your internet connection.
96105

97-
To make the animation process even more intuitive, you can enable the `Live mode` to send position commands via a serial connection (UART/USB). This will allow you to control your servos in real-time from within Blender.
106+
![Install dependencies button](images/live_mode_dependencies.png)
98107

99-
After enabling the add-on, you can find the `Servo Positions` popover menu in the header of the timeline. Here you can prepare and control the serial connection for the `Live mode`. For additional convenience, you can also find buttons to export the servo positions here.
108+
Afterwards you can prepare and control the connection to be used for the `Live mode` via this menu. For additional convenience, you will also find buttons to export the servo positions here.
100109

101-
![Timeline menu](screenshots/timeline_menu.png)
110+
### Setup a connection
102111

103-
### Setup a Serial Connection
112+
To use the `Live Mode`, you will need to prepare a receiver which will interpret the received commands and use them to control the servo motors accordingly.
104113

105-
To use the `Live Mode`, you will need to prepare a receiver which will interpret the received commands and use them to control the servo motors accordingly. In most cases, the receiver can be considered an Arduino compatible micro controller which is connected via USB to your PC.
114+
In most cases, the receiver can be considered an Arduino compatible micro controller. As a first step, a connection method should be selected via the `Method` dropdown menu.
106115

107-
Once the micro controller is connected, the add-on will try to find and list the respective `Serial Port`. If there are multiple ports and you are unsure which one belongs to your controller, simply compare the list of ports after removing and re-connecting the device.
116+
![Timeline menu](images/timeline_menu.gif)
117+
118+
> Note: starting the `Live Mode` will immediately send the position values for all servos based on the current frame. Make sure that this will not break anything, as the servos will try to move to their new position as fast as possible.
119+
120+
#### Serial connection
121+
122+
Once the micro controller is connected via USB to your PC, the add-on will try to find and list the respective `Serial Port`. If there are multiple ports and you are unsure which one belongs to your controller, simply compare the list of ports after removing and re-connecting the device.
108123

109124
The `Baud Rate` specifies at which rate or speed the data will be transferred. It might need to be adjusted according to the limitations and configurations of your receiver. Keep in mind that a high frame rate combined with a multitude of servos requires a faster data transmission to achieve a smooth movement. As a reference, it was possible to smoothly control `16 servos` at `60 fps` with a baud rate of `115200`.
110125

111126
Once the `Serial Port` and `Baud Rate` have been set, you can click the `Connect` button to establish the serial connection and start the `Live Mode`.
112127

113-
> Note: starting the `Live Mode` will immediately send the position values for all servos based on the current frame. Make sure that this will not break anything, as the servos will try to move to their new position as fast as possible.
128+
#### Web socket connection
129+
130+
It is also possible to send the position values via a TCP-based web socket connection. For example, one could use a WiFi-capable micro controller like the `ESP32` and set up a server to receive commands from Blender. The server should be in the same network as the machine which is running Blender.
131+
132+
After starting such a server, we can enter the respective IP address and port into the `Host` and `Port` input fields.
133+
134+
Clicking the `Connect` button will then establish a tcp connection and start the `Live Mode`.
114135

115136
### Position Jump Handling
116137

117-
Once the connection is established, you can use the timeline to control your servos in a synchronized way. This opens up the possibility to jump to a different frame or position within your animation. To prevent damage due to the servos moving too quickly, you can use `Position Jump Handling` and define a respective `Threshold`. This option is enabled by default.
138+
Once the connection is established, you can use the timeline to control your servos in a synchronized way. This opens up the possibility to jump to a different frame or position within your animation. To prevent damage due to the servos moving too quickly, you can use `Position Jump Handling`. This option is enabled by default.
139+
140+
When clicking somewhere in the timeline and therefore jumping to a different frame, the add-on will first calculate all position value differences. If one of those differences exceeds the `Threshold` value of the respective servos, they will be slowly moved to their new target position. This is done by sending multiple position values in small increments. During this process, the user interface will show a progress indicator.
141+
142+
The speed of this process is also relative to the configured `Threshold` values. A slower and safer movement can be achieved by setting the threshold values as low as possible with the actual animation still able to run properly.
143+
144+
### Servo Calibration
145+
146+
While having an active live mode connection, it is possible to use a servo calibration feature. This will allow you to find the minimum and maximum position value of a servo similar to what you would normally do with a servo tester.
147+
148+
The calibration process can be started by clicking the `Calibrate servo` button within the servo settings panel:
149+
150+
![Calibrate servo button](images/calibrate_servo_button.png)
151+
152+
> Note: the button will only be clickable when there is an active live mode connection.
153+
154+
Clicking this button will bring up a dialog containing a drop down menu to switch between the minimum and maximum position. You can then carefully adjust the position value until the servo stops moving. After doing so for both directions or position types, you can click on `OK` to apply these values as the new min and max position values.
155+
156+
![Calibrate servo dialog](images/calibrate_servo_dialog.png)
157+
158+
> Note: Be careful when changing the position value and toggling the position type as the servo will move at full speed and position jump handling is not being considered.
118159
119-
When clicking somewhere in the timeline and therefore jumping to a different frame, the add-on will first calculate all position value differences. If one of those differences exceeds the `Threshold` value, the servos will be slowly moved to their new target position. This is done by sending multiple position values in small increments. During this process, the user interface will show a progress indicator.
160+
To cancel this process you can either press `ESC` or click outside the dialog box. While position jump handling is not considered during the calibration process it is again considered when cancelling or applying the calibration.
120161

121-
### Serial Protocol
162+
### Command Protocol
122163

123164
The position values are sent based on a specific binary protocol. The receiver has to know about it and be able to interpret the received data in order to successfully trigger the correct servo movement.
124165

@@ -132,6 +173,6 @@ The protocol defines in which order and pattern individual bytes are transferred
132173

133174
The position value is split into 2 bytes (high and low), while the first byte is the most significant one.
134175

135-
### Reading Serial Commands on an Arduino
176+
### Reading Commands on an Arduino
136177

137-
Instead of writing your own logic to read and interpret the serial commands, you can also use the [Blender Servo Animation Arduino Library](https://github.com/timhendriks93/blender-servo-animation-arduino) which has a built-in support for the live mode. Check out the library's repository for more details and some read-to-use examples.
178+
Instead of writing your own logic to read and interpret the live mode commands, you can also use the [Blender Servo Animation Arduino Library](https://github.com/timhendriks93/blender-servo-animation-arduino) which has a built-in support for the live mode. Check out the library's repository for more details and some ready-to-use examples.

addon/__init__.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
# pylint: disable=wrong-import-position,wrong-import-order
2-
from .utils.system import register_vendor_path
3-
4-
register_vendor_path()
5-
61
import bpy
72

83
from .props.bone_property_group import BonePropertyGroup
@@ -11,14 +6,15 @@
116
from .ui.menu_panel import MenuPanel
127
from .ops.json_export import JsonExport
138
from .ops.arduino_export import ArduinoExport
14-
from .ops.start_live_mode import StartLiveMode
159
from .ops.stop_live_mode import StopLiveMode
16-
from .ops.live_mode import LiveMode
10+
from .ops.install_dependencies import InstallDependencies
11+
from .ops.start_live_mode import StartLiveMode
12+
from .ops.calibrate_servo import CalibrateServo
1713

1814
bl_info = {
1915
"name": "Export Animation as Servo Position Values",
2016
"author": "Tim Hendriks",
21-
"version": (1, 3, 0),
17+
"version": (1, 4, 0),
2218
"blender": (2, 90, 0),
2319
"location": "Bone Properties > Servo Settings | File > Import-Export",
2420
"description": "Exports armature animations as servo position values.",
@@ -36,9 +32,10 @@
3632
MenuPanel,
3733
ArduinoExport,
3834
JsonExport,
39-
StartLiveMode,
4035
StopLiveMode,
41-
LiveMode
36+
StartLiveMode,
37+
InstallDependencies,
38+
CalibrateServo
4239
)
4340

4441

0 commit comments

Comments
 (0)