Quantity

From FreeCAD Documentation
Revision as of 21:26, 13 February 2014 by Renatorivo (talk | contribs) (Created page with "Dato che l'angolo è fisicamente adimensionale, ma in un sistema CAD non è meno importante, si è aggiunta una unità virtuale in più per Angle. Questo crea un vettore di 8 ...")

Quantity è la combinazione di un numero in virgola mobile e di una unità di misura.

Generale

In un sistema CAD o CAE ​​è molto importante mantenere la traccia dell'unità di misura di un valore. Quando si mescolano le unità o si calcolano i risultati in diverse unità di misura possono sorgere un sacco di problemi. Un famoso disastro, causato da un disguido sulle unità di misura, è il crash of the Mars Climate Orbiter. Anche all'interno di uno stesso Sistema di misura le unità possono essere disponibili in diversi formati, secondo il settore di utilizzo. Ad esempio, la velocità in km/h per le automobili, in m/s in robotica o in mm/min per la fresatura. Un sistema CAD deve conservare una traccia affidabile delle unità. Inoltre deve utilizzarle per eseguire i calcoli e deve verificare che per i parametri speciali sia adottata la giusta unità.

Per questo motivo è stata creata la sezione Quantity di FreeCAD. Essa include tutto il codice e gli oggetti che servono per trattare le unità, i calcoli delle unità, i dati inseriti dall'utente, la conversione tra i Sistemi e per fornire un corretto output delle unità e dei valori. In futuro, in FreeCAD, nessun parametro dovrebbe essere solo più un numero.

Unità supportate

Il parser dei dati in ingresso di FreeCAD supporta una serie di unità e di Sistemi di unità. Per indicare micro si deve utilizzare la lettera greca µ, ma, in sostituzione, viene anche accettata la 'u'.

  • Length - Lunghezza
    • "nm"
    • "µm"
    • "mm"
    • "cm"
    • "dm"
    • "m"
    • "km"
    • "in"
    • "ft"
    • "thou"
    • "mil"
    • "yd"
    • "mi"

Da fare: tutto il resto ...


Le specifiche dettagliate si trovano nel codice:

Rappresentazione interna

Tutte le unità fisiche possono essere espresse come combinazione delle sette Unità SI di base:


Un modo semplice per esprimere una Unità è quello di utilizzare un gruppo di 7 interi, il numero delle unità di base, che definisce di quale unità si tratta. Le firme delle 7 unità di base sono:

  • LUNGHEZZA: [1,0,0,0,0,0,0]
  • MASSA: [0,1,0,0,0,0,0]
  • TEMPO: [0,0,1,0,0,0,0]
  • CORRENTE ELETTRICA: [0,0,0,1,0,0,0]
  • TEMPERATURA TERMODINAMICA: [0,0,0,0,1,0,0]
  • QUANTITÀ DI SOSTANZA: [0,0,0,0,0,1,0]
  • INTENSITÀ LUMINOSA: [0,0,0,0,0,0,1]

Partendo da queste 7 unità, siamo poi in grado di esprimere tutte le unità derivate definite nella Guida per l'utilizzo del Sistema Internazionale di Unità (SI) e di crearne di nuove, secondo le esigenze, come ad esempio:

  • MASS DENSITY: [-3,1,0,0,0,0,0]
  • AREA: [0,2,0,0,0,0,0]

Dato che l'angolo è fisicamente adimensionale, ma in un sistema CAD non è meno importante, si è aggiunta una unità virtuale in più per Angle. Questo crea un vettore di 8 dati nella firma delle unità di FreeCAD.

Units calculator

Often you are in need of calculating units from one system to another. For example you have old parameter tables with wired units. In that cases FreeCAD offers a conversion tool called Units-Calculator which helps in translating units.

Its description in detail is here: Std_UnitsCalculator

InputField

The InputField is a QLineEdit derived Qt widget to handle all kind of user interaction with Quantities and parameters. It features following properties:

  • parsing arbitrary value/unit input
  • checking on the right unit (if given) and give the user feedback
  • special context menu for operations on Quantities/Values
  • history management (save the last used values)
  • save often needed values as shortcut in context menu
  • dialing values with mouse wheel and arrow keys (tbd)
  • dialing with middle mouse button and mouse move (tbd)
  • python integration for usage in python only dialogs (tbd)

The UnitsCalculator uses the InputField already.

Main docu: InputField

Code:

Python scripting

The Unit and Quantity system in FreeCAD is (as nearly everything) fully accessibly via Python.

Unit

The Unit class represents the Fingerprint of any physical unit. As descriped in the Basics section a vector of 8 numbers is used to represent this fingerprint. The Unit class allows the handling and calculation with this information.

from Units import Unit

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

# using predefined constats
Unit(FreeCAD.Units.Length)
Unit(FreeCAD.Units.Mass)
Unit(FreeCAD.Units.Pressure)

# parsing unit out of an string
Unit('kg/(m*s^2)')    # Pressure
Unit('Pa')            # the same as combined Unit Pascale
Unit('J')             # Joul (Work,Energy) mm^2*kg/(s^2)

# you can use units from all supported unit-systems
Unit('psi')           # Imperial pressure
Unit('lb')            # Mass
Unit('ft^2')          # Area

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

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

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

The Unit is mainly used to descripe a certain unit-type for a parameter. There fore a special Property Type in FreeCAD can transport a Unit to check and ensure the right Unit. A Unit and a float value is called Quantity.

Quantity

from Units import Unit,Quantity

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

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

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

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

# you can use units from all supported unit-systems
Quantity('1.0 psi')           # Imperial pressure
Quantity('1.0 lb')            # Mass
Quantity('1.0 ft^2')    

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

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

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

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

User facing values

Normally in script you can use Quantity for all kind of calculation and checking, but there comes the time you have to output information to the user. You could use getValueAs() to force a certain unit, but normally the user sets his preferred unit-schema in the preferences. This unit-schema do all the translations to the representation the user likes to see. At the moment there are 3 schema implemented:

  • 1: Internal (mm/kg/s)
  • 2: MKS (m/kg/s)
  • 3: US customary (in/lb)

There can be easily additional schemas implemented in the future...

The quantity class has two possibilities to use the actual schema translation:

from Units import Unit,Quantity

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

This does the job if you only need a string. But somethimes you need more control, e.g. if you want to have a dialog button which dial up and down. Then you need more information about the translation output. There fore the getUserPrefered() method of quantity is used:

Quantity('22 m').getUserPrefered()  # gets a tubple:('22 m', 1000.0, 'm')
Quantity('2  m').getUserPrefered()  # Tuple: ('2000 mm', 1.0, 'mm')

Here you get two more informations as a tuple of size 3. You get the string as before, plus the factor the number is translated and the raw string with only the unit chosen by the translation schema. With this information you can implement a much richer user interaction.

The code for the schema translation you can see here:

Appendix

Parser supported Units

Although all physical units can be described with the seven SI units, most of the units used in technical areas are common combined units (like Pa = N/m^2 Pascal ). There fore the units parser in FreeCAD support lot of SI and Imperial combined units. This units are defined in src/Base/QuantityParser.l file and can be further advanced in the future.


"nm"   = Quantity(1.0e-6    ,Unit(1));           // nano meter
"µm"   = Quantity(1.0e-3    ,Unit(1));           // micro meter
"mm"   = Quantity(1.0       ,Unit(1));           // milli meter
"cm"   = Quantity(10.0      ,Unit(1));           // centi meter
"dm"   = Quantity(100.0     ,Unit(1));           // deci meter
"m"    = Quantity(1.0e3     ,Unit(1));           // meter
"km"   = Quantity(1.0e6     ,Unit(1));           // kilo meter
"l"    = Quantity(1000000.0 ,Unit(3));           // Liter      dm^3
                                                 
"µg"   = Quantity(1.0e-9    ,Unit(0,1));         // micro gram
"mg"   = Quantity(1.0e-6    ,Unit(0,1));         // milli gram
"g"    = Quantity(1.0e-3    ,Unit(0,1));         // gram
"kg"   = Quantity(1.0       ,Unit(0,1));         // kilo gram
"t"    = Quantity(1000.0    ,Unit(0,1));         // ton
                                                 
"s"    = Quantity(1.0       ,Unit(0,0,1));       // second                          (internal standard time)
"min"  = Quantity(60.0      ,Unit(0,0,1));       // minute
"h"    = Quantity(3600.0    ,Unit(0,0,1));       // hour  
                                                 
"A"    = Quantity(1.0       ,Unit(0,0,0,1));     // Ampere          (internal standard electric current)
"mA"   = Quantity(0.001     ,Unit(0,0,0,1));     // milli Ampere         
"kA"   = Quantity(1000.0    ,Unit(0,0,0,1));     // kilo Ampere         
"MA"   = Quantity(1.0e6     ,Unit(0,0,0,1));     // Mega Ampere         
                                                 
"K"    = Quantity(1.0       ,Unit(0,0,0,0,1));   // Kelvin (internal standard thermodynamic temperature)
"mK"   = Quantity(0.001     ,Unit(0,0,0,0,1));   // Kelvin         
"µK"   = Quantity(0.000001  ,Unit(0,0,0,0,1));   // Kelvin         
"mol"  = Quantity(1.0       ,Unit(0,0,0,0,0,1));   // Mole     (internal standard amount of substance)        
"cd"   = Quantity(1.0       ,Unit(0,0,0,0,0,0,1)); // Candela   (internal standard luminous intensity)        
"deg"  = Quantity(1.0           ,Unit(0,0,0,0,0,0,0,1));  // degree         (internal standard angle)
"rad"  = Quantity(180/M_PI      ,Unit(0,0,0,0,0,0,0,1));  // radian         
"gon"  = Quantity(360.0/400.0   ,Unit(0,0,0,0,0,0,0,1));  // gon         
"in"   = Quantity(25.4          ,Unit(1));       // inch
"\""   = Quantity(25.4          ,Unit(1));       // inch
"fo"   = Quantity(304.8         ,Unit(1));       // foot
"'"    = Quantity(304.8         ,Unit(1));       // foot
"th"   = Quantity(0.0254        ,Unit(1));       // thou
"yd"   = Quantity(914.4         ,Unit(1));       // yard


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