FreeCAD as pre-post processor for MBDyn
Moderator: bernd
Forum rules
and Helpful information for the FEM forum
and Helpful information for the FEM forum
Re: FreeCAD as pre-post processor for MBDyn
Is it possible to post-process MBDyn results without FCStd model file?
Re: FreeCAD as pre-post processor for MBDyn
Hi.
I want to be able to store any quantity as a property for a scripetd object, including any random units. So I thought to do this:
from FreeCAD import Units
obj=FreeCAD.ActiveDocument.addObject("App::FeaturePython","InternalObjectName")
obj.addProperty('App::PropertyQuantity', 'ThePropertyName', 'Subsection', 'Description for tooltip')
obj.ThePropertyName = Units.Quantity(1.0,Units.Unit(0,1))
However it seems that 'App::PropertyQuantity' cannot get any unit:
Traceback (most recent call last):
File "<input>", line 1, in <module>
ArithmeticError: Not matching Unit!
I need for instance to store moments of inertia or angular velocity and acceleration, so I do requires specific units....
Any suggestions?
Cheers!
I want to be able to store any quantity as a property for a scripetd object, including any random units. So I thought to do this:
from FreeCAD import Units
obj=FreeCAD.ActiveDocument.addObject("App::FeaturePython","InternalObjectName")
obj.addProperty('App::PropertyQuantity', 'ThePropertyName', 'Subsection', 'Description for tooltip')
obj.ThePropertyName = Units.Quantity(1.0,Units.Unit(0,1))
However it seems that 'App::PropertyQuantity' cannot get any unit:
Traceback (most recent call last):
File "<input>", line 1, in <module>
ArithmeticError: Not matching Unit!
I need for instance to store moments of inertia or angular velocity and acceleration, so I do requires specific units....
Any suggestions?
Cheers!
Re: FreeCAD as pre-post processor for MBDyn
Hi Jose,
I found this thread, maybe it can help you.
https://www.forum.freecadweb.org/viewto ... 10&t=47992
I found this thread, maybe it can help you.
https://www.forum.freecadweb.org/viewto ... 10&t=47992
Re: FreeCAD as pre-post processor for MBDyn
Yes, that works perfectly. I´ll paste the example here in case it's useful:
I think the documentation:
https://wiki.freecadweb.org/FeaturePyth ... tyQuantity
has to be updated to explain how to use "App::PropertyQuantity"....
Thanks
Code: Select all
from FreeCAD import Units
from femobjects import base_fempythonobject
class MyNewObject(base_fempythonobject.BaseFemPythonObject):
Type = "Fem::MyNewObject"
def __init__(self, obj):
super(MyNewObject, self).__init__(obj)
obj.addProperty(
"App::PropertyQuantity",
"MyNewProperty",
"MyPropertyGroup",
"Set my new PropertyQuantity"
)
obj.MyNewProperty = Units.VacuumPermittivity
newobj = App.ActiveDocument.addObject("Fem::ConstraintPython", "FunnyObject")
MyNewObject(newobj)
newobj.MyNewProperty = Units.Quantity("1 s^4*A^2 / (m^3*kg)")
newobj.MyNewProperty
https://wiki.freecadweb.org/FeaturePyth ... tyQuantity
has to be updated to explain how to use "App::PropertyQuantity"....
Thanks
Re: FreeCAD as pre-post processor for MBDyn
Here is a strange thing I just noticed.
The scripted object above works perfectly fine, however if you save the FreeCAD file and open it again, the units will be gone... The initial units of the property disappear after saving, closing and opening the file again.
What may be wrong?
The scripted object above works perfectly fine, however if you save the FreeCAD file and open it again, the units will be gone... The initial units of the property disappear after saving, closing and opening the file again.
What may be wrong?
Re: FreeCAD as pre-post processor for MBDyn
Here is the relevant part of my code:
This works perfectly, except that when the FreeCAD document is saved, closed and open again, the units of the "absolute_angular_velocity_X" property have disappeared.
Any ideas why?
Code: Select all
from FreeCAD import Units
import FreeCAD
class Rigidbody:
def __init__(self, obj):
obj.addProperty("App::PropertyQuantity",
"absolute_angular_velocity_X",
"Initial conditions: absolute angular velocity [deg/s]",
"X component of the absolute initial angular velocity").absolute_angular_velocity_X = 10.0
obj.absolute_angular_velocity_X = FreeCAD.Units.Unit('deg/s')
a = FreeCAD.ActiveDocument.addObject("Part::FeaturePython","MyObject")
Rigidbody(a)
Any ideas why?
Re: FreeCAD as pre-post processor for MBDyn
I think I spotted this problem when i was working on the other workbench but did not continue to investigate due to all major task I had.
Maybe be overwriting one of the following methods you could reattribute the unit to each object?
OnDocumentRestore
__setstate__
Or maybe the __getstate__ method to modify the way the object is saved ?
Maybe be overwriting one of the following methods you could reattribute the unit to each object?
OnDocumentRestore
__setstate__
Or maybe the __getstate__ method to modify the way the object is saved ?
Re: FreeCAD as pre-post processor for MBDyn
Got the solution. Units have to be restored every time the document is loaded:
My guess is that this is so that units can be changed in case the user has selected another unit system. The default is mm/kg/s/deg
I wonder why is that other properties (App::PropertyDistance, App::PropertyAngle, etc) do not have the same behavior. The units for these are stored and do not have to be restored on document load. I also wonder why these exist at all, as we can use App::PropertyQuantity for all the properties...
Code: Select all
def onDocumentRestored(self, obj):
obj.absolute_angular_velocity_X = FreeCAD.Units.Unit('deg/s')
I wonder why is that other properties (App::PropertyDistance, App::PropertyAngle, etc) do not have the same behavior. The units for these are stored and do not have to be restored on document load. I also wonder why these exist at all, as we can use App::PropertyQuantity for all the properties...
Re: FreeCAD as pre-post processor for MBDyn
Hi. I´m having an issue with a couple of my scripted objects. The problem seems to be related to the onChanged method. I use this method to change one property of the object according to the values entered or selected by the user. It works perfectly, but when I close and open the FreeCAD model I get the next error:
The thing is that the object does have an attribute "type". Here is the whole object:
What am I getting wrong?
Code: Select all
if(fp.type == 'const, <const_coef>'):
<class 'AttributeError'>: 'FeaturePython' object has no attribute 'type'
Code: Select all
import FreeCAD
class Drive:
def __init__(self, obj, label):
obj.addExtension("App::GroupExtensionPython", self)
obj.addProperty("App::PropertyString","label","Drive","label",1).label = label
#function type
obj.addProperty("App::PropertyEnumeration","type","Drive","type")
obj.type=['const, <const_coef>',
'cosine, <initial_time>, <angular_vel>, <amplitude>, half, <initial_value>',
'cosine, <initial_time>, <angular_vel>, <amplitude>, one, <initial_value>',
'cosine, <initial_time>, <angular_vel>, <amplitude>, forever, <initial_value>',
'cosine, <initial_time>, <angular_vel>, <amplitude>, <number_of_cycles>, <initial_value>',
'cubic, <const_coef>, <linear_coef>, <parabolic_coef>, <cubic_coef>',
'direct',
'double ramp, <a_slope>, <a_initial_time>, <a_final_time>, <d_slope>, <d_initial_time>, forever, <initial_value>',
'double ramp, <a_slope>, <a_initial_time>, <a_final_time>, <d_slope>, <d_initial_time>, <d_final_time>, <initial_value>',
'double step, <initial_time>, <final_time>, <step_value>, <initial_value>',
'linear, <const_coef>, <slope_coef>',
'ramp, <slope>, <initial_time>, forever, <initial_value>',
'ramp, <slope>, <initial_time>, <final_time>, <initial_value>',
'sine, <initial_time>, <angular_vel>, <amplitude>, half, <initial_value>',
'sine, <initial_time>, <angular_vel>, <amplitude>, one, <initial_value>',
'sine, <initial_time>, <angular_vel>, <amplitude>, forever, <initial_value>',
'sine, <initial_time>, <angular_vel>, <amplitude>, <number_of_cycles>, <initial_value>',
'step, <initial_time>, <step_value>, <initial_value>',
'string',
'time',
'timestep',
'unit']
#Slope parameters:
obj.addProperty("App::PropertyFloat","a_slope","Slope parameters","a_slope").a_slope = 2.0
obj.addProperty("App::PropertyFloat","slope","Slope parameters","slope").slope = 0.1
obj.addProperty("App::PropertyFloat","slope_coef","Slope parameters","slope_coef").slope_coef = 0.1
obj.addProperty("App::PropertyFloat","d_slope","Slope parameters","d_slope").d_slope = -2.0
#coefficient parameters
obj.addProperty("App::PropertyFloat","const_coef","Coefficient parameters","const_coef").const_coef = 10.0
obj.addProperty("App::PropertyFloat","linear_coef","Coefficient parameters","linear_coef").linear_coef = 1.0
obj.addProperty("App::PropertyFloat","parabolic_coef","Coefficient parameters","parabolic_coef").parabolic_coef = 1.0
obj.addProperty("App::PropertyFloat","cubic_coef","Coefficient parameters","cubic_coef").cubic_coef = 1.0
#Drive parameters
obj.addProperty("App::PropertyFloat","step_value","Drive parameters","step_value").step_value = 10.0
obj.addProperty("App::PropertyFloat","angular_vel","Drive parameters","angular_vel").angular_vel = 3.11
obj.addProperty("App::PropertyFloat","amplitude","Drive parameters","amplitude").amplitude = 10.0
obj.addProperty("App::PropertyFloat","initial_value","Drive parameters","initial_value").initial_value = 0.0
obj.addProperty("App::PropertyInteger","number_of_cycles","Drive parameters","number_of_cycles").number_of_cycles = 2
#Time parameters:
obj.addProperty("App::PropertyQuantity","a_initial_time","Time parameters","a_initial_time").a_initial_time = 1.0
obj.a_initial_time = FreeCAD.Units.Unit('s')
obj.addProperty("App::PropertyQuantity","d_initial_time","Time parameters","d_initial_time").d_initial_time = 4.0
obj.d_initial_time = FreeCAD.Units.Unit('s')
obj.addProperty("App::PropertyQuantity","a_final_time","Time parameters","a_final_time").a_final_time = 2.0
obj.a_final_time = FreeCAD.Units.Unit('s')
obj.addProperty("App::PropertyQuantity","d_final_time","Time parameters","d_final_time").d_final_time = 5.0
obj.d_final_time = FreeCAD.Units.Unit('s')
obj.addProperty("App::PropertyQuantity","initial_time","Time parameters","initial_time").initial_time = 2.0
obj.initial_time = FreeCAD.Units.Unit('s')
obj.addProperty("App::PropertyQuantity","final_time","Time parameters","final_time").final_time = 4.0
obj.final_time = FreeCAD.Units.Unit('s')
obj.addProperty("App::PropertyString","expression","Drive","expression",1).expression = '1.5*sin(2.*Time)'
obj.Proxy = self
FreeCAD.ActiveDocument.recompute()
def onChanged(self, fp, prop):
if(fp.type == 'const, <const_coef>'):
fp.expression = 'const, ' + str(fp.const_coef)
if(fp.type == 'cosine, <initial_time>, <angular_vel>, <amplitude>, half, <initial_value>'):
fp.expression = 'cosine, ' + str(fp.initial_time.Value) + ', ' + str(fp.angular_vel) + ', ' + str(fp.amplitude) + ', half, ' + str(fp.initial_value)
if(fp.type == 'cosine, <initial_time>, <angular_vel>, <amplitude>, one, <initial_value>'):
fp.expression = 'cosine, ' + str(fp.initial_time.Value) + ', ' + str(fp.angular_vel) +', ' + str(fp.amplitude) + ', one, ' + str(fp.initial_value)
if(fp.type == 'cosine, <initial_time>, <angular_vel>, <amplitude>, forever, <initial_value>'):
fp.expression = 'cosine, ' + str(fp.initial_time.Value) + ', ' + str(fp.angular_vel) + ', ' + str(fp.amplitude) + ', forever, ' + str(fp.initial_value)
if(fp.type == 'cosine, <initial_time>, <angular_vel>, <amplitude>, <number_of_cycles>, <initial_value>'):
fp.expression = 'cosine, ' + str(fp.initial_time.Value) + ', ' + str(fp.angular_vel) + ', ' + str(fp.amplitude) + ', ' + str(fp.number_of_cycles) + ', ' + str(fp.initial_value)
if(fp.type == 'cubic, <const_coef>, <linear_coef>, <parabolic_coef>, <cubic_coef>'):
fp.expression = 'cubic, ' + str(fp.const_coef) + ', ' + str(fp.linear_coef) + ', ' + str(fp.parabolic_coef) + ', ' + str(fp.cubic_coef)
if(fp.type == 'direct'):
fp.expression = 'direct'
if(fp.type == 'double ramp, <a_slope>, <a_initial_time>, <a_final_time>, <d_slope>, <d_initial_time>, forever, <initial_value>'):
fp.expression = 'double ramp, ' + str(fp.a_slope) + ', ' + str(fp.a_initial_time.Value) + ', ' + str(fp.a_final_time.Value) + ', ' + str(fp.d_slope) + ', ' + str(fp.d_initial_time.Value) + ', forever, ' + str(fp.initial_value)
if(fp.type == 'double ramp, <a_slope>, <a_initial_time>, <a_final_time>, <d_slope>, <d_initial_time>, <d_final_time>, <initial_value>'):
fp.expression = 'double ramp, ' + str(fp.a_slope) + ', ' + str(fp.a_initial_time.Value) + ', ' + str(fp.a_final_time.Value) + ', ' + str(fp.d_slope) + ', ' + str(fp.d_initial_time.Value) + ', ' + str(fp.d_final_time.Value) + ', ' + str(fp.initial_value)
if(fp.type == 'double step, <initial_time>, <final_time>, <step_value>, <initial_value>'):
fp.expression = 'double step, ' + str(fp.initial_time.Value) + ', ' + str(fp.final_time.Value) + ', ' + str(fp.step_value) + ', ' + str(fp.initial_value)
if(fp.type == 'linear, <const_coef>, <slope_coef>'):
fp.expression = 'linear, ' + str(fp.const_coef) + ', ' + str(fp.slope_coef)
if(fp.type == 'ramp, <slope>, <initial_time>, forever, <initial_value>'):
fp.expression = 'ramp, ' + str(fp.slope) + ', ' + str(fp.initial_time.Value) + ', forever, ' + str(fp.initial_value)
if(fp.type == 'ramp, <slope>, <initial_time>, <final_time>, <initial_value>'):
fp.expression = 'ramp, ' + str(fp.slope) + ', ' + str(fp.initial_time.Value) + ', ' + str(fp.final_time.Value) + ', ' + str(fp.initial_value)
if(fp.type == 'sine, <initial_time>, <angular_vel>, <amplitude>, half, <initial_value>'):
fp.expression = 'sine, ' + str(fp.initial_time.Value) + ', ' + str(fp.angular_vel) + ', ' + str(fp.amplitude) + ', half, ' + str(fp.initial_value)
if(fp.type == 'sine, <initial_time>, <angular_vel>, <amplitude>, one, <initial_value>'):
fp.expression = 'sine, ' + str(fp.initial_time.Value) + ', ' + str(fp.angular_vel) + ', ' + str(fp.amplitude) + ', one, ' + str(fp.initial_value)
if(fp.type == 'sine, <initial_time>, <angular_vel>, <amplitude>, forever, <initial_value>'):
fp.expression = 'sine, ' + str(fp.initial_time.Value) + ', ' + str(fp.angular_vel) + ', ' + str(fp.amplitude) + ', forever, ' + str(fp.initial_value)
if(fp.type == 'sine, <initial_time>, <angular_vel>, <amplitude>, <number_of_cycles>, <initial_value>'):
fp.expression = 'sine, '+ str(fp.initial_time.Value) + ', ' + str(fp.angular_vel) + ', ' + str(fp.amplitude) + ', ' + str(fp.number_of_cycles) + ', ' + str(fp.initial_value)
if(fp.type == 'step, <initial_time>, <step_value>, <initial_value>'):
fp.expression = 'step, ' + str(fp.initial_time.Value) + ', ' + str(fp.step_value) + ', ' + str(fp.initial_value)
if(fp.type == 'string'):
fp.expression = 'string, "' + fp.string + '"'
if(fp.type == 'time'):
fp.expression = 'time'
if(fp.type == 'timestep'):
fp.expression = 'timestep'
if(fp.type == 'unit'):
fp.expression = 'unit'
def execute(self, fp):
'''Do something when doing a recomputation, this method is mandatory'''
FreeCAD.Console.PrintMessage("DRIVE: " +fp.label+ " successful recomputation...\n")
def onDocumentRestored(self, obj):
obj.a_initial_time = FreeCAD.Units.Unit('s')
obj.d_initial_time = FreeCAD.Units.Unit('s')
obj.a_final_time = FreeCAD.Units.Unit('s')
obj.d_final_time = FreeCAD.Units.Unit('s')
obj.initial_time = FreeCAD.Units.Unit('s')
obj.final_time = FreeCAD.Units.Unit('s')