Quantity/pl

Wielkość jest połączeniem liczby zmiennoprzecinkowej i jednostki. Jest używana wszędzie we FreeCAD do obsługi parametrów i wszelkich innych danych wejściowych/wyjściowych.

Informacje ogólne

W systemie CAD lub CAE bardzo ważne jest śledzenie jednostki danej wartości. Wiele problemów może pojawić się przy pomyleniu jednostek lub obliczaniu wyników w różnych systemach jednostek. Jedną z najsłynniejszych katastrof jest katastrofa sondy Mars Climate Orbiter spowodowana pomyłką w jednostkach. Nawet w tym samym systemie jednostek istnieje wiele ich odmian, zawsze dostosowanych do obszaru zastosowania. Proste przykłady to np. prędkość w km/h (samochody), m/s (robotyka) czy mm/min (frezowanie). System CAD musi niezawodnie śledzić jednostki. Musi także wykonywać z nimi obliczenia i sprawdzać poprawność jednostki dla szczególnych parametrów.

Z tego powodu powstała struktura jednostek we FreeCAD. Zawiera ona cały kod i obiekty potrzebne do obsługi jednostek, obliczeń z jednostkami, wprowadzania danych przez użytkownika, konwersji do innych systemów jednostek oraz estetycznego wyświetlania jednostek i wartości. W dłuższej perspektywie żaden parametr we FreeCAD nie powinien być jedynie liczbą.

Obsługiwane jednostki

Parser danych wejściowych we FreeCAD obsługuje wiele jednostek i systemów jednostek. FreeCAD obsługuje grecką literę „µ” oznaczającą mikro, ale akceptuje także „u” jako zamiennik. Pełną listę wszystkich obsługiwanych jednostek można znaleźć tutaj.

Szczegółowe specyfikacje, które można znaleźć w kodzie:

Wewnętrzna reprezentacja

Wszystkie jednostki fizyczne można wyrazić jako połączenie siedmiu jednostek SI:

Prostym sposobem wyrażenia jednostki jest tablica liczb całkowitych o rozmiarze 7 (liczba jednostek bazowych), która definiuje czym jest jednostka. Sygnatury 7 jednostek bazowych to:

Z tych 7 jednostek jesteśmy w stanie wyrazić wszystkie jednostki pochodne zdefiniowane w Przewodniku dotyczącym stosowania międzynarodowego systemu jednostek (SI) i w razie potrzeby stworzyć nowe, takie jak np:

Ponieważ kąt jest fizycznie bezwymiarowy, ale istotny dla systemu CAD, dodajemy jeszcze jedną wirtualną jednostkę dla Kąta. To tworzy wektor 8 w sygnaturze jednostek FreeCAD.

Kalkulator jednostek

Często zachodzi potrzeba konwersji wartości z jednego systemu jednostek na drugi. Przykładowo, posiadasz stare tabele parametrów z dziwnymi jednostkami. W takich przypadkach FreeCAD oferuje narzędzie do konwersji nazwane Kalkulatorem jednostek, który pomaga w przekształcaniu jednostek.

Jego szczegółowy opis znajduje się tutaj: Przelicznik jednostek

Pole wejściowe

InputField (pole wejściowe) to widżet Qt pochodzący od QLineEdit, służący do obsługi wszelkich interakcji użytkownika z wielkościami i parametrami. Oferuje następujące właściwości:

Kalkulator jednostek już korzysta z InputField.

Kod:

Tworzenie skryptów

System jednostek i wielkości we FreeCAD jest (jak prawie wszystko) w pełni dostępny z poziomu skryptów Pythona.

Jednostka

Klasa Unit (jednostka) reprezentuje odcisk każdej jednostki fizycznej. Jak opisano w sekcji Podstawy, do przedstawienia tego odcisku używany jest wektor ośmiu liczb. Klasa Unit umożliwia obsługę i wykonywanie obliczeń na podstawie tych informacji.

from FreeCAD import Units

# creating a unit with certain signature
Units.Unit(0,1)      # Mass     (kg)
Units.Unit(1)        # Length   (mm)
Units.Unit(-1,1,-2)  # Pressure (kg/mm*s^2)

# using predefined constants
Units.Unit(Units.Length)
Units.Unit(Units.Mass)
Units.Unit(Units.Pressure)

# parsing unit out of a string
Units.Unit('kg/(m*s^2)')    # Pressure
Units.Unit('Pa')            # the same as combined unit Pascale
Units.Unit('J')             # Joule (work,energy) mm^2*kg/(s^2)

# you can use units from all supported systems of units
Units.Unit('psi')           # imperial pressure
Units.Unit('lb')            # imperial  mass
Units.Unit('ft^2')          # imperial area

# comparing units
Units.Unit(0,1) == Unit(Units.Mass)

# getting type of unit
Units.Unit('kg/(m*s^2)').Type == 'Pressure'

# calculating
Units.Unit('kg') * Units.Unit('m^-1*s^-2') == Units.Unit('kg/(m*s^2)')

Jednostka jest głównie używana do opisu określonego typu jednostki dla parametru. Dlatego w FreeCAD zastosowano specjalny typ właściwości, który może przekazać jednostkę w celu sprawdzenia i zapewnienia jej poprawności. Połączenie jednostki i wartości zmiennoprzecinkowej nazywane jest wielkością.

Wielkość

from FreeCAD import Units

# to create a quantity you need a value (float) and a unit
Units.Quantity(1.0,Units.Unit(0,1))     # Mass       1.0 kg
Units.Quantity(1.0,Units.Unit(1))       # Length    1.0 mm
Units.Quantity(1.0,Units.Unit(-1,1,-2)) # Pressure  1.0 kg/mm*s^2
Units.Quantity(1.0,Units.Pressure)      # Pressure  1.0 kg/mm*s^2

# you can directly give a signature
Units.Quantity(1.0,0,1)     # Mass       1.0 kg
Units.Quantity(1.0,1)       # Length    1.0 mm
Units.Quantity(1.0,-1,1,-2) # Pressure  1.0 kg/mm*s^2

# parsing quantities out of a string
Units.Quantity('1.0 kg/(m*s^2)') # Pressure
Units.Quantity('1.0 Pa')         # the same as combined Unit Pascale
Units.Quantity('1.0 J')          # Joule (Work,Energy) mm^2*kg/(s^2)

# You can use a point or comma as float delimiter
Units.Quantity('1,0 m')
Units.Quantity('1.0 m')

# you can use units from all supported systems of units
Units.Quantity('1.0 psi')  # imperial pressure
Units.Quantity('1.0 lb')   # imperial mass
Units.Quantity('1.0 ft^2') # imperial area

# the quantity parser can do calculations too
Units.Quantity('360/5 deg')        # splitting circle 
Units.Quantity('1/16 in')          # fractions
Units.Quantity('5.3*6.3 m^2')      # calculating an area
Units.Quantity('1/(log(2.3)/sin(pi)*3.4)+1.8e-3 m')
Units.Quantity('1ft 3in')          # imperial style

# and for sure calculation and comparison
Units.Quantity('1 Pa') * Units.Quantity(2.0) == Units.Quantity('2 Pa')
Units.Quantity('1 m') * Units.Quantity('2 m') == Units.Quantity('2 m^2')
Units.Quantity('1 m') * Units.Quantity('2 ft') + Units.Quantity('2 mm^2')
Units.Quantity('1 m') > Units.Quantity('2 ft')

# accessing the components
Units.Quantity('1 m').Value # get the number (always internal system (mm/kg/s))
Units.Quantity('1 m').Unit  # get the unit
Units.Quantity('1 m') == Units.Quantity( Units.Quantity('1 m').Value , Units.Quantity('1 m').Unit)

# translating the value into other units than the internal system (mm/kg/s)
Units.Quantity('1 km/h').getValueAs('m/s')                  # translate value
Units.Quantity('1 m').getValueAs(2.45,1)                    # translation value and unit signature
Units.Quantity('1 kPa').getValueAs(Units.Pascal)            # predefined standard units 
Units.Quantity('1 MPa').getValueAs(Units.Quantity('N/m^2')) # a quantity

Wartości prezentowane użytkownikowi

Zazwyczaj w skryptach można używać Quantity (wielkości) do wszelkiego rodzaju obliczeń i sprawdzeń, ale przychodzi moment, gdy trzeba wyświetlić informacje użytkownikowi. Można użyć getValueAs(), aby wymusić określoną jednostkę, ale zazwyczaj użytkownik ustawia w preferencjach swoje ulubione schematy jednostek. Ten schemat jednostek dokonuje wszystkich konwersji do formy, którą użytkownik chce zobaczyć. Obecnie zaimplementowano trzy schematy:

W przyszłości można łatwo dodać kolejne schematy...

Klasa Quantity ma dwie opcje użycia aktualnego schematu konwersji:

from FreeCAD import Units

# Use the translated string:
Units.Quantity('1m').UserString           # '1000 mm' in 1; '1 m' in 2; and '1.09361 yr' in 3

To wystarcza, jeśli potrzebujesz jedynie łańcucha znaków. Ale czasami potrzebna jest większa kontrola, np. gdy chcesz mieć przycisk w oknie dialogowym, który zwiększa lub zmniejsza wartość. Wtedy potrzebne są dodatkowe informacje o wyniku konwersji. W tym celu używana jest metoda getUserPreferred() klasy Quantity:

Units.Quantity('22 m').getUserPreferred() # gets a tuple:('22 m', 1000.0, 'm')
Units.Quantity('2  m').getUserPreferred() # Tuple: ('2000 mm', 1.0, 'mm')

Tutaj otrzymujesz więcej informacji w postaci krotki (trzech elementów). Otrzymujesz łańcuch znaków jak wcześniej, dodatkowo współczynnik wartości oraz surowy łańcuch zawierający tylko jednostkę wybraną przez schemat konwersji. Dzięki tym informacjom możesz zaimplementować znacznie bogatszą interakcję z użytkownikiem.

Kod schematów konwersji można znaleźć tutaj:

Precyzja

Precyzja wielkości w oknach dialogowych FreeCAD odpowiada liczbie miejsc po przecinku określonej w preferencjach. Aby użyć tych ustawień w swoim skrypcie (na przykład w oknach dialogowych), można je pobrać za pomocą następującego kodu:

import FreeCAD

params = App.ParamGet("User parameter:BaseApp/Preferences/Units")
params.GetInt('Decimals') # returns an int

Dodatek

Jednostki wspierane przez parser

Chociaż wszystkie jednostki fizyczne można opisać za pomocą siedmiu jednostek SI, większość jednostek stosowanych w dziedzinach technicznych to powszechnie używane jednostki złożone (np. Pa = N/m^2, Paskal). Dlatego parser jednostek w FreeCAD obsługuje wiele jednostek złożonych SI i imperialnych. Jednostki te są zdefiniowane w pliku src/Base/QuantityParser.l i mogą być w przyszłości dalej rozszerzane.

from FreeCAD import Units

 "nm"  = Units.Quantity(1.0e-6    ,Units.Unit(1));         // nano meter
 "µm"  = Units.Quantity(1.0e-3    ,Units.Unit(1));         // micro meter
 "mm"  = Units.Quantity(1.0       ,Units.Unit(1));         // milli meter
 "cm"  = Units.Quantity(10.0      ,Units.Unit(1));         // centi meter
 "dm"  = Units.Quantity(100.0     ,Units.Unit(1));         // deci meter
 "m"   = Units.Quantity(1.0e3     ,Units.Unit(1));         // meter
 "km"  = Units.Quantity(1.0e6     ,Units.Unit(1));         // kilo meter
 "l"   = Units.Quantity(1000000.0 ,Units.Unit(3));         // liter dm^3
                                                  
 "µg"  = Units.Quantity(1.0e-9    ,Units.Unit(0,1));       // micro gram
 "mg"  = Units.Quantity(1.0e-6    ,Units.Unit(0,1));       // milli gram
 "g"   = Units.Quantity(1.0e-3    ,Units.Unit(0,1));       // gram
 "kg"  = Units.Quantity(1.0       ,Units.Unit(0,1));       // kilo gram
 "t"   = Units.Quantity(1000.0    ,Units.Unit(0,1));       // ton
                                                  
 "s"   = Units.Quantity(1.0       ,Units.Unit(0,0,1));     // second (internal standard time)
 "min" = Units.Quantity(60.0      ,Units.Unit(0,0,1));     // minute
 "h"   = Units.Quantity(3600.0    ,Units.Unit(0,0,1));     // hour  
                                                  
 "A"   = Units.Quantity(1.0       ,Units.Unit(0,0,0,1));   // Ampere (internal standard electric current)
 "mA"  = Units.Quantity(0.001     ,Units.Unit(0,0,0,1));   // milli Ampere         
 "kA"  = Units.Quantity(1000.0    ,Units.Unit(0,0,0,1));   // kilo Ampere         
 "MA"  = Units.Quantity(1.0e6     ,Units.Unit(0,0,0,1));   // Mega Ampere         
                                                  
 "K"   = Units.Quantity(1.0       ,Units.Unit(0,0,0,0,1)); // Kelvin (internal standard thermodynamic temperature)
 "mK"  = Units.Quantity(0.001     ,Units.Unit(0,0,0,0,1)); // Kelvin         
 "µK"  = Units.Quantity(0.000001  ,Units.Unit(0,0,0,0,1)); // Kelvin         

 "mol" = Units.Quantity(1.0       ,Units.Unit(0,0,0,0,0,1)); // Mole (internal standard amount of substance)        

 "cd"  = Units.Quantity(1.0       ,Units.Unit(0,0,0,0,0,0,1)); // Candela (internal standard luminous intensity)        

 "deg" = Units.Quantity(1.0         ,Units.Unit(0,0,0,0,0,0,0,1)); // degree (internal standard angle)
 "rad" = Units.Quantity(180/M_PI    ,Units.Unit(0,0,0,0,0,0,0,1)); // radian         
 "gon" = Units.Quantity(360.0/400.0 ,Units.Unit(0,0,0,0,0,0,0,1)); // gon         

 "in"  = Units.Quantity(25.4        ,Units.Unit(1));       // inch
 "\""  = Units.Quantity(25.4        ,Units.Unit(1));       // inch
 "fo"  = Units.Quantity(304.8       ,Units.Unit(1));       // foot
 "'"   = Units.Quantity(304.8       ,Units.Unit(1));       // foot
 "th"  = Units.Quantity(0.0254      ,Units.Unit(1));       // thou
 "yd"  = Units.Quantity(914.4       ,Units.Unit(1));       // yard

 "lb"  = Units.Quantity(0.45359237   ,Units.Unit(0,1));    // pound
 "oz"  = Units.Quantity(0.0283495231 ,Units.Unit(0,1));    // ounce
 "st"  = Units.Quantity(6.35029318   ,Units.Unit(0,1));    // Stone
 "cwt" = Units.Quantity(50.80234544  ,Units.Unit(0,1));    // hundredweights