Skip to main content

Static and dynamic rotor balancing using portable measurement equipment calculations based on Brüel & Kjær guide.

Project description

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyprb-1.0.0.tar.gz (19.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyprb-1.0.0-py3-none-any.whl (25.0 kB view details)

Uploaded Python 3

File details

Details for the file pyprb-1.0.0.tar.gz.

File metadata

  • Download URL: pyprb-1.0.0.tar.gz
  • Upload date:
  • Size: 19.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.8

File hashes

Hashes for pyprb-1.0.0.tar.gz
Algorithm Hash digest
SHA256 70df984586e7302948a072c55cce359c2eeaab5871294015be86aaecd318e6d7
MD5 08a1e92f5a38439d6a27719ae481aba5
BLAKE2b-256 c1880e5093a4afc191483fb700f5d1c504b2de885f9ab8e75c68769ec01289d2

See more details on using hashes here.

File details

Details for the file pyprb-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: pyprb-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 25.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.8

File hashes

Hashes for pyprb-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d1ab42489c2f400a30661d0c0f732d3a7d39585ba44f02e71b6f9cbe549be34c
MD5 c17c741eb89940dacf4c554ec48a9074
BLAKE2b-256 7840370393bc13cb3fbfa3b1175aa5fe36eaf10c60dd4da909c5339981f0f9c7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page