Skip to main content

A Python package for static and dynamic rotor balancing calculations based on the methodology described in “Static and Dynamic Balancing using portable measuring equipment” by John Vaughan (Brüel & Kjær Application Note).

Features

  • VibrationVector: Represents unbalance by means of a vector

  • MassVector: Represents a mass placed at an angular position on a rotor

  • StaticBalancing: Single-plane balancing for rotors

  • DynamicBalancing: Two-plane balancing for rotors

  • VibrationExtractor: Extracts vibration vectors from time-domain signals

  • detect_rotation_freq: Detects rotation frequency from a trigger signal

  • Four pluggable extraction methods: IQDemodulation (default), LeastSquaresFit, SynchronousAveraging, FFTExtraction

Installation

Install from PyPI:

pip install pyPRB

Or install from source:

git clone https://github.com/ladisk/pyPRB.git
cd pyPRB
pip install .

For development installation:

pip install -e .[dev]

Quick Start

Static Balancing Example

from pyPRB import VibrationVector, MassVector, StaticBalancing

# Initial measurements
V_0 = VibrationVector(amplitude=3.4, phase=116)  # No trial mass
V_1 = VibrationVector(amplitude=1.8, phase=42)   # With trial mass

# Trial mass: 2.0 g mounted at 0° on the rotor
trial_mass = MassVector(2.0, 0.0)

# Create balancer
balancer = StaticBalancing(V_0, V_1, trial_mass=trial_mass)

# Display measurement table
print(balancer)

# Compute compensation
comp_mass = balancer.compute_compensation()
# Output: Compensation mass: 2.01 g at position -30.8° on the rotor.

Dynamic Balancing Example

from pyPRB import VibrationVector, MassVector, DynamicBalancing

# Initial measurements (no trial masses)
V_1_0 = VibrationVector(7.2, 238)   # Plane 1
V_2_0 = VibrationVector(13.5, 296)  # Plane 2

# With trial mass in Plane 1
V_1_1 = VibrationVector(4.9, 114)   # Plane 1
V_2_1 = VibrationVector(9.2, 347)   # Plane 2

# With trial mass in Plane 2
V_1_2 = VibrationVector(4.0, 79)    # Plane 1
V_2_2 = VibrationVector(12.0, 292)  # Plane 2

# Trial masses: 2.5 g each, mounted at 0° on their respective planes
trial_mass_1 = MassVector(2.5, 0.0)
trial_mass_2 = MassVector(2.5, 0.0)

# Create balancer
balancer = DynamicBalancing(
    V_1_0, V_2_0, V_1_1, V_2_1, V_1_2, V_2_2,
    trial_mass_1=trial_mass_1, trial_mass_2=trial_mass_2
)

# Display measurement table
print(balancer)

# Compute compensations for both planes
comp_mass_1, comp_mass_2 = balancer.compute_compensation()
# Output:
# +---------+---------------------+------------+
# |  Plane  |  Compensation Mass  |  Position  |
# +=========+=====================+============+
# |    1    |       2.95 g        |   50.2°    |
# +---------+---------------------+------------+
# |    2    |       2.84 g        |   -81.9°   |
# +---------+---------------------+------------+

Extracting Vibration Vectors from Measurements

import numpy as np
from pyPRB import (
    VibrationExtractor, detect_rotation_freq,
    MassVector, StaticBalancing,
)

# Synthetic signals (B&K Example 2)
sample_rate = 10000  # Hz
f0_true = 25.0       # rotation frequency (Hz)
duration = 5.0       # s
t = np.arange(0, duration, 1 / sample_rate)
rng = np.random.default_rng(0)

trigger = np.sign(np.sin(2 * np.pi * f0_true * t))
signal_run0 = (3.4 * np.cos(2 * np.pi * f0_true * t + np.deg2rad(116))
               + 0.05 * rng.standard_normal(len(t)))
signal_run1 = (1.8 * np.cos(2 * np.pi * f0_true * t + np.deg2rad(42))
               + 0.05 * rng.standard_normal(len(t)))

# 1. Detect rotation frequency from the trigger signal
f0 = detect_rotation_freq(trigger, sample_rate=sample_rate, max_freq=50.0)

# 2. Create extractor (default method: IQ demodulation)
extractor = VibrationExtractor(sample_rate=sample_rate, rotation_freq=f0)

# 3. Extract vibration vectors for each measurement run
V_0 = extractor.get_vibration_vector(signal_run0, trigger)
V_1 = extractor.get_vibration_vector(signal_run1, trigger)

# 4. Use the vectors for balancing
trial_mass = MassVector(2.0, 0.0)
balancer = StaticBalancing(V_0, V_1, trial_mass=trial_mass)
comp_mass = balancer.compute_compensation()
# Output: Compensation mass: 2.01 g at position -30.8° on the rotor.

Balancing procedure

Static Balancing

For a rotor with unbalance in a single plane:

  1. Measure initial vibration vector V₀

  2. Add known trial mass m and measure resulting vibration V₁

  3. Compute compensation mass with StaticBalancing

Dynamic Balancing

For a rotor requiring two-plane balancing:

  1. Measure initial vibration vectors in both planes: V₁,₀ and V₂,₀

  2. Add trial mass m₁,₁ in plane 1, measure: V₁,₁ and V₂,₁

  3. Add trial mass m₂,₂ in plane 2, measure: V₁,₂ and V₂,₂

  4. Compute compensation masses in both planes with DynamicBalancing

Metadata

Release files for pyPRB 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyPRB 1.0.0
File Size Uploaded
pyprb-1.0.0.tar.gz 19.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pyPRB 1.0.0
File Interpreter ABI Platform
pyprb-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 44.2 kB

Release files / pyprb-1.0.0.tar.gz

Download URL pyprb-1.0.0.tar.gz
Size 19.2 kB
Tags Source
SHA-256 checksum
How to use checksums
70df984586e7302948a072c55cce359c2eeaab5871294015be86aaecd318e6d7
BLAKE2b-256 checksum
How to use checksums
c1880e5093a4afc191483fb700f5d1c504b2de885f9ab8e75c68769ec01289d2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.8

Release files / pyprb-1.0.0-py3-none-any.whl

Download URL pyprb-1.0.0-py3-none-any.whl
Size 25.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d1ab42489c2f400a30661d0c0f732d3a7d39585ba44f02e71b6f9cbe549be34c
BLAKE2b-256 checksum
How to use checksums
7840370393bc13cb3fbfa3b1175aa5fe36eaf10c60dd4da909c5339981f0f9c7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.8

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page