FreeCAD as pre-post procesor for MBDyn

About the development of the FEM module/workbench.

Moderator: bernd

josegegas
Posts: 39
Joined: Sat Feb 11, 2017 12:54 am
Location: New Zealand

Re: FreeCAD as pre-post procesor for MBDyn

Postby josegegas » Tue Nov 12, 2019 5:17 am

Made some more progress today... fixing errors in the code, a bit more complicated simulations start to be really fun:

phpBB [video]

:D
Last edited by Kunda1 on Tue Nov 12, 2019 8:58 am, edited 2 times in total.
Reason: added video tags
User avatar
microelly2
Posts: 4440
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: FreeCAD as pre-post procesor for MBDyn

Postby microelly2 » Tue Nov 12, 2019 5:39 am

Wow. nice to see this interface.
vocx
Posts: 1850
Joined: Thu Oct 18, 2018 9:18 pm

Re: FreeCAD as pre-post procesor for MBDyn

Postby vocx » Tue Nov 12, 2019 6:02 am

josegegas wrote:
Tue Nov 12, 2019 5:17 am
Made some more progress today... fixing errors in the code, a bit more complicated simulations start to be really fun:

https://www.youtube.com/watch?v=YyUkuVBGgyU&t=315s

:D
You still haven't made this public, right?

My advice is to use dedicated icons for your scripted objects (those that appear on the tree view). This makes the workbench look more professional, because it doesn't use the plain "cube" icon from the Part Workbench. It also prevents confusion, as some of your objects may only work with your particular workbench.

When you create your scripted object, you can assign a "view provider" to define visual properties, including the icon.

Code: Select all

obj = App.ActiveDocument.addObject("Part::FeaturePython", "MBDsolid")
MBDObject(obj)  # Class that sets ups the general properties of the scripted object
MBDViewProvider(obj.ViewObject)  # Class that sets up the visual properties

class MBDViewProvider:
    def __init__(self, vobj):
        vobj.Proxy = self
    def __getstate__(self):
        return None
    def __setstate__(self, state):
        return None
    def execute(self, vobj):
        return
    def getIcon(self):
        return os.path.join(os.path.dirname(__file__), "icons", "MDBobject.svg")
josegegas
Posts: 39
Joined: Sat Feb 11, 2017 12:54 am
Location: New Zealand

Re: FreeCAD as pre-post procesor for MBDyn

Postby josegegas » Tue Nov 12, 2019 6:23 am

vocx wrote:
Tue Nov 12, 2019 6:02 am
josegegas wrote:
Tue Nov 12, 2019 5:17 am
Made some more progress today... fixing errors in the code, a bit more complicated simulations start to be really fun:

https://www.youtube.com/watch?v=YyUkuVBGgyU&t=315s

:D
You still haven't made this public, right?

My advice is to use dedicated icons for your scripted objects (those that appear on the tree view). This makes the workbench look more professional, because it doesn't use the plain "cube" icon from the Part Workbench. It also prevents confusion, as some of your objects may only work with your particular workbench.

When you create your scripted object, you can assign a "view provider" to define visual properties, including the icon.

Code: Select all

obj = App.ActiveDocument.addObject("Part::FeaturePython", "MBDsolid")
MBDObject(obj)  # Class that sets ups the general properties of the scripted object
MBDViewProvider(obj.ViewObject)  # Class that sets up the visual properties

class MBDViewProvider:
    def __init__(self, vobj):
        vobj.Proxy = self
    def __getstate__(self):
        return None
    def __setstate__(self, state):
        return None
    def execute(self, vobj):
        return
    def getIcon(self):
        return os.path.join(os.path.dirname(__file__), "icons", "MDBobject.svg")
No, not public yet. I'll make it public once it is more usable. I'm still catching errors...

Yes I was wondering how to add icons to the scripted objects. I will do this. Thanks! Also, do you know how to make an object part of another object? I mean, as in the FEM workbench, when you create a new analysis, the analysis itself contains scripted objects, such as the mesh, the material, constraints, etc. I'd like to do the same instead of using those containers with the folder icon, or are these the same?

Cheers
ickby
Posts: 2927
Joined: Wed Oct 05, 2011 7:36 am

Re: FreeCAD as pre-post procesor for MBDyn

Postby ickby » Tue Nov 12, 2019 7:09 am

You have multiple options, dependend if it only needs to serve as group or if it should be a special object (e.g. Part::Feature)

1. Make a simple group with custom icon

Code: Select all

import FreeCAD

class VPGroup:
	def __init__(self, obj):
		obj.Proxy = self

	def getIcon(self):
		'''Return the icon in XPM format which will appear in the tree view. This method is\
  		optional and if not defined a default icon is shown.'''
		return """
            /* XPM */
            static const char * ViewProviderBox_xpm[] = {
            "16 16 6 1",
            "   c None",
            ".  c #141010",
            "+  c #615BD2",
            "@  c #C39D55",
            "#  c #000000",
            "$  c #57C355",
            "        ........",
            "   ......++..+..",
            "   .@@@@.++..++.",
            "   .@@@@.++..++.",
            "   .@@  .++++++.",
            "  ..@@  .++..++.",
            "###@@@@ .++..++.",
            "##$.@@$#.++++++.",
            "#$#$.$$$........",
            "#$$#######      ",
            "#$$#$$$$$#      ",
            "#$$#$$$$$#      ",
            "#$$#$$$$$#      ",
            " #$#$$$$$#      ",
            "  ##$$$$$#      ",
            "   #######      "};
            """

obj = App.ActiveDocument.addObject("App::DocumentObjectGroupPython")
VPGroup(obj.ViewObject)
2. Make any object with group extension (this allows e.g. Part::Feature to be a group)

Code: Select all

import FreeCAD

class MyCustomGroup():
	def __init__(self, obj):
		obj.addExtension("App::GroupExtensionPython", self)

class MyCustomGroupViewProvider():
	def __init__(self, obj):
		obj.addExtension("Gui::ViewProviderGroupExtensionPython", self)
		obj.Proxy = self

	def getIcon(self):
	        '''Return the icon in XPM format which will appear in the tree view. This method is\
	                optional and if not defined a default icon is shown.'''
	        return """
	            /* XPM */
	            static const char * ViewProviderBox_xpm[] = {
	            "16 16 6 1",
	            "   c None",
	            ".  c #141010",
	            "+  c #615BD2",
	            "@  c #C39D55",
	            "#  c #000000",
	            "$  c #57C355",
	            "        ........",
	            "   ......++..+..",
	            "   .@@@@.++..++.",
	            "   .@@@@.++..++.",
	            "   .@@  .++++++.",
	            "  ..@@  .++..++.",
	            "###@@@@ .++..++.",
	            "##$.@@$#.++++++.",
	            "#$#$.$$$........",
	            "#$$#######      ",
	            "#$$#$$$$$#      ",
	            "#$$#$$$$$#      ",
	            "#$$#$$$$$#      ",
	            " #$#$$$$$#      ",
	            "  ##$$$$$#      ",
	            "   #######      "};
	            """

obj = App.ActiveDocument.addObject("Part::FeaturePython","Group")
MyCustomGroup(obj)
MyCustomGroupViewProvider(obj.ViewObject)
The extension approach has the added advantage that you can make the group only accept certain types of object by implementing the "allowObject" function:

Code: Select all

class MyCustomGroup():
	def __init__(self, obj):
		obj.addExtension("App::GroupExtensionPython", self)
	
	def allowObject(self, obj):
		#check if obj is allowed, maybe by type?
		return obj.isDerivedFrom("Part::FeaturePython")
		
vocx
Posts: 1850
Joined: Thu Oct 18, 2018 9:18 pm

Re: FreeCAD as pre-post procesor for MBDyn

Postby vocx » Tue Nov 12, 2019 7:29 am

josegegas wrote:
Tue Nov 12, 2019 6:23 am
Yes I was wondering how to add icons to the scripted objects. I will do this. Thanks! Also, do you know how to make an object part of another object? I mean, as in the FEM workbench, when you create a new analysis, the analysis itself contains scripted objects, such as the mesh, the material, constraints, etc. I'd like to do the same instead of using those containers with the folder icon, or are these the same?

Cheers
The folder object corresponds to a Std Group which is created as

Code: Select all

obj = App.ActiveDocument.addObject("App::DocumentObjectGroup", "Group")
To make an object part of another object, you need to implement the claimChildren method of the view provider. Notice that this is purely aesthetic; the relationship between who is the parent and which the child depends on your implementation.

In the view provider the "Object" is the real object. This can hold a "Component" property that will hold those external objects that will be placed under this Object in the tree view.

Code: Select all

# Real object
class MBDSolid:
    def __init__(self, obj, tp="MBDSolid"):
        if obj:
            obj.Proxy = self
        self.Type = tp
        obj.addProperty("App::PropertyLinkList", "Components", "Base", QT_TRANSLATE_NOOP("App::Property", "The components of this block"))
        # This property will appear in the property editor

# Then the view provider
class MBDViewProvider:
    def __init__(self, vobj):
        vobj.Proxy = self
        self.Object = vobj.Object
    def __getstate__(self):
        return None
    def __setstate__(self, state):
        return None
    def attach(self,vobj):
        self.Object = vobj.Object
    def execute(self, vobj):
        return
    def getIcon(self):
        return os.path.join(os.path.dirname(__file__), "icons", "MDBobject.svg")
    def claimChildren(self):
        objs = []
        if hasattr(self.Object, "Components"):
            objs.extend(self.Object.Components)
        return objs
        # Those objects that are inside the Components property will appear as children in the tree
It seems in FEM a lot of this is defined in C++ so it's a bit harder to get.

The Analysis object in FEM seems to use the same ViewProvider as a Std Group (App::DocumentObjectGroup). Maybe it's basically a Group with a specific FEM icon, so maybe you could do the same.

https://github.com/FreeCAD/FreeCAD/blob ... is.cpp#L81
User avatar
saso
Posts: 1336
Joined: Fri May 16, 2014 1:14 pm
Contact:

Re: FreeCAD as pre-post procesor for MBDyn

Postby saso » Tue Nov 12, 2019 10:25 am

josegegas wrote:
Tue Nov 12, 2019 5:17 am
Made some more progress today... fixing errors in the code, a bit more complicated simulations start to be really fun:
Very nice indeed! Two questions...

Is it already possible, or do you see that it could be possible in the future, to solve with this such examples as freecad-heini-1 has asked for here https://forum.freecadweb.org/viewtopic. ... 10#p343888 and https://forum.freecadweb.org/viewtopic. ... 20#p344564 ? As I understand it is basically about the contact (collision) between two surfaces...

Do you think it would be possible to have with this also interactive simulations, so that the model would be solved but then instead of running it as an animation, one would be able to pick a part of it with the mouse and move it manually?
josegegas
Posts: 39
Joined: Sat Feb 11, 2017 12:54 am
Location: New Zealand

Re: FreeCAD as pre-post procesor for MBDyn

Postby josegegas » Tue Nov 12, 2019 12:23 pm

saso wrote:
Tue Nov 12, 2019 10:25 am
josegegas wrote:
Tue Nov 12, 2019 5:17 am
Made some more progress today... fixing errors in the code, a bit more complicated simulations start to be really fun:
Very nice indeed! Two questions...

Is it already possible, or do you see that it could be possible in the future, to solve with this such examples as freecad-heini-1 has asked for here https://forum.freecadweb.org/viewtopic. ... 10#p343888 and https://forum.freecadweb.org/viewtopic. ... 20#p344564 ? As I understand it is basically about the contact (collision) between two surfaces...

Do you think it would be possible to have with this also interactive simulations, so that the model would be solved but then instead of running it as an animation, one would be able to pick a part of it with the mouse and move it manually?

This is perfectly possible! My next goal is actually to simulate a complete 4 stroke engine. Here is some work so far:

https://www.youtube.com/watch?v=x_lCrEkQUrE

You can't see the cams in the video, but I already modeled and simulated them. Here's a video of a cam simulated with MBDyn:

https://www.youtube.com/watch?v=ZwDzvJ9XD7M

You can find the code for that simulation in the video description. Here's an elastic contact example:

https://www.youtube.com/watch?v=H6fry6T5fSU

MBDyn is such a beautiful software, and integrated with FreeCAD will be a very powerful tool. I actually think that MBDyn can do as the definitive asembly workbench for FreeCAD. As you can see in my videos, the parts move perfectly because MBDyn takes care of the assembly, it looks for all the constraints and everything. I'm quite existed about this.
User avatar
microelly2
Posts: 4440
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: FreeCAD as pre-post procesor for MBDyn

Postby microelly2 » Tue Nov 12, 2019 12:44 pm

At the moment I see that you work with mbd configuration files and you have related objects inside freecad.
Does it make sense to implement the mbd nodes as nodes in pyflow and do the configration work there?
For me working in a network is easier than in the object tree hierarchy where I cannot see the relations between the object.
here some impressions on pyflow
https://www.youtube.com/playlist?list=P ... tKxbGxrmlr
User avatar
saso
Posts: 1336
Joined: Fri May 16, 2014 1:14 pm
Contact:

Re: FreeCAD as pre-post procesor for MBDyn

Postby saso » Tue Nov 12, 2019 3:56 pm

josegegas wrote:
Tue Nov 12, 2019 12:23 pm
I actually think that MBDyn can do as the definitive asembly workbench for FreeCAD. As you can see in my videos, the parts move perfectly because MBDyn takes care of the assembly, it looks for all the constraints and everything. I'm quite existed about this.
Yes, lately I was actually thinking about something similar, this is why I asked this questions :)

I was however thinking about doing it with Modelica, since Modelica is a language, we could even write our own libraries with it, if some of the existing ones would not be useful for our needs... But I am not preferring one solution over the other, similar to how we can use different solvers for FEM/CFD it would be IMO good to also have support for different solutions for simulations.

But directly using something like this for the assembly solver I am not sure if it is really possible. For assembling the model (from different parts and sub-assemblies) the user does not really need all the power of such simulation engines, what s/he needs however is a very fast (real time) solver, simulation engines however normally need some time (in complex models it can actually be a very long time) to "solve" the simulation. So, for the basic assembly we would need a simplified version of such a simulation engine with a sort of JIT compiler OR a combination of a more standard assembly constraints/mates and a more advanced ones for simulations (and I think most commercial parametric cad software is doing it like this).

This is however actually also one of the reasons for this post https://forum.freecadweb.org/viewtopic.php?f=8&t=40775, if Modelica, as a language, is a step further from the simulation packages and libraries, then DifferentialEquations.jl and SUNDIALS projects are another step further in to research of the best algorithms and mathematics that are behind this.