diff --git a/.gitignore b/.gitignore
index bad6d9c..66e077c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,6 @@ __pycache__
notes.txt
.vscode
test.py
-out.xml
\ No newline at end of file
+out.xml
+fnrpl.sh
+TODO.txt
\ No newline at end of file
diff --git a/InitGui.py b/InitGui.py
index b582a5a..09f55a0 100644
--- a/InitGui.py
+++ b/InitGui.py
@@ -22,9 +22,9 @@ def Initialize(self):
__dirname__ = os.path.join(FreeCAD.getUserAppDataDir(), "Mod", "RobotDescriptor")
#print("got dir:" + __dirname__);
- from robot_descriptor import initialize
+ from robot_descriptor import initialize ,model_editor
from robot_descriptor.sdf_elements import world
- self.list = ['RD_initialize','world_properties']
+ self.list = ['RD_initialize','world_properties','Model_Editor']
self.appendToolbar("RobotDescription",self.list) # creates a new toolbar with your commands
self.appendMenu("Robot Description",self.list) # creates a new menu
#self.appendMenu(["Robot Description","Tools"],self.list) # appends a submenu to an existing menu
diff --git a/robot_descriptor/RD_parser/RD_parse_sdf.py b/robot_descriptor/RD_utils/RD_parse_sdf.py
similarity index 99%
rename from robot_descriptor/RD_parser/RD_parse_sdf.py
rename to robot_descriptor/RD_utils/RD_parse_sdf.py
index 414fc9f..1ccf3a7 100644
--- a/robot_descriptor/RD_parser/RD_parse_sdf.py
+++ b/robot_descriptor/RD_utils/RD_parse_sdf.py
@@ -1,6 +1,6 @@
import xml.etree.ElementTree as ET
import os
-from .. import RD_globals
+from .. import common
diff --git a/robot_descriptor/RD_parser/initialize_element_tree.py b/robot_descriptor/RD_utils/initialize_element_tree.py
similarity index 96%
rename from robot_descriptor/RD_parser/initialize_element_tree.py
rename to robot_descriptor/RD_utils/initialize_element_tree.py
index c16b4ed..60c8c05 100644
--- a/robot_descriptor/RD_parser/initialize_element_tree.py
+++ b/robot_descriptor/RD_utils/initialize_element_tree.py
@@ -1,5 +1,5 @@
-from .. import RD_globals
+from .. import common
from . import RD_parse_sdf
@@ -63,7 +63,7 @@ def get_element(self)->ET.Element:
t=convdict_2_tree("world.sdf")
tree=t.get_tree
elm=t.get_elements
- e_elem=RD_globals.set_xml_data('linear_velocity',elm,False,[12,9,8])
+ e_elem=common.set_xml_data('linear_velocity',elm,False,[12,9,8])
e_elem_t=ET.ElementTree(e_elem)
tree.write("out.xml",encoding='utf8',xml_declaration=True)
e_elem_t.write("out.xml",encoding='utf8',xml_declaration=True)
\ No newline at end of file
diff --git a/robot_descriptor/RD_utils/parse_asm4_model.py b/robot_descriptor/RD_utils/parse_asm4_model.py
new file mode 100644
index 0000000..45381e5
--- /dev/null
+++ b/robot_descriptor/RD_utils/parse_asm4_model.py
@@ -0,0 +1,98 @@
+import FreeCAD
+import FreeCADGui
+import robot_descriptor.common as common
+import os
+
+'''
+assembly4 Technical manual
+https://github.com/Zolko-123/FreeCAD_Assembly4/blob/master/TECHMANUAL.md
+
+'''
+
+def read_assembly():
+ links=FreeCAD.ActiveDocument.findObjects("App::Link")
+
+ #get all objects of type part feature
+ objs=FreeCAD.ActiveDocument.findObjects("Part::Feature")
+ #get objects in the parts group
+ parts=FreeCAD.ActiveDocument.Parts.Group
+ #get fasteners since fasteners might not be accesed through links
+ #remove objects in parts , coordinate systems
+ #coordinate systems are removed by checking the MapMode attribute
+ #hopefully this is will get only fasteners
+ fasteners=[fast for fast in objs if fast not in parts and not hasattr(fast,'MapMode')]
+
+ #ensure that the link and the fastener are not the same object
+ #this might occur when the parts folder contains some parts that are used in the assembly
+ #get link documents
+ lnk_docs=[lnk.LinkedObject.Document for lnk in links]
+ for fastener in fasteners:
+ if fastener.Document not in lnk_docs:
+ links.append(fastener)
+
+ #links in Assembly4 are of type "App::Link"
+ #this is a list
+ #this will store a list of dictionaries
+ def create_structure(data,dest):
+ #check the parent objects
+ #since data is a list of dictionaries
+ #for every element int he list check if its parent is dest
+ children=[child for child in data if child["parent"]==dest["name"]]
+ #return of no children are found
+ if len (children)==0:
+ return
+ #append the children to the current item
+ for ch in children:
+ dest["children"].append(ch)
+ create_structure(data,ch)
+
+
+ link_data=[]
+ #create the root parent
+ structured_data={}
+
+ #links that have been iterated and not references
+ non_refs=[]
+ for child in links:
+
+ name=child.Label
+ #attachedTo returns a string of the format 'Parent Assembly#LCS_Origin' hence
+ #hence separating by the the '#' and taking the first element will be the parent
+ #the 2nd the coordinate system its attached to
+ parent,attachement=child.AttachedTo.split('#')
+ #returned type has '#' preceeding the coordinate remove it
+ attached_by=child.AttachedBy.replace('#','')
+ if hasattr(child,"LinkedObject") :
+ #get links which refer to the same document
+ ref=[r for r in non_refs if r.LinkedObject.Document ==child.LinkedObject.Document]
+ if len(ref)==1:
+ #set type as reference i.e its a copy of a link that already exists in the assembly
+ link_data.append({"ref_label":ref[0].Label,"type":"ref","link":child,"name":name,"parent":parent,"attached_to":attachement,"attached_by":attached_by,'children':[]})
+ elif len(ref)==0:
+ link_data.append({"ref_label":None,"type":"link","link":child,"name":name,"parent":parent,"attached_to":attachement,"attached_by":attached_by,'children':[]})
+ non_refs.append(child)
+ else:
+ FreeCAD.Console.PrintDeveloperError("parse_asm4:error getting refs no than 1 were found, this is a bug \n")
+ return
+ else:
+ #add fasterners and other too
+ link_data.append({"ref_label":None,"type":"link","link":child,"name":name,"parent":parent,"attached_to":attachement,"attached_by":attached_by,'children':[]})
+
+ #create a hierarchial data
+ if hasattr(child,"LinkedObject"):
+ if hasattr(child.LinkedObject.Document,"Assembly"):
+ FreeCAD.Console.PrintError("Sub assemblies not supported yet \n")
+ return None
+ root_lcs=FreeCAD.ActiveDocument.findObjects("PartDesign::CoordinateSystem")
+ structured_data={"ref_label":None,"type":"link","link":None,'name':"Parent Assembly","attachment":None,"coordinate_systems":root_lcs,"children":[]}
+
+ #this will just create a hierarchial data representation
+ create_structure(link_data,structured_data)
+ del link_data
+ del non_refs
+ return structured_data
+
+
+def get_pose_info():
+ pass
+
diff --git a/robot_descriptor/RD_parser/readme.md b/robot_descriptor/RD_utils/readme.md
similarity index 100%
rename from robot_descriptor/RD_parser/readme.md
rename to robot_descriptor/RD_utils/readme.md
diff --git a/robot_descriptor/RD_globals.py b/robot_descriptor/common.py
similarity index 89%
rename from robot_descriptor/RD_globals.py
rename to robot_descriptor/common.py
index 161d898..2952876 100644
--- a/robot_descriptor/RD_globals.py
+++ b/robot_descriptor/common.py
@@ -14,10 +14,10 @@
-
+import os
import FreeCAD
-ICON_PATH=FreeCAD.getUserAppDataDir()+"Mod/RobotDescriptor/robot_descriptor/icons"
-UI_PATH=FreeCAD.getUserAppDataDir()+"Mod/RobotDescriptor/robot_descriptor/forms"
+ICON_PATH=os.path.join(FreeCAD.getUserAppDataDir()+"Mod","RobotDescriptor","robot_descriptor","icons")
+UI_PATH=os.path.join(FreeCAD.getUserAppDataDir()+"Mod","RobotDescriptor","robot_descriptor","forms")
DOCUMENT=FreeCAD.ActiveDocument
import copy
import xml.etree.ElementTree as ET
@@ -78,7 +78,7 @@ def set_xml_data(element:ET.Element,tag:str,Is_Attribute:bool,value:Union[dict,f
#no need for a loop
try:
elem=elem_iter.__next__()
- except:
+ except Exception:
return None
# ensure no dictionaries are sent for non attributes
if Is_Attribute is False and isinstance(value,dict) is False:
@@ -90,7 +90,7 @@ def set_xml_data(element:ET.Element,tag:str,Is_Attribute:bool,value:Union[dict,f
else:
#add/edit attributes
for key in value.keys():
- elem.set(key,value[key])
+ elem.set(key,str(value[key]))
return element
@@ -114,9 +114,9 @@ def get_value(elem_data):
try:
try:
return int(elem_data)
- except:
+ except Exception:
return float(elem_data)
- except:
+ except Exception:
return elem_data
if Is_Attribute is not True:
@@ -126,7 +126,7 @@ def get_value(elem_data):
#only a single element exists no need to use a for loop
try:
elem=elem_iter.__next__()
- except:
+ except Exception:
return None
if Is_Attribute is False:
txt=elem.text
@@ -138,9 +138,9 @@ def get_value(elem_data):
try:
try:
return int(elem.attrib[tag[1]])
- except:
+ except Exception:
return float(elem.attrib[tag[1]])
- except:
+ except Exception:
return elem.attrib[tag[1]]
#deleting attributes
@@ -165,14 +165,17 @@ def parse_dict(root_dict:dict,path:list):
# used to track the current index of the path list
current_idx=0
+ #if only one element is left return it
if len(path)==1:
if path[-1]=='sdf':
return root_dict[path[-1]]
+ #check if the element exists
elif path[-1] in list(root_dict.keys()):
return root_dict[path[-1]]
else:
return None
else:
+ #get the first item in the dictionary
parent_key=path[current_idx]
current_idx+=1
#child element tag
@@ -202,6 +205,7 @@ def update_dictionary(path:list,child_tag:Union[str,None],elem:Union[list,ET.Ele
parent_dict=parse_dict(elem_dict,path)
if parent_dict is not None:
+ #this allows update of an element not its children basically None means not the children
if child_tag is None:
if isinstance(elem,list):
parent_dict["elem_str"]=list(map(lambda e:ET.tostring(e,encoding="unicode"),elem))
@@ -245,14 +249,19 @@ def merge_elements(destination_el:ET.Element,source_el:ET.Element,recursive:bool
#implemtatation for all other elements
#the ones that are not recursive and not physics
else:
+ # Update attributes of destination_el with source_el
destination_el.attrib.update(source_el.attrib)
+ if source_el.text:
+ destination_el.text = source_el.text
+ # Merge child elements recursively
for child in source_el:
- existing_el=destination_el.find(child.tag)
+ existing_el = destination_el.find(child.tag)
if existing_el is not None:
- destination_el.remove(existing_el)
- destination_el.append(child)
+ merge_elements(existing_el, child) # Recursively merge the existing element with the new one
else:
- destination_el.append(child)
+ # If the element doesn't exist in destination, simply append it
+ # destination_el.append(child)
+ pass
import math
@@ -260,6 +269,8 @@ def merge_elements(destination_el:ET.Element,source_el:ET.Element,recursive:bool
class color_pickr:
+ '''class that implements color picker methods
+ '''
def __init__(self) -> None:
pass
#color picker
diff --git a/robot_descriptor/forms/collision.ui b/robot_descriptor/forms/collision.ui
new file mode 100644
index 0000000..506c6da
--- /dev/null
+++ b/robot_descriptor/forms/collision.ui
@@ -0,0 +1,147 @@
+
+
+ collision
+
+
+
+ 0
+ 0
+ 662
+ 682
+
+
+
+ collision
+
+
+ -
+
+
+
+ 644
+ 650
+
+
+
+
-
+
+
-
+
+
+ laser_retro
+
+
+
+ -
+
+
+ false
+
+
+
+ -
+
+
+ max_contacts
+
+
+
+ -
+
+
+ false
+
+
+
+
+
+ -
+
+
+ include_surface_info
+
+
+
+ -
+
+
+ false
+
+
+
+ 16777215
+ 587
+
+
+
+ true
+
+
+
+
+ 0
+ 0
+ 624
+ 585
+
+
+
+
+
+
+
+
+
+
+
+
+
+ collision_laser_retro_cb
+ toggled(bool)
+ collision_laser_retro_sp
+ setEnabled(bool)
+
+
+ 94
+ 30
+
+
+ 252
+ 30
+
+
+
+
+ collison_max_contacts_cb
+ toggled(bool)
+ collision_max_contacts_sp
+ setEnabled(bool)
+
+
+ 409
+ 30
+
+
+ 567
+ 30
+
+
+
+
+ include_surface_info_cb
+ toggled(bool)
+ collision_scroll
+ setEnabled(bool)
+
+
+ 330
+ 60
+
+
+ 330
+ 415
+
+
+
+
+
diff --git a/robot_descriptor/forms/link.ui b/robot_descriptor/forms/link.ui
new file mode 100644
index 0000000..a09496d
--- /dev/null
+++ b/robot_descriptor/forms/link.ui
@@ -0,0 +1,1617 @@
+
+
+ link
+
+
+
+ 0
+ 0
+ 715
+ 668
+
+
+
+ link
+
+
+ -
+
+
+
+ 697
+ 650
+
+
+
+
+ 16777215
+ 650
+
+
+
+
-
+
+
+
+ 215
+ 100
+
+
+
+
+ 16777215
+ 110
+
+
+
+ link states
+
+
+ true
+
+
+ true
+
+
+
-
+
+
+ If true, the link is affected by gravity
+
+
+ gravity
+
+
+
+ -
+
+
+ If true, the link is affected by the wind
+
+
+ enable_wind
+
+
+
+ -
+
+
+ If true, the link is kinematic only
+
+
+ kinematic
+
+
+
+ -
+
+
+ If true, the link can collide with other links in the model.
+Two links within a model will collide if link1.self_collide OR link2.self_collide.
+Links connected by a joint will never collide
+
+
+ self_collide
+
+
+
+
+
+
+ -
+
+
+
+ 414
+ 600
+
+
+
+ true
+
+
+
+
+ 0
+ 0
+ 440
+ 918
+
+
+
+
-
+
+
+ false
+
+
+
+ 348
+ 900
+
+
+
+
+ 413
+ 950
+
+
+
+ This link's fluid added mass matrix about the link's origin.
+ This matrix represents the inertia of the fluid that is dislocated when the
+ body moves. Added mass should be zero if the density of the surrounding
+ fluid is negligible with respect to the body's density.
+ The 6x6 matrix is symmetric, therefore only 21 unique elements can be set.
+ The elements of the matrix follow the [x, y, z, p, q, r] notation, where
+ [x, y, z] correspond to translation and [p, q, r] to rotation
+
+
+ fluid_added_mass
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+
+ 370
+ 200
+
+
+
+
+ 372
+ 190
+
+
+
+ x_axis
+
+
+
+
+ 18
+ 28
+ 344
+ 75
+
+
+
+
+ 340
+ 75
+
+
+
+
+ 344
+ 78
+
+
+
+ Added mass in the X axis due to linear acceleration in the x,y,z axes
+
+
+ linear_acceleration
+
+
+
-
+
+
+
+ 12
+ 24
+
+
+
+
+ 15
+ 30
+
+
+
+ x
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 90
+ 24
+
+
+
+
+ 100
+ 30
+
+
+
+ Added mass in the X axis due to linear acceleration in the X axis, in kg
+
+
+ kg
+
+
+ 1000.000000000000000
+
+
+
+ -
+
+
+
+ 12
+ 24
+
+
+
+
+ 15
+ 30
+
+
+
+ y
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 90
+ 24
+
+
+
+
+ 100
+ 30
+
+
+
+ Added mass in the X axis due to linear acceleration in the Y axis, and vice-versa, in kg.
+
+
+ kg
+
+
+ 1000.000000000000000
+
+
+
+ -
+
+
+
+ 12
+ 24
+
+
+
+
+ 15
+ 30
+
+
+
+ z
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 90
+ 24
+
+
+
+ Added mass in the X axis due to linear acceleration in the Z axis, and vice-versa, in kg.
+
+
+ kg
+
+
+ 1000.000000000000000
+
+
+
+
+
+
+
+
+ 12
+ 108
+ 345
+ 75
+
+
+
+
+ 343
+ 75
+
+
+
+
+ 345
+ 78
+
+
+
+ Added mass in the X axis due to linear acceleration in the x,y,z axes
+
+
+ angular_acceleration
+
+
+ -
+
+
+
+ 12
+ 24
+
+
+
+
+ 15
+ 30
+
+
+
+ x
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 90
+ 24
+
+
+
+
+ 100
+ 30
+
+
+
+ Added mass in the X axis due to angular acceleration about the X axis, and vice-versa, in kg * m.
+
+
+ kgm
+
+
+ 1000.000000000000000
+
+
+
+ -
+
+
+
+ 12
+ 24
+
+
+
+
+ 15
+ 30
+
+
+
+ y
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 90
+ 24
+
+
+
+
+ 100
+ 30
+
+
+
+ Added mass in the X axis due to angular acceleration about the Y axis, and vice-versa, in kg * m.
+
+
+ kgm
+
+
+ 1000.000000000000000
+
+
+
+ -
+
+
+
+ 12
+ 24
+
+
+
+
+ 15
+ 30
+
+
+
+ z
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 90
+ 24
+
+
+
+
+ 100
+ 30
+
+
+
+ Added mass in the X axis due to angular acceleration about the Z axis, and vice-versa, in kg * m
+
+
+ kgm
+
+
+ 1000.000000000000000
+
+
+
+
+
+
+
+ -
+
+
+
+ 370
+ 205
+
+
+
+
+ 372
+ 190
+
+
+
+ y_axis
+
+
+
-
+
+
+
+ 343
+ 75
+
+
+
+
+ 344
+ 78
+
+
+
+ Added mass in the X axis due to linear acceleration in the x,y,z axes
+
+
+ linear_acceleration
+
+
+
-
+
+
+
+ 12
+ 24
+
+
+
+
+ 15
+ 30
+
+
+
+ y
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 90
+ 24
+
+
+
+
+ 100
+ 30
+
+
+
+ Added mass in the Y axis due to linear acceleration in the Y axis, in kg
+
+
+ kg
+
+
+ 1000.000000000000000
+
+
+
+ -
+
+
+
+ 10
+ 15
+
+
+
+
+ 10
+ 18
+
+
+
+ z
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 90
+ 24
+
+
+
+
+ 100
+ 30
+
+
+
+ Added mass in the Y axis due to linear acceleration in the Z axis, and vice-versa, in kg.
+
+
+ kg
+
+
+ 1000.000000000000000
+
+
+
+
+
+
+ -
+
+
+
+ 343
+ 75
+
+
+
+
+ 345
+ 78
+
+
+
+ Added mass in the X axis due to linear acceleration in the x,y,z axes
+
+
+ angular_acceleration
+
+
+
-
+
+
+
+ 12
+ 24
+
+
+
+
+ 15
+ 30
+
+
+
+ x
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 90
+ 24
+
+
+
+
+ 100
+ 30
+
+
+
+ Added mass in the Y axis due to angular acceleration about the X axis, and vice-versa, in kg * m
+
+
+ kgm
+
+
+ 1000.000000000000000
+
+
+
+ -
+
+
+
+ 12
+ 24
+
+
+
+
+ 15
+ 30
+
+
+
+ y
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 90
+ 24
+
+
+
+
+ 100
+ 30
+
+
+
+ Added mass in the Y axis due to angular acceleration about the Y axis, and vice-versa, in kg * m.
+
+
+ kgm
+
+
+ 1000.000000000000000
+
+
+
+ -
+
+
+
+ 12
+ 24
+
+
+
+
+ 15
+ 30
+
+
+
+ z
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 90
+ 24
+
+
+
+
+ 100
+ 30
+
+
+
+ Added mass in the Y axis due to angular acceleration about the Z axis, and vice-versa, in kg * m.
+
+
+ kgm
+
+
+ 1000.000000000000000
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 370
+ 190
+
+
+
+
+ 372
+ 190
+
+
+
+ z_axis
+
+
+
-
+
+
+
+ 343
+ 75
+
+
+
+
+ 344
+ 78
+
+
+
+ Added mass in the X axis due to linear acceleration in the x,y,z axes
+
+
+ linear_acceleration
+
+
+
+
+ 81
+ 32
+ 139
+ 26
+
+
+
+
-
+
+
+
+ 12
+ 24
+
+
+
+
+ 15
+ 30
+
+
+
+ z
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 90
+ 24
+
+
+
+
+ 100
+ 30
+
+
+
+ Added mass in the Z axis due to linear acceleration in the Z axis, in kg.
+
+
+ kg
+
+
+ 1000.000000000000000
+
+
+
+
+
+
+
+ -
+
+
+
+ 343
+ 75
+
+
+
+
+ 345
+ 78
+
+
+
+ Added mass in the X axis due to linear acceleration in the x,y,z axes
+
+
+ angular_acceleration
+
+
+
-
+
+
+
+ 12
+ 24
+
+
+
+
+ 15
+ 30
+
+
+
+ x
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 90
+ 24
+
+
+
+
+ 100
+ 30
+
+
+
+ Added mass in the Z axis due to angular acceleration about the X axis, and vice-versa, in kg * m.
+
+
+ kgm
+
+
+ 1000.000000000000000
+
+
+
+ -
+
+
+
+ 12
+ 24
+
+
+
+
+ 15
+ 30
+
+
+
+ y
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 90
+ 24
+
+
+
+
+ 100
+ 30
+
+
+
+ Added mass in the Z axis due to angular acceleration about the Y axis, and vice-versa, in kg * m.
+
+
+ kgm
+
+
+ 1000.000000000000000
+
+
+
+ -
+
+
+
+ 12
+ 24
+
+
+
+
+ 15
+ 30
+
+
+
+ z
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 90
+ 24
+
+
+
+
+ 100
+ 30
+
+
+
+ Added mass in the Z axis due to angular acceleration about the Z axis, and vice-versa, in kg * m.
+
+
+ kgm
+
+
+ 1000.000000000000000
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 370
+ 255
+
+
+
+
+ 372
+ 300
+
+
+
+ moment
+
+
+
-
+
+
+
+ 343
+ 75
+
+
+
+
+ 345
+ 78
+
+
+
+ Added mass in the X axis due to linear acceleration in the x,y,z axes
+
+
+ moment_x
+
+
+
-
+
+
+
+ 12
+ 24
+
+
+
+
+ 15
+ 30
+
+
+
+ x
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 90
+ 24
+
+
+
+
+ 100
+ 30
+
+
+
+ Added mass moment about the X axis due to angular acceleration about the X axis, in kg * m^2.
+
+
+ kgm^2
+
+
+ 1000.000000000000000
+
+
+
+ -
+
+
+
+ 12
+ 24
+
+
+
+
+ 15
+ 30
+
+
+
+ y
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 90
+ 24
+
+
+
+
+ 100
+ 30
+
+
+
+ Added mass moment about the X axis due to angular acceleration about the Y axis, and vice-versa, in kg * m^2
+
+
+ kgm^2
+
+
+ 1000.000000000000000
+
+
+
+ -
+
+
+
+ 12
+ 24
+
+
+
+
+ 15
+ 30
+
+
+
+ z
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 90
+ 24
+
+
+
+
+ 100
+ 30
+
+
+
+ Added mass moment about the X axis due to angular acceleration about the Z axis, and vice-versa, in kg * m^2.
+
+
+ kgm^2
+
+
+ 1000.000000000000000
+
+
+
+
+
+
+ -
+
+
+
+ 343
+ 75
+
+
+
+
+ 345
+ 78
+
+
+
+ Added mass in the X axis due to linear acceleration in the x,y,z axes
+
+
+ moment_y
+
+
+
-
+
+
-
+
+
+
+ 12
+ 24
+
+
+
+
+ 15
+ 30
+
+
+
+ y
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 90
+ 24
+
+
+
+
+ 100
+ 30
+
+
+
+ Added mass moment about the Y axis due to angular acceleration about the Y axis, in kg * m^2
+
+
+ kgm^2
+
+
+ 1000.000000000000000
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 12
+ 24
+
+
+
+
+ 15
+ 30
+
+
+
+ z
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 90
+ 24
+
+
+
+
+ 100
+ 30
+
+
+
+ Added mass moment about the Y axis due to angular acceleration about the Z axis, and vice-versa, in kg * m^2
+
+
+ kgm^2
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 343
+ 75
+
+
+
+
+ 344
+ 78
+
+
+
+ Added mass in the X axis due to linear acceleration in the x,y,z axes
+
+
+ moment_z
+
+
+
-
+
+
-
+
+
+
+ 10
+ 15
+
+
+
+
+ 10
+ 18
+
+
+
+ z
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 90
+ 24
+
+
+
+
+ 100
+ 30
+
+
+
+ Added mass moment about the Z axis due to angular acceleration about the Z axis, in kg * m^2
+
+
+ kgm^2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 217
+ 110
+
+
+
+
+ 16777215
+ 120
+
+
+
+ Exponential damping of the link's velocity.
+
+
+ velocity_decay
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+
+ 35
+ 15
+
+
+
+
+ 45
+ 16
+
+
+
+ linear
+
+
+
+ -
+
+
+ 5
+
+
+ 1000.000000000000000
+
+
+
+ -
+
+
+
+ 50
+ 25
+
+
+
+
+ 55
+ 27
+
+
+
+ angular
+
+
+
+ -
+
+
+ 5
+
+
+ 1000.000000000000000
+
+
+
+
+
+
+ -
+
+
+ false
+
+
+
+ 213
+ 70
+
+
+
+
+ 16777215
+ 70
+
+
+
+ inertial
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+ auto
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 481
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/robot_descriptor/forms/material.ui b/robot_descriptor/forms/material.ui
index faf70fa..e2ea512 100644
--- a/robot_descriptor/forms/material.ui
+++ b/robot_descriptor/forms/material.ui
@@ -1,530 +1,228 @@
- Form
-
+ material
+
0
0
- 573
- 690
+ 548
+ 1545
- Form
+ material
-
+
- 8
- 82
- 259
- 89
+ 0
+ 14
+ 538
+ 1536
-
-
- 0
- 89
-
-
-
- script
-
-
- true
-
-
- false
-
-
-
-
- 18
- 28
- 16
- 15
-
-
-
- uri
-
-
-
-
-
- 52
- 24
- 175
- 23
-
-
-
-
-
-
- 12
- 56
- 34
- 15
-
-
-
- name
-
-
-
-
-
- 52
- 52
- 113
- 23
-
-
-
-
-
-
-
- 280
- 84
- 259
- 89
-
-
-
-
- 0
- 89
-
-
-
- shader
-
-
- true
-
-
- false
-
-
-
-
- 12
- 32
- 57
- 15
-
-
-
- TextLabel
-
-
-
-
-
- 80
- 28
- 79
- 23
-
-
- -
-
- vertex
-
-
- -
-
- pixel
-
-
- -
-
- normal_map_object_space
-
-
- -
-
- normal_map_tangent_space
-
-
-
-
-
-
- 8
- 60
- 100
- 21
-
-
-
- normal_map
-
-
-
-
-
- 114
- 60
- 113
- 23
-
-
-
-
-
-
-
- 10
- 184
- 78
- 24
-
-
-
-
- 0
- 24
-
-
-
- render_order
-
-
-
-
-
- 94
- 180
- 83
- 24
-
-
-
-
- 0
- 24
-
-
-
- Set render order for coplanar polygons. The higher value will be rendered on top of the other coplanar polygons
-
-
-
-
-
- 8
- 650
- 85
- 24
-
-
-
-
- 0
- 24
-
-
-
- lighting
-
-
-
-
-
- 4
- 210
- 520
- 100
-
-
-
-
- 520
- 100
-
-
- 520
- 100
+ 538
+ 2000
-
- background color
-
-
- ambient
-
-
- true
-
-
- false
-
-
- -
-
-
-
- 0
- 24
-
-
-
-
- 16777215
- 24
-
-
-
-
- -
-
-
-
- 16777215
- 24
-
-
-
- B
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 16777215
- 24
-
-
-
- A
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 16777215
- 24
-
-
-
- R
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 0
- 24
-
-
-
-
- 16777215
- 24
-
-
-
-
- -
-
+
+
-
+
- 0
- 24
+ 240
+ 89
- 16777215
- 24
+ 240
+ 95
+
+ script
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+ uri
+
+
+
+ -
+
+
+
+ 160
+ 16777215
+
+
+
+
+ -
+
+
+
+ 50
+ 24
+
+
+
+ name
+
+
+
+ -
+
+
+
+ 115
+ 16777215
+
+
+
+
+
- -
-
-
-
- 16777215
- 24
-
-
-
- G
-
-
- Qt::AlignCenter
-
-
-
- -
-
+
-
+
- 0
- 24
+ 240
+ 95
- 16777215
- 24
+ 240
+ 95
+
+ shader
+
+
+ true
+
+
+ false
+
+
+
+
+ 12
+ 30
+ 57
+ 16
+
+
+
+ type
+
+
+
+
+
+ 82
+ 26
+ 100
+ 21
+
+
+
+
+ 100
+ 16777215
+
+
+
-
+
+ pixel
+
+
+ -
+
+ vertex
+
+
+ -
+
+ normal_map_object_space
+
+
+ -
+
+ normal_map_tangent_space
+
+
+
+
+
+
+ 12
+ 57
+ 100
+ 20
+
+
+
+ normal_map
+
+
+
+
+ false
+
+
+
+ 118
+ 57
+ 100
+ 20
+
+
+
+
+ 100
+ 16777215
+
+
+
- -
-
-
-
- 45
- 16777215
-
-
-
-
-
-
-
-
-
-
-
-
- 6
- 322
- 520
- 100
-
-
-
-
- 520
- 100
-
-
-
-
- 520
- 100
-
-
-
- background color
-
-
- diffuse
-
-
- true
-
-
- false
-
-
-
-
+
- 0
- 24
-
-
-
-
- 16777215
- 24
-
-
-
-
- -
-
-
-
- 16777215
- 24
-
-
-
- B
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 16777215
+ 85
24
-
- A
-
-
- Qt::AlignCenter
-
-
-
- -
-
- 16777215
- 24
+ 85
+ 28
- R
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 0
- 24
-
-
-
-
- 16777215
- 24
-
+ render_order
-
-
+
0
@@ -533,207 +231,631 @@
- 16777215
- 24
+ 100
+ 105
-
-
- -
-
-
-
- 16777215
- 24
-
-
-
- G
-
-
- Qt::AlignCenter
+
+ Set render order for coplanar polygons. The higher value will be rendered on top of the other coplanar polygons
- -
-
-
-
- 0
- 24
-
-
-
-
- 16777215
- 24
-
-
-
-
- -
-
+
-
+
- 45
+ 56
16777215
-
+ shininess
-
-
-
-
-
- 6
- 434
- 520
- 100
-
-
-
-
- 520
- 100
-
-
-
-
- 520
- 100
-
-
-
- background color
-
-
- specular
-
-
- true
-
-
- false
-
-
- -
-
+
-
+
- 0
+ 90
24
- 16777215
- 24
+ 100
+ 27
- -
-
-
+
-
+
+
- 16777215
- 24
+ 520
+ 100
-
- B
-
-
- Qt::AlignCenter
-
-
-
- -
-
- 16777215
- 24
+ 520
+ 100
-
- A
-
-
- Qt::AlignCenter
-
+
+ background color
+
+
+ diffuse
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+
+ 16777215
+ 24
+
+
+
+ A
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+
+ 16777215
+ 24
+
+
+
+ B
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 45
+ 16777215
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+
+ 16777215
+ 24
+
+
+
+ G
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+
+ 16777215
+ 24
+
+
+
+ R
+
+
+ Qt::AlignCenter
+
+
+
+
- -
-
-
-
- 16777215
- 24
-
-
-
- R
-
-
- Qt::AlignCenter
-
-
-
- -
-
+
-
+
- 0
- 24
+ 520
+ 100
- 16777215
- 24
+ 520
+ 100
+
+ background color
+
+
+ specular
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+
+ 16777215
+ 24
+
+
+
+ B
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 16777215
+ 24
+
+
+
+ A
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 16777215
+ 24
+
+
+
+ R
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+
+ 16777215
+ 24
+
+
+
+ G
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+
+ 45
+ 16777215
+
+
+
+
+
+
+
+
- -
-
+
-
+
- 0
- 24
+ 520
+ 100
- 16777215
- 24
-
-
-
-
- -
-
-
-
- 16777215
- 24
+ 520
+ 100
-
- G
-
-
- Qt::AlignCenter
-
+
+ background color
+
+
+ emissive
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+
+ 16777215
+ 24
+
+
+
+ B
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 16777215
+ 24
+
+
+
+ A
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 16777215
+ 24
+
+
+
+ R
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+
+ 16777215
+ 24
+
+
+
+ G
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+
+ 45
+ 16777215
+
+
+
+
+
+
+
+
- -
-
+
-
+
0
@@ -742,63 +864,17 @@
- 16777215
- 24
-
-
-
-
- -
-
-
-
- 45
- 16777215
+ 120
+ 25
-
+ lighting
-
-
-
-
-
- 6
- 544
- 520
- 100
-
-
-
-
- 520
- 100
-
-
-
-
- 520
- 100
-
-
-
- background color
-
-
- emissive
-
-
- true
-
-
- false
-
-
- -
-
+
-
+
0
@@ -807,312 +883,1091 @@
- 16777215
- 24
-
-
-
-
- -
-
-
-
- 16777215
- 24
+ 120
+ 25
- B
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 16777215
- 24
-
-
-
- A
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 16777215
- 24
-
-
-
- R
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 0
- 24
-
-
-
-
- 16777215
- 24
-
+ double_sided
- -
-
+
-
+
- 0
- 24
-
-
-
-
- 16777215
- 24
+ 470
+ 933
-
-
- -
-
- 16777215
- 24
+ 520
+ 1100
-
- G
-
-
- Qt::AlignCenter
-
+
+ pbr
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+ metal
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+ albedo_map
+
+
+
+ -
+
+
+ false
+
+
+
+ -
+
+
+ roughness_map
+
+
+
+ -
+
+
+ false
+
+
+
+ -
+
+
+ roughness
+
+
+
+ -
+
+
+ false
+
+
+
+ -
+
+
+ metalness_map
+
+
+
+ -
+
+
+ false
+
+
+
+ -
+
+
+ metalness
+
+
+
+ -
+
+
+ false
+
+
+
+ 250
+ 24
+
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+ environment_map
+
+
+
+ -
+
+
+ false
+
+
+
+ -
+
+
+ ambient_occlusion_map
+
+
+
+ -
+
+
+ false
+
+
+
+ -
+
+
+ emissive_map
+
+
+
+ -
+
+
+ false
+
+
+
+ -
+
+
+
+ 100
+ 140
+
+
+
+
+ 210
+ 140
+
+
+
+ normal_map
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+
+ 0
+ 24
+
+
+
+
+ -
+
+
+
+ 50
+ 24
+
+
+
+
+ 75
+ 26
+
+
+
+ type
+
+
+
+ -
+
+
+
+ 105
+ 24
+
+
+
+
+ 110
+ 27
+
+
+
-
+
+ tangent
+
+
+ -
+
+ object
+
+
+
+
+
+
+
+ -
+
+
+
+ 220
+ 75
+
+
+
+
+ 250
+ 140
+
+
+
+ light_map
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+
+ 135
+ 24
+
+
+
+
+ 175
+ 27
+
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+ uv_set
+
+
+
+ -
+
+
+ false
+
+
+
+ 90
+ 24
+
+
+
+
+ 120
+ 27
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 400
+ 370
+
+
+
+
+ 450
+ 370
+
+
+
+ specular
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+ albedo_map
+
+
+
+ -
+
+
+ specular_map
+
+
+
+ -
+
+
+ glossiness
+
+
+
+ -
+
+
+ false
+
+
+
+ 250
+ 24
+
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+ environment_map
+
+
+
+ -
+
+
+ ambient_occlusion_map
+
+
+
+ -
+
+
+ false
+
+
+
+ -
+
+
+ emissive_map
+
+
+
+ -
+
+
+ glossiness_map
+
+
+
+ -
+
+
+
+ 200
+ 100
+
+
+
+
+ 210
+ 130
+
+
+
+ light_map
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+
+ 100
+ 24
+
+
+
+
+ 170
+ 30
+
+
+
+
+ -
+
+
+
+ 50
+ 24
+
+
+
+
+ 95
+ 30
+
+
+
+ uv_set
+
+
+
+ -
+
+
+ false
+
+
+
+ 85
+ 24
+
+
+
+
+
+
+
+ -
+
+
+
+ 200
+ 94
+
+
+
+
+ 300
+ 130
+
+
+
+ normal_map
+
+
+ false
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+ -
+
+
+ type
+
+
+
+ -
+
+
-
+
+ tangent
+
+
+ -
+
+ object
+
+
+
+
+
+
+
+ -
+
+
+ false
+
+
+
+ -
+
+
+ false
+
+
+
+ -
+
+
+ false
+
+
+
+ -
+
+
+ false
+
+
+
+ -
+
+
+ false
+
+
+
+
+
+
+
- -
-
+
-
+
- 0
- 24
+ 520
+ 100
- 16777215
- 24
+ 520
+ 100
-
-
- -
-
-
-
- 45
- 16777215
-
-
-
-
-
+
+ background color
+
+
+ ambient
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+
+ 16777215
+ 24
+
+
+
+ B
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 16777215
+ 24
+
+
+
+ A
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 16777215
+ 24
+
+
+
+ R
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+
+ 16777215
+ 24
+
+
+
+ G
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+
+ 45
+ 16777215
+
+
+
+
+
+
+
+
-
-
-
- 382
- 184
- 57
- 15
-
-
-
- shininess
-
-
-
-
-
- 446
- 180
- 87
- 24
-
-
-
-
- 0
- 24
-
-
-
-
-
-
- 116
- 650
- 105
- 24
-
-
-
-
- 0
- 24
-
-
-
- double_sided
-
-
-
-
-
- 60
- 52
- 62
- 24
-
-
-
-
- 0
- 24
-
-
-
-
-
-
- 446
- 20
- 80
- 24
-
-
-
-
- 0
- 24
-
-
-
- browse
-
-
-
-
-
- 326
- 20
- 113
- 24
-
-
-
-
- 0
- 24
-
-
-
-
-
-
- 282
- 18
- 37
- 24
-
-
-
-
- 0
- 24
-
-
-
- points
-
-
-
-
-
- 18
- 52
- 34
- 24
-
-
-
-
- 0
- 24
-
-
-
- width
-
-
-
-
-
- 62
- 18
- 113
- 24
-
-
-
-
- 0
- 24
-
-
-
-
-
-
- 16
- 18
- 34
- 24
-
-
-
-
- 0
- 24
-
-
-
- name
-
-
-
+
+
+ metal_albedo_map_checkBox
+ toggled(bool)
+ metal_albedo_map_lineEdit
+ setEnabled(bool)
+
+
+ 140
+ 689
+
+
+ 356
+ 689
+
+
+
+
+ metal_roughness_map_checkBox
+ toggled(bool)
+ metal_roughness_map_lineEdit
+ setEnabled(bool)
+
+
+ 140
+ 728
+
+
+ 356
+ 728
+
+
+
+
+ metal_roughness_checkBox
+ toggled(bool)
+ metal_roughness_lineEdit
+ setEnabled(bool)
+
+
+ 140
+ 767
+
+
+ 356
+ 767
+
+
+
+
+ metalness_map_checkBox
+ toggled(bool)
+ metalness_map_lineEdit
+ setEnabled(bool)
+
+
+ 140
+ 806
+
+
+ 356
+ 806
+
+
+
+
+ metalness_checkBox
+ toggled(bool)
+ metalness_sp
+ setEnabled(bool)
+
+
+ 140
+ 845
+
+
+ 356
+ 845
+
+
+
+
+ metal_environment_map_checkBox
+ toggled(bool)
+ metal_environment_map_lineEdit
+ setEnabled(bool)
+
+
+ 140
+ 885
+
+
+ 356
+ 885
+
+
+
+
+ metal_ambient_occlusion_map_checkBox
+ toggled(bool)
+ metal_ambient_occlusion_map_lineEdit
+ setEnabled(bool)
+
+
+ 140
+ 924
+
+
+ 356
+ 924
+
+
+
+
+ metal_emissive_map_checkBox
+ toggled(bool)
+ metal_emissive_map_lineEdit
+ setEnabled(bool)
+
+
+ 140
+ 963
+
+
+ 356
+ 963
+
+
+
+
+ metal_uv_set_checkBox
+ toggled(bool)
+ metal_uv_set_sp
+ setEnabled(bool)
+
+
+ 321
+ 1091
+
+
+ 422
+ 1091
+
+
+
+
+ normal_map_checkBox
+ toggled(bool)
+ material_normal_map_input
+ setEnabled(bool)
+
+
+ 334
+ 89
+
+
+ 440
+ 89
+
+
+
+
+ specular_albedo_map_checkBox
+ toggled(bool)
+ specular_albedo_map_lineEdit
+ setEnabled(bool)
+
+
+ 122
+ 1200
+
+
+ 338
+ 1200
+
+
+
+
+ specular_map_checkBox
+ toggled(bool)
+ specular_map_lineEdit
+ setEnabled(bool)
+
+
+ 122
+ 1229
+
+
+ 338
+ 1229
+
+
+
+
+ specular_glossiness_map_checkBox
+ toggled(bool)
+ specular_glossiness_map_lineEdit
+ setEnabled(bool)
+
+
+ 122
+ 1375
+
+
+ 338
+ 1375
+
+
+
+
+ specular_glossiness_checkBox
+ toggled(bool)
+ specular_glossiness_sp
+ setEnabled(bool)
+
+
+ 122
+ 1258
+
+
+ 338
+ 1258
+
+
+
+
+ specular_environment_map_checkBox
+ toggled(bool)
+ specular_environment_map_lineEdit
+ setEnabled(bool)
+
+
+ 122
+ 1288
+
+
+ 338
+ 1288
+
+
+
+
+ specular_ambient_occlusion_map_checkBox
+ toggled(bool)
+ specular_ambient_occlusion_map_lineEdit
+ setEnabled(bool)
+
+
+ 155
+ 1317
+
+
+ 374
+ 1317
+
+
+
+
+ specular_emissive_map_checkBox
+ toggled(bool)
+ specular_emissive_map_lineEdit
+ setEnabled(bool)
+
+
+ 122
+ 1346
+
+
+ 338
+ 1346
+
+
+
+
+ specular_uv_set_checkBox
+ toggled(bool)
+ specular_uv_set_sp
+ setEnabled(bool)
+
+
+ 110
+ 1484
+
+
+ 201
+ 1484
+
+
+
+
diff --git a/robot_descriptor/forms/surface.ui b/robot_descriptor/forms/surface.ui
new file mode 100644
index 0000000..145d935
--- /dev/null
+++ b/robot_descriptor/forms/surface.ui
@@ -0,0 +1,1717 @@
+
+
+ Form
+
+
+
+ 0
+ 0
+ 600
+ 810
+
+
+
+
+ 600
+ 0
+
+
+
+
+ 653
+ 16777215
+
+
+
+ Form
+
+
+ -
+
+
+
-
+
+
+ surface
+
+
+
-
+
+
+ bounce
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+
+ 90
+ 24
+
+
+
+
+ 110
+ 27
+
+
+
+ Bounciness coefficient of restitution, from [0...1], where 0=no bounciness
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+ threshold
+
+
+
+ -
+
+
+
+ 90
+ 24
+
+
+
+
+ 110
+ 27
+
+
+
+ Bounce capture velocity, below which effective coefficient of restitution is 0
+
+
+ 10000.000000000000000
+
+
+ 1.000000000000000
+
+
+
+ -
+
+
+ restitution_coefficient
+
+
+
+
+
+
+ -
+
+
+ true
+
+
+
+ 0
+ 630
+
+
+
+ 0
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+
+ friction
+
+
+
-
+
+
+
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+
+ 508
+ 16777215
+
+
+
+ bullet
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+ friction
+
+
+
+ -
+
+
+ false
+
+
+ Coefficient of friction in first friction pyramid direction,
+ the unitless maximum ratio of force in first friction pyramid
+ direction to normal force
+
+
+
+ -
+
+
+ friction2
+
+
+
+ -
+
+
+ false
+
+
+ Coefficient of friction in second friction pyramid direction,
+ the unitless maximum ratio of force in second friction pyramid
+ direction to normal force
+
+
+
+ -
+
+
+ rolling_friction
+
+
+
+ -
+
+
+ false
+
+
+ Coefficient of rolling friction
+
+
+
+ -
+
+
+
+ 500
+ 465
+
+
+
+ Unit vector specifying first friction pyramid direction in
+ collision-fixed reference frame
+
+
+ fdir1
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+
+ 27
+ 16777215
+
+
+
+ x
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+
+ 27
+ 16777215
+
+
+
+ y
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 27
+ 27
+
+
+
+ z
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 205
+
+
+
+
+ 505
+ 220
+
+
+
+ ODE
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+ mu
+
+
+
+ -
+
+
+ false
+
+
+ Coefficient of friction in first friction pyramid direction,
+ the unitless maximum ratio of force in first friction pyramid
+ direction to normal force.
+
+
+
+ -
+
+
+ slip1
+
+
+
+ -
+
+
+ false
+
+
+ Force dependent slip in first friction pyramid direction,
+equivalent to inverse of viscous damping coefficient
+ with units of m/s/N.
+ A slip value of 0 is infinitely viscous
+
+
+
+ -
+
+
+ mu2
+
+
+
+ -
+
+
+ false
+
+
+ Coefficient of friction in second friction pyramid direction,
+ the unitless maximum ratio of force in second friction pyramid
+ direction to normal force.
+
+
+
+ -
+
+
+ slip2
+
+
+
+ -
+
+
+ false
+
+
+ Force dependent slip in second friction pyramid direction,
+ equivalent to inverse of viscous damping coefficient
+ with units of m/s/N.
+ A slip value of 0 is infinitely viscous.
+
+
+
+ -
+
+
+
+ 500
+ 465
+
+
+
+ unit vector specifying first friction pyramid direction in
+ collision-fixed reference frame.
+ If the friction pyramid model is in use,
+ and this value is set to a unit vector for one of the
+ colliding surfaces
+
+
+ fdir1
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+
+ 27
+ 16777215
+
+
+
+ x
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+
+ 27
+ 16777215
+
+
+
+ y
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 27
+ 27
+
+
+
+ z
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 160
+
+
+
+
+ 533
+ 170
+
+
+
+ torsional
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+
+ 0
+ 24
+
+
+
+
+ 70
+ 16777215
+
+
+
+ coefficient
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 90
+ 16777215
+
+
+
+ Torsional friction coefficient, unitless maximum ratio of
+ tangential stress to normal stress.
+
+
+
+ -
+
+
+ ode
+
+
+ true
+
+
+ false
+
+
+
+
+ 24
+ 62
+ 57
+ 15
+
+
+
+ slip
+
+
+
+
+
+ 95
+ 58
+ 83
+ 23
+
+
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 130
+ 16777215
+
+
+
+ If this flag is true,
+ torsional friction is calculated using the "patch_radius" parameter.
+ If this flag is set to false,
+ "surface_radius" (R) and contact depth (d)
+ are used to compute the patch radius as sqrt(R*d).
+
+
+ use_patch_radius
+
+
+
+ -
+
+
+
+ 95
+ 24
+
+
+
+
+ 80
+ 16777215
+
+
+
+ patch_radius
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 90
+ 16777215
+
+
+
+ Radius of contact patch surface
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 130
+ 16777215
+
+
+
+ surface_radius
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 90
+ 16777215
+
+
+
+ Surface radius on the point of contact
+
+
+
+
+
+
+
+
+
+
+
+
+
+ contact
+
+
+ -
+
+
+
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+
+ 220
+ 16777215
+
+
+
+ Flag to disable contact force generation, while still allowing collision checks and contact visualization to occur
+
+
+ collide_without_contact
+
+
+
+ -
+
+
+
+ 220
+ 16777215
+
+
+
+ collide_without_contact_bitmask
+
+
+
+ -
+
+
+ false
+
+
+
+ 50
+ 24
+
+
+
+
+ 120
+ 16777215
+
+
+
+ Bitmask for collision filtering when collide_without_contact is on
+
+
+
+ -
+
+
+
+ 120
+ 16777215
+
+
+
+ collide_bitmask
+
+
+
+ -
+
+
+ false
+
+
+
+ 50
+ 24
+
+
+
+
+ 120
+ 16777215
+
+
+
+ Bitmask for collision filtering. This will override collide_without_contact. Parsed as 16-bit unsigned integer
+
+
+ 65535
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 150
+ 16777215
+
+
+
+ category_bitmask
+
+
+
+ -
+
+
+ false
+
+
+
+ 50
+ 24
+
+
+
+
+ 120
+ 16777215
+
+
+
+ Bitmask for category of collision filtering.
+Collision happens if ((category1 & collision2) | (category2 & collision1)) is not zero.
+If not specified, the category_bitmask should be interpreted as being the same as collide_bitmask.
+Parsed as 16-bit unsigned integer
+
+
+ 65535
+
+
+
+ -
+
+
+
+ 120
+ 16777215
+
+
+
+ poissons_ratio
+
+
+
+ -
+
+
+ false
+
+
+
+ 50
+ 24
+
+
+
+
+ 120
+ 16777215
+
+
+
+ Poisson's ratio is the unitless ratio between transverse and axial strain.
+ This value must lie between (-1, 0.5). Defaults to 0.3 for typical steel.
+ Note typical silicone elastomers have Poisson's ratio near 0.49 ~ 0.50
+
+
+
+ -
+
+
+
+ 120
+ 16777215
+
+
+
+ elastic_modulus
+
+
+
+ -
+
+
+ false
+
+
+
+ 50
+ 24
+
+
+
+
+ 120
+ 16777215
+
+
+
+ Young's Modulus in SI derived unit Pascal.
+ Defaults to -1. If value is less or equal to zero,
+ contact using elastic modulus (with Poisson's Ratio) is disabled.
+
+
+
+ -
+
+
+ ode
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+ soft_cfm
+
+
+
+ -
+
+
+ false
+
+
+ Soft constraint force mixing
+
+
+
+ -
+
+
+ kd
+
+
+
+ -
+
+
+ false
+
+
+ dynamically "damping"-equivalent coefficient for contact joints
+
+
+
+ -
+
+
+ soft_erp
+
+
+
+ -
+
+
+ false
+
+
+ Soft error reduction parameter
+
+
+
+ -
+
+
+ max_vel
+
+
+
+ -
+
+
+ false
+
+
+ maximum contact correction velocity truncation term.
+
+
+
+ -
+
+
+ kp
+
+
+
+ -
+
+
+ false
+
+
+ dynamically "stiffness"-equivalent coefficient for contact joints
+
+
+ 10000000000000.000000000000000
+
+
+
+ -
+
+
+ min_depth
+
+
+
+ -
+
+
+ false
+
+
+ minimum allowable depth before contact correction impulse is applied
+
+
+
+
+
+
+ -
+
+
+
+ 500
+ 155
+
+
+
+ bullet
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+ soft_cfm
+
+
+
+ -
+
+
+ false
+
+
+ Soft constraint force mixing
+
+
+
+ -
+
+
+ soft_erp
+
+
+
+ -
+
+
+ false
+
+
+ see ode
+
+
+
+ -
+
+
+ kp
+
+
+
+ -
+
+
+ split_impulse_penetration_threshold
+
+
+
+ -
+
+
+ false
+
+
+ see ode
+
+
+ 10000000000000.000000000000000
+
+
+
+ -
+
+
+ imilar to ODE's max_vel implementation
+
+
+
+ -
+
+
+ kd
+
+
+
+ -
+
+
+ false
+
+
+ see ode
+
+
+
+ -
+
+
+ split_impulse
+
+
+
+
+
+
+
+
+
+
+
+
+
+ soft_contact
+
+
+ -
+
+
+ soft_contact
+
+
+ true
+
+
+
-
+
+
+ bone_attachment
+
+
+
+ -
+
+
+ This is variable k_v in the soft contacts paper. Its unit is N/m
+
+
+ N/m
+
+
+ 1000.000000000000000
+
+
+
+ -
+
+
+ stiffness
+
+
+
+ -
+
+
+ This is variable k_e in the soft contacts paper
+
+
+ N/m
+
+
+ 1000.000000000000000
+
+
+
+ -
+
+
+ damping
+
+
+
+ -
+
+
+ Viscous damping of point velocity in body frame
+
+
+ N/m/s
+
+
+ 1000.000000000000000
+
+
+
+ -
+
+
+ flesh_mass_fraction
+
+
+
+ -
+
+
+ Fraction of mass to be distributed among deformable nodes
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 248
+ 20
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 448
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ surface_ode_mu_cb
+ toggled(bool)
+ surface_ode_mu_sp
+ setEnabled(bool)
+
+
+ 121
+ 425
+
+
+ 240
+ 425
+
+
+
+
+ surface_ode_mu2_cb
+ toggled(bool)
+ surface_ode_mu2_sp
+ setEnabled(bool)
+
+
+ 121
+ 455
+
+
+ 240
+ 455
+
+
+
+
+ surface_ode_slip1_cb
+ toggled(bool)
+ surface_ode_slip1_sp
+ setEnabled(bool)
+
+
+ 359
+ 425
+
+
+ 478
+ 425
+
+
+
+
+ surface_ode_slip2_cb
+ toggled(bool)
+ surface_ode_slip2_sp
+ setEnabled(bool)
+
+
+ 359
+ 455
+
+
+ 478
+ 455
+
+
+
+
+ surface_bullet_friction_cb
+ toggled(bool)
+ surface_bullet_friction_sp
+ setEnabled(bool)
+
+
+ 98
+ 636
+
+
+ 169
+ 636
+
+
+
+
+ surface_bullet_friction2_cb
+ toggled(bool)
+ surface_bullet_friction2_sp
+ setEnabled(bool)
+
+
+ 244
+ 636
+
+
+ 318
+ 636
+
+
+
+
+ surface_bullet_rolling_friction_cb
+ toggled(bool)
+ surface_bullet_rolling_friction_sp
+ setEnabled(bool)
+
+
+ 411
+ 636
+
+
+ 503
+ 636
+
+
+
+
+ contact_collide_without_contact_bitmask_cb
+ toggled(bool)
+ contact_collide_without_contact_bitmask_sp
+ setEnabled(bool)
+
+
+ 162
+ 253
+
+
+ 434
+ 253
+
+
+
+
+ contact_poissons_ratio_cb
+ toggled(bool)
+ contact_poissons_ratio_sp
+ setEnabled(bool)
+
+
+ 112
+ 343
+
+
+ 434
+ 343
+
+
+
+
+ contact_collide_bitmask_cb
+ toggled(bool)
+ contact_collide_bitmask_sp
+ setEnabled(bool)
+
+
+ 112
+ 283
+
+
+ 434
+ 283
+
+
+
+
+ contact_category_bitmask_cb
+ toggled(bool)
+ contact_category_bitmask_sp
+ setEnabled(bool)
+
+
+ 127
+ 313
+
+
+ 434
+ 313
+
+
+
+
+ contact_elastic_modulus_cb
+ toggled(bool)
+ contact_elastic_modulus_sp
+ setEnabled(bool)
+
+
+ 112
+ 373
+
+
+ 434
+ 373
+
+
+
+
+ contact_ode_soft_cfm_cb
+ toggled(bool)
+ contact_ode_soft_cfm_sp
+ setEnabled(bool)
+
+
+ 115
+ 446
+
+
+ 245
+ 446
+
+
+
+
+ contact_ode_soft_erp_cb
+ toggled(bool)
+ contact_ode_soft_erp_sp
+ setEnabled(bool)
+
+
+ 115
+ 489
+
+
+ 245
+ 489
+
+
+
+
+ contact_ode_kp_cb
+ toggled(bool)
+ contact_ode_kp_sp
+ setEnabled(bool)
+
+
+ 115
+ 532
+
+
+ 245
+ 532
+
+
+
+
+ contact_ode_kd_cb
+ toggled(bool)
+ contact_ode_kd_sp
+ setEnabled(bool)
+
+
+ 375
+ 446
+
+
+ 483
+ 446
+
+
+
+
+ contact_ode_max_vel_cb
+ toggled(bool)
+ contact_ode_max_vel_sp
+ setEnabled(bool)
+
+
+ 375
+ 489
+
+
+ 483
+ 489
+
+
+
+
+ contact_ode_min_depth_cb
+ toggled(bool)
+ contact_ode_min_depth_sp
+ setEnabled(bool)
+
+
+ 375
+ 532
+
+
+ 483
+ 532
+
+
+
+
+ contact_bullet_soft_cfm_cb
+ toggled(bool)
+ contact_bullet_soft_cfm_sp
+ setEnabled(bool)
+
+
+ 102
+ 623
+
+
+ 219
+ 623
+
+
+
+
+ contact_bullet_kp_cb
+ toggled(bool)
+ contact_bullet_kp_sp
+ setEnabled(bool)
+
+
+ 102
+ 691
+
+
+ 219
+ 691
+
+
+
+
+ contact_bullet_soft_erp_cb
+ toggled(bool)
+ contact_bullet_soft_erp_sp
+ setEnabled(bool)
+
+
+ 102
+ 657
+
+
+ 219
+ 657
+
+
+
+
+ contact_bullet_kd_cb
+ toggled(bool)
+ contact_bullet_kd_sp
+ setEnabled(bool)
+
+
+ 350
+ 623
+
+
+ 474
+ 623
+
+
+
+
+
diff --git a/robot_descriptor/forms/visual.ui b/robot_descriptor/forms/visual.ui
new file mode 100644
index 0000000..36d67fa
--- /dev/null
+++ b/robot_descriptor/forms/visual.ui
@@ -0,0 +1,153 @@
+
+
+ Form
+
+
+
+ 0
+ 0
+ 730
+ 700
+
+
+
+
+ 695
+ 700
+
+
+
+ Form
+
+
+ -
+
+
+
-
+
+
+ laser_retro
+
+
+
+ -
+
+
+ false
+
+
+
+ -
+
+
+ transparency
+
+
+
+ -
+
+
+ false
+
+
+
+ -
+
+
+ false
+
+
+ visibility_flags
+
+
+
+ -
+
+
+ false
+
+
+ 900000000
+
+
+ QAbstractSpinBox::DefaultStepType
+
+
+
+ -
+
+
+ cast_shadows
+
+
+
+ -
+
+
+
+ 660
+ 600
+
+
+
+
+ 16777215
+ 607
+
+
+
+ true
+
+
+
+
+ 0
+ 0
+ 692
+ 605
+
+
+
+
+
+
+
+
+
+
+
+
+
+ visual_laser_retro_cb
+ toggled(bool)
+ visual_laser_retro_sp
+ setEnabled(bool)
+
+
+ 73
+ 29
+
+
+ 189
+ 29
+
+
+
+
+ visual_transparency_cb
+ toggled(bool)
+ visual_transparency_sp
+ setEnabled(bool)
+
+
+ 306
+ 29
+
+
+ 423
+ 29
+
+
+
+
+
diff --git a/robot_descriptor/forms/world.ui b/robot_descriptor/forms/world.ui
index f81e4fe..74c7644 100644
--- a/robot_descriptor/forms/world.ui
+++ b/robot_descriptor/forms/world.ui
@@ -65,8 +65,8 @@
12
14
- 589
- 655
+ 587
+ 648
@@ -1575,8 +1575,8 @@ to zero if you want the min COR always to be used
10
10
- 541
- 333
+ 543
+ 421
@@ -1588,323 +1588,374 @@ to zero if you want the min COR always to be used
false
-
-
-
- 170
- 30
- 119
- 23
-
-
-
- name of planetary surface model, used to determine the surface altitude
+
+ -
+
+
+
+ 95
+ 24
+
+
+
+
+ 100
+ 24
+
+
+
+ surface_model
+
+
+
+ -
+
+
+
+ 117
+ 21
+
+
+
+
+ 120
+ 24
+
+
+
+ name of planetary surface model, used to determine the surface altitude
at a given latitude and longitude. The default is an ellipsoid model of
the earth based on the WGS-84 standard. It is used in Gazebo's GPS sensor
implementation.
-
-
- false
-
-
-
-
- EARTH_WGS84
-
+
+
+ false
+
+ -
+
+ EARTH_WGS84
+
+
+
-
-
-
-
- 20
- 40
- 88
- 15
-
-
-
- surface_model
-
-
-
-
-
- 20
- 70
- 147
- 15
-
-
-
- world_frame_orientation
-
-
-
-
-
- 170
- 60
- 153
- 23
-
-
-
- This field identifies how Gazebo world frame is aligned in Geographical
+ -
+
+
+
+ 155
+ 24
+
+
+
+ world_frame_orientation
+
+
+
+ -
+
+
+
+ 151
+ 21
+
+
+
+
+ 155
+ 24
+
+
+
+ This field identifies how Gazebo world frame is aligned in Geographical
sense. The final Gazebo world frame orientation is obtained by rotating
a frame aligned with following notation by the field heading_deg.
Options are:
-
-
- false
-
-
-
-
- ENU (East-North-Up)
-
+
+
+ false
+
+ -
+
+ ENU (East-North-Up)
+
+
+
-
-
-
-
- 20
- 100
- 75
- 15
-
-
-
- latitude_deg
-
-
-
-
-
- 170
- 96
- 81
- 24
-
-
-
- Geodetic latitude at origin of gazebo reference frame, specified
+ -
+
+
+
+ 85
+ 24
+
+
+
+ latitude_deg
+
+
+
+ -
+
+
+
+ 88
+ 24
+
+
+
+
+ 90
+ 24
+
+
+
+ Geodetic latitude at origin of gazebo reference frame, specified
in units of degrees.
-
-
-
-
-
- °
-
-
- 4
-
-
- -90.000000000000000
-
-
- 90.000000000000000
-
-
-
-
-
- 20
- 130
- 86
- 15
-
-
-
- longitude_deg
-
-
-
-
-
- 168
- 126
- 81
- 24
-
-
-
- Longitude at origin of gazebo reference frame, specified in units
+
+
+
+
+
+ °
+
+
+ 4
+
+
+ -90.000000000000000
+
+
+ 90.000000000000000
+
+
+
+ -
+
+
+
+ 95
+ 24
+
+
+
+ longitude_deg
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 100
+ 24
+
+
+
+ Longitude at origin of gazebo reference frame, specified in units
of degrees
-
-
- °
-
-
- 4
-
-
- -180.000000000000000
-
-
- 180.000000000000000
-
-
-
-
-
- 20
- 158
- 57
- 15
-
-
-
- elevation
-
-
-
-
-
- 168
- 154
- 85
- 24
-
-
-
- Elevation of origin of gazebo reference frame, specified in meters
-
-
- m
-
-
- 4
-
-
- 10000.000000000000000
-
-
-
-
-
- 340
- 30
- 78
- 15
-
-
-
- heading_deg
-
-
-
-
-
- 428
- 26
- 89
- 24
-
-
-
- Heading offset of gazebo reference frame, measured as angle between
+
+
+ °
+
+
+ 4
+
+
+ -180.000000000000000
+
+
+ 180.000000000000000
+
+
+
+ -
+
+
+
+ 65
+ 24
+
+
+
+ elevation
+
+
+
+ -
+
+
+
+ 112
+ 24
+
+
+
+
+ 120
+ 24
+
+
+
+ Elevation of origin of gazebo reference frame, specified in meters
+
+
+ m
+
+
+ 4
+
+
+ 10000.000000000000000
+
+
+
+ -
+
+
+
+ 85
+ 24
+
+
+
+ heading_deg
+
+
+
+ -
+
+
+
+ 80
+ 24
+
+
+
+
+ 85
+ 24
+
+
+
+ Heading offset of gazebo reference frame, measured as angle between
Gazebo world frame and the world_frame_orientation type.
The direction of rotation follows the right-hand rule, so a positive
angle indicates clockwise rotation (from east to north) when viewed from top-down. Note
that this is not consistent with compass heading convention.
The angle is specified in degrees.
-
-
- °
-
-
- -360.000000000000000
-
-
- 360.000000000000000
-
-
-
-
-
- 16
- 260
- 161
- 67
-
-
-
- surface_axis_polar
-
-
- true
-
-
- false
-
-
-
-
- 8
- 26
- 109
- 24
-
-
-
- Polar axis of a custom surface type, specified in meters.
- This is only required for custom surfaces
-
-
- m
-
-
- 4
-
-
- 10000.000000000000000
-
-
-
-
-
-
- 14
- 182
- 165
- 69
-
-
-
- surface_axis_equatorial
-
-
- true
-
-
- false
-
-
-
-
- 4
- 28
- 104
- 24
-
-
-
- Equatorial axis of a custom surface type, specified in meters.
+
+
+ °
+
+
+ -360.000000000000000
+
+
+ 360.000000000000000
+
+
+
+ -
+
+
+
+ 175
+ 65
+
+
+
+
+ 180
+ 70
+
+
+
+ surface_axis_equatorial
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+ Equatorial axis of a custom surface type, specified in meters.
This is only required for custom surfaces.
-
-
- m
-
-
- 4
-
-
- 1000.000000000000000
-
-
-
-
-
+
+
+ m
+
+
+ 4
+
+
+ 1000.000000000000000
+
+
+
+
+
+
+ -
+
+
+
+ 159
+ 61
+
+
+
+
+ 170
+ 70
+
+
+
+ surface_axis_polar
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+ Polar axis of a custom surface type, specified in meters.
+ This is only required for custom surfaces
+
+
+ m
+
+
+ 4
+
+
+ 10000.000000000000000
+
+
+
+
+
+
+
+
+
6
@@ -1923,13 +1974,10 @@ of degrees
light
- -
-
-
-
- 16777215
- 100
-
+
-
+
+
+ Reset
@@ -1963,67 +2011,11 @@ of degrees
0
0
- 551
+ 549
771
- -
-
-
- name
-
-
-
- -
-
-
-
- 0
- 23
-
-
-
-
- -
-
-
- type
-
-
-
- -
-
-
-
- 0
- 23
-
-
-
-
-
- point
-
-
- -
-
- spot
-
-
- -
-
- directional
-
-
-
-
- -
-
-
- intensity
-
-
-
-
@@ -2040,219 +2032,205 @@ of degrees
- -
-
-
-
- 0
- 21
-
-
-
- cast_shadows
-
-
-
- -
-
-
-
- 0
- 21
-
-
-
- visualize
-
-
- true
-
-
-
- -
-
-
-
- 0
- 21
-
-
+
-
+
- light_on
-
-
- true
+ intensity
- -
-
+
-
+
- 489
- 98
-
-
-
-
- 533
- 16777215
+ 505
+ 145
- Diffuse
+ pose
-
-
-
-
-
-
- 0
- 25
-
+
+
-
+
+
+ x
-
-
- 64
- 16777215
-
+
+ Qt::AlignCenter
-
- 1.000000000000000
+
+
+ -
+
+
+ y
-
- 0.100000000000000
+
+ Qt::AlignCenter
-
- 1.000000000000000
+
+
+ -
+
+
+ z
+
+
+ Qt::AlignCenter
-
-
+
0
25
-
-
- 64
- 16777215
-
-
-
- 1.000000000000000
+
+ 4
-
- 0.100000000000000
+
+ -100.000000000000000
-
- 1.000000000000000
+
+ 1000.000000000000000
- -
-
+
-
+
0
25
-
+
+ 4
+
+
+ -100.000000000000000
+
+
+ 1000.000000000000000
+
+
+
+ -
+
+
- 64
- 16777215
+ 0
+ 25
-
- 1.000000000000000
+
+ 4
-
- 0.100000000000000
+
+ -100.000000000000000
-
- 1.000000000000000
+
+ 1000.000000000000000
- -
-
-
- A
+
-
+
+
+ roll
Qt::AlignCenter
- -
-
+
-
+
- R
+ pitch
Qt::AlignCenter
- -
-
+
-
+
+
+ yaw
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
0
25
-
-
- 64
- 16777215
-
+
+ rad
-
- 1.000000000000000
+
+ 4
-
- 0.100000000000000
+
+ -6.283200000000000
-
- 1.000000000000000
+
+ 6.283200000000000
- -
-
-
- G
+
-
+
+
+
+ 0
+ 25
+
-
- Qt::AlignCenter
+
+ rad
-
-
- -
-
-
- B
+
+ 4
-
- Qt::AlignCenter
+
+ -6.283200000000000
+
+
+ 6.283200000000000
- -
-
-
+
-
+
+
- 45
- 16777215
+ 0
+ 25
-
-
+
+ rad
+
+
+ 4
+
+
+ -6.283200000000000
+
+
+ 6.283200000000000
@@ -2469,136 +2447,20 @@ of degrees
- -
-
+
-
+
0
- 75
-
-
-
-
- 534
- 16777215
-
-
-
- attenuation
-
-
-
-
-
-
- constant
-
-
-
- -
-
-
-
- 64
- 25
-
-
-
- 0.100000000000000
-
-
- 1.000000000000000
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- quadratic
-
-
-
-
-
- 64
- 25
-
-
-
- 0.100000000000000
-
-
-
-
- -
-
-
- linear
-
-
-
- -
-
-
-
- 64
- 25
-
-
-
- 0.100000000000000
-
-
- 1.000000000000000
-
-
-
- -
-
-
-
- 64
- 25
-
-
-
- 100000.000000000000000
-
-
- 0.100000000000000
-
-
- 10.000000000000000
-
-
-
- -
-
-
- range
-
-
-
-
-
-
- -
-
-
-
- 505
- 145
+ 94
- pose
+ direction
-
+
-
-
+
x
@@ -2608,7 +2470,7 @@ of degrees
-
-
+
y
@@ -2618,7 +2480,7 @@ of degrees
-
-
+
z
@@ -2628,261 +2490,436 @@ of degrees
-
-
+
0
25
-
- 4
-
-100.000000000000000
-
- 1000.000000000000000
-
-
-
+
0
25
-
- 4
-
-100.000000000000000
-
- 1000.000000000000000
-
-
-
+
0
25
-
- 4
-
-100.000000000000000
-
- 1000.000000000000000
+
+ -1.000000000000000
- -
-
-
- roll
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
- pitch
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
- yaw
-
-
- Qt::AlignCenter
-
-
-
- -
-
+
+
+
+ -
+
+
+
+ 0
+ 21
+
+
+
+ cast_shadows
+
+
+
+ -
+
+
+
+ 489
+ 98
+
+
+
+
+ 533
+ 16777215
+
+
+
+ Diffuse
+
+
+
-
+
0
25
-
- rad
+
+
+ 64
+ 16777215
+
-
- 4
+
+ 1.000000000000000
-
- -6.283200000000000
+
+ 0.100000000000000
-
- 6.283200000000000
+
+ 1.000000000000000
- -
-
+
-
+
0
25
-
- rad
+
+
+ 64
+ 16777215
+
-
- 4
+
+ 1.000000000000000
-
- -6.283200000000000
+
+ 0.100000000000000
-
- 6.283200000000000
+
+ 1.000000000000000
- -
-
+
-
+
0
25
-
- rad
-
-
- 4
-
-
- -6.283200000000000
+
+
+ 64
+ 16777215
+
- 6.283200000000000
+ 1.000000000000000
-
-
-
-
-
- -
-
-
-
- 0
- 94
-
-
-
- direction
-
-
-
-
-
-
- x
+
+ 0.100000000000000
-
- Qt::AlignCenter
+
+ 1.000000000000000
- -
-
+
-
+
- y
+ A
Qt::AlignCenter
- -
-
+
-
+
- z
+ R
Qt::AlignCenter
- -
-
+
-
+
0
25
-
- -100.000000000000000
+
+
+ 64
+ 16777215
+
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+ 1.000000000000000
- -
-
-
-
- 0
- 25
-
+
-
+
+
+ G
-
- -100.000000000000000
+
+ Qt::AlignCenter
- -
-
-
+
-
+
+
+ B
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
- 0
- 25
+ 45
+ 16777215
-
- -100.000000000000000
-
-
- -1.000000000000000
+
+
- -
-
-
+
-
+
+
+
+ 0
+ 21
+
+
+
+ visualize
+
+
true
+
+
+ -
+
0
- 100
+ 75
-
- spot
+
+
+ 534
+ 16777215
+
+
+
+ attenuation
+
+
+
-
+
+
+ constant
+
+
+
+ -
+
+
+
+ 64
+ 25
+
+
+
+ 0.100000000000000
+
+
+ 1.000000000000000
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+
+ 65
+ 24
+
+
+
+ quadratic
+
+
+
+
+
+ 64
+ 25
+
+
+
+ 0.100000000000000
+
+
+
+
+ -
+
+
+ linear
+
+
+
+ -
+
+
+
+ 64
+ 25
+
+
+
+ 0.100000000000000
+
+
+ 1.000000000000000
+
+
+
+ -
+
+
+
+ 64
+ 25
+
+
+
+ 100000.000000000000000
+
+
+ 0.100000000000000
+
+
+ 10.000000000000000
+
+
+
+ -
+
+
+ range
+
+
+
+
+
+
+ -
+
+
+ name
+
+
+
+ -
+
+
+
+ 0
+ 23
+
+
+
-
+
+ point
+
+
+ -
+
+ spot
+
+
+ -
+
+ directional
+
+
+
+
+ -
+
+
+
+ 0
+ 21
+
+
+
+ light_on
+
+
+ true
+
+
+
+ -
+
+
+ true
+
+
+
+ 0
+ 100
+
+
+
+ spot
-
@@ -2960,14 +2997,34 @@ of degrees
+ -
+
+
+
+ 0
+ 23
+
+
+
+
+ -
+
+
+ type
+
+
+
- -
-
-
- Reset
+
-
+
+
+
+ 16777215
+ 100
+
@@ -3397,1535 +3454,52 @@ of degrees
true
-
- -
-
-
- cubemap_uri
-
-
-
- -
-
-
- time
-
-
-
- -
-
-
- 24.000000000000000
-
-
-
- -
-
-
-
- 0
- 23
-
-
-
-
- -
-
-
- sunset
-
-
-
- -
-
-
- clouds
-
-
- true
-
-
-
-
-
-
- mean_size
-
-
-
- -
-
-
- humidity
-
-
-
- -
-
-
- direction
-
-
-
- -
-
-
- Density of clouds
-
-
- 4
-
-
- 1.000000000000000
-
-
- 0.100000000000000
-
-
-
- -
-
-
-
- 16777215
- 100
-
-
-
-
-
-
- ambient
-
-
-
-
-
-
-
- 16777215
- 24
-
-
-
- R
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 16777215
- 24
-
-
-
- B
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 0
- 24
-
-
-
-
- 16777215
- 24
-
-
-
- 1.000000000000000
-
-
- 0.100000000000000
-
-
-
- -
-
-
-
- 0
- 24
-
-
-
-
- 16777215
- 24
-
-
-
- 1.000000000000000
-
-
- 0.100000000000000
-
-
-
- -
-
-
-
- 0
- 24
-
-
-
-
- 16777215
- 24
-
-
-
- 1.000000000000000
-
-
- 0.100000000000000
-
-
-
- -
-
-
-
- 0
- 24
-
-
-
-
- 16777215
- 24
-
-
-
- 1.000000000000000
-
-
- 0.100000000000000
-
-
-
- -
-
-
-
- 16777215
- 24
-
-
-
- G
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 16777215
- 24
-
-
-
- A
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 45
- 16777215
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Direction of the cloud movement
-
-
- 4
-
-
- 3.145600000000000
-
-
- 0.100000000000000
-
-
-
- -
-
-
- speed
-
-
-
- -
-
-
-
- 70
- 16777215
-
-
-
- Speed of the clouds
-
-
- 4
-
-
-
- -
-
-
-
- 60
- 24
-
-
-
- 4
-
-
- 1.000000000000000
-
-
- 0.100000000000000
-
-
-
-
-
-
- -
-
-
-
- 80
- 16777215
-
-
-
- 24.000000000000000
-
-
-
- -
-
-
- sunrise
-
-
-
- -
-
-
- 24.000000000000000
-
-
-
-
-
-
- -
-
-
-
- 0
- 24
-
-
-
-
- 150
- 16777215
-
-
-
- shadows
-
-
-
- -
-
-
-
- 0
- 24
-
-
-
-
- 150
- 16777215
-
-
-
- grid
-
-
-
- -
-
-
-
- 160
- 24
-
-
-
-
- 150
- 16777215
-
-
-
- origin_visual
-
-
-
- -
-
-
-
- 520
- 203
-
-
-
-
- 530
- 16777215
-
-
-
- fog
-
-
- true
-
-
-
-
-
-
- type
-
-
-
- -
-
-
-
- 0
- 24
-
-
-
-
- 100
- 25
-
-
-
-
-
- none
-
-
- -
-
- constant
-
-
- -
-
- linear
-
-
- -
-
- quadratic
-
-
-
-
- -
-
-
-
- 450
- 100
-
-
-
-
- 16777215
- 100
-
-
-
- fog color
-
-
- color
-
-
-
-
-
-
-
- 16777215
- 24
-
-
-
- B
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 16777215
- 24
-
-
-
- A
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 0
- 24
-
-
-
-
- 16777215
- 24
-
-
-
- 1.000000000000000
-
-
- 0.100000000000000
-
-
-
- -
-
-
-
- 16777215
- 24
-
-
-
- G
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 0
- 24
-
-
-
-
- 16777215
- 24
-
-
-
- 1.000000000000000
-
-
- 0.100000000000000
-
-
-
- -
-
-
-
- 0
- 24
-
-
-
-
- 16777215
- 24
-
-
-
- 1.000000000000000
-
-
- 0.100000000000000
-
-
-
- -
-
-
-
- 0
- 24
-
-
-
-
- 16777215
- 24
-
-
-
- 1.000000000000000
-
-
- 0.100000000000000
-
-
-
- -
-
-
-
- 16777215
- 24
-
-
-
- R
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 46
- 16777215
-
-
-
-
-
-
-
-
-
-
- -
-
-
- density
-
-
-
- -
-
-
- Density of fog
-
-
-
- -
-
-
- end
-
-
-
- -
-
-
- Distance to end of fog
-
-
- 1000.000000000000000
-
-
-
- -
-
-
- Distance to start of fog
-
-
-
- -
-
-
- start
-
-
-
-
-
-
-
-
-
-
-
-
- 8
- 586
- 80
- 23
-
-
-
- Reset
-
-
-
-
-
- 456
- 586
- 110
- 21
-
-
-
- enable_scene
-
-
-
-
-
- road
-
-
-
-
- 432
- 592
- 105
- 21
-
-
-
-
- 105
- 0
-
-
-
- Enable_road
-
-
-
-
-
- 10
- 596
- 80
- 23
-
-
-
- Reset
-
-
-
-
-
- 10
- 12
- 569
- 571
-
-
-
- true
-
-
-
-
- 0
- 0
- 553
- 672
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
-
- 0
- 24
-
-
-
- name
-
-
-
-
-
- 0
- 24
-
-
-
-
-
- -
-
-
-
- 500
- 624
-
-
-
-
- 570
- 630
-
-
-
- material
-
-
- true
-
-
- false
-
-
-
-
-
-
-
- 240
- 89
-
-
-
-
- 240
- 16777215
-
-
-
- script
-
-
- true
-
-
- false
-
-
-
-
- 18
- 28
- 16
- 15
-
-
-
- uri
-
-
-
-
-
- 52
- 24
- 153
- 23
-
-
-
-
- 160
- 16777215
-
-
-
-
-
-
- 12
- 56
- 34
- 15
-
-
-
- name
-
-
-
-
-
- 52
- 52
- 113
- 23
-
-
-
-
- 115
- 16777215
-
-
-
-
-
- -
-
-
-
- 240
- 95
-
-
-
-
- 240
- 16777215
-
-
-
- shader
-
-
- true
-
-
- false
-
-
-
-
- 12
- 30
- 57
- 16
-
-
-
- type
-
-
-
-
-
- 82
- 26
- 100
- 21
-
-
-
-
- 100
- 16777215
-
-
-
-
-
- pixel
-
-
- -
-
- vertex
-
-
- -
-
- normal_map_object_space
-
-
- -
-
- normal_map_tangent_space
-
-
-
-
-
-
- 12
- 57
- 100
- 20
-
-
-
- normal_map
-
-
-
-
-
- 118
- 57
- 100
- 20
-
-
-
-
- 100
- 16777215
-
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
-
- 85
- 24
-
-
-
-
- 85
- 28
-
-
-
- render_order
-
-
-
-
-
- 0
- 24
-
-
-
-
- 100
- 16777215
-
-
-
- Set render order for coplanar polygons. The higher value will be rendered on top of the other coplanar polygons
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
-
- 56
- 16777215
-
-
-
- shininess
-
-
-
-
-
- 0
- 24
-
-
-
-
- 100
- 27
-
-
-
-
-
- -
-
-
-
- 520
- 100
-
-
-
-
- 520
- 100
-
-
-
- background color
-
-
- ambient
-
-
- true
-
-
- false
-
-
-
-
-
-
-
- 0
- 24
-
-
-
-
- 16777215
- 24
-
-
-
- 1.000000000000000
-
-
- 0.100000000000000
-
-
-
- -
-
-
-
- 16777215
- 24
-
-
-
- B
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 16777215
- 24
-
-
-
- A
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 16777215
- 24
-
-
-
- R
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 0
- 24
-
-
-
-
- 16777215
- 24
-
-
-
- 1.000000000000000
-
-
- 0.100000000000000
-
-
-
- -
-
-
-
- 0
- 24
-
-
-
-
- 16777215
- 24
-
-
-
- 1.000000000000000
-
-
- 0.100000000000000
-
-
-
- -
-
-
-
- 16777215
- 24
-
-
-
- G
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 0
- 24
-
-
-
-
- 16777215
- 24
-
-
-
- 1.000000000000000
-
-
- 0.100000000000000
-
-
-
- -
-
-
-
- 45
- 16777215
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
- 520
- 100
-
-
-
-
- 520
- 100
-
-
-
- background color
-
-
- diffuse
-
-
- true
-
-
- false
-
-
-
-
-
-
-
- 0
- 24
-
-
-
-
- 16777215
- 24
-
-
-
- 1.000000000000000
-
-
- 0.100000000000000
-
-
-
- -
-
-
-
- 16777215
- 24
-
-
-
- B
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 16777215
- 24
-
-
-
- A
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 16777215
- 24
-
-
-
- R
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 0
- 24
-
-
-
-
- 16777215
- 24
-
-
-
- 1.000000000000000
-
-
- 0.100000000000000
-
-
-
- -
-
-
-
- 0
- 24
-
-
-
-
- 16777215
- 24
-
-
-
- 1.000000000000000
-
-
- 0.100000000000000
-
-
-
- -
-
-
-
- 16777215
- 24
-
-
-
- G
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 0
- 24
-
-
-
-
- 16777215
- 24
-
-
-
- 1.000000000000000
-
-
- 0.100000000000000
-
-
-
- -
-
-
-
- 45
- 16777215
-
-
-
-
-
-
-
-
+
+ false
+
+
+ -
+
+
+ cubemap_uri
+
- -
-
-
-
- 520
- 100
-
+
-
+
+
+ time
-
+
+
+ -
+
+
+ 24.000000000000000
+
+
+
+ -
+
+
- 520
- 100
+ 0
+ 23
-
- background color
+
+
+ -
+
+
+ sunset
+
+
+ -
+
- specular
+ clouds
true
@@ -4933,150 +3507,276 @@ of degrees
false
-
-
-
-
-
-
- 0
- 24
-
-
-
-
- 16777215
- 24
-
-
-
- 1.000000000000000
-
-
- 0.100000000000000
+
+
-
+
+
+ mean_size
- -
-
-
-
- 16777215
- 24
-
-
+
-
+
- B
-
-
- Qt::AlignCenter
+ humidity
-
-
-
-
- 16777215
- 24
-
-
+
- A
+ direction
-
- Qt::AlignCenter
+
+
+ -
+
+
+ Density of clouds
+
+
+ 4
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
- -
-
+
-
+
16777215
- 24
+ 100
-
- R
+
+
-
- Qt::AlignCenter
+
+ ambient
+
+
-
+
+
+
+ 16777215
+ 24
+
+
+
+ R
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 16777215
+ 24
+
+
+
+ B
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
+
+ 1.000000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+
+ 16777215
+ 24
+
+
+
+ G
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 16777215
+ 24
+
+
+
+ A
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 45
+ 16777215
+
+
+
+
+
+
+
+
- -
-
-
-
- 0
- 24
-
+
-
+
+
+ Direction of the cloud movement
-
-
- 16777215
- 24
-
+
+ 4
- 1.000000000000000
+ 3.145600000000000
0.100000000000000
- -
-
-
-
- 0
- 24
-
-
-
-
- 16777215
- 24
-
-
-
- 1.000000000000000
-
-
- 0.100000000000000
+
-
+
+
+ speed
-
-
+
- 16777215
- 24
+ 70
+ 16777215
-
- G
+
+ Speed of the clouds
-
- Qt::AlignCenter
+
+ 4
- -
-
+
-
+
- 0
+ 60
24
-
-
- 16777215
- 24
-
+
+ 4
1.000000000000000
@@ -5086,73 +3786,202 @@ of degrees
- -
-
-
-
- 45
- 16777215
-
-
-
-
-
-
-
- -
-
+
-
+
+
+
+ 80
+ 16777215
+
+
+
+ 24.000000000000000
+
+
+
+ -
+
+
+ sunrise
+
+
+
+ -
+
+
+ 24.000000000000000
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 150
+ 16777215
+
+
+
+ shadows
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 150
+ 16777215
+
+
+
+ grid
+
+
+
+ -
+
+
+
+ 160
+ 24
+
+
+
+
+ 150
+ 16777215
+
+
+
+ origin_visual
+
+
+
+ -
+
+
+
+ 520
+ 203
+
+
+
+
+ 530
+ 16777215
+
+
+
+ fog
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+ type
+
+
+
+ -
+
+
+
+ 0
+ 24
+
+
+
+
+ 100
+ 25
+
+
+
-
+
+ none
+
+
+ -
+
+ constant
+
+
+ -
+
+ linear
+
+
+ -
+
+ quadratic
+
+
+
+
+ -
+
- 520
+ 450
100
- 520
+ 16777215
100
- background color
+ fog color
- emissive
-
-
- true
-
-
- false
+ color
-
-
-
-
-
-
- 0
- 24
-
-
+
+
-
+
16777215
24
-
- 1.000000000000000
+
+ B
-
- 0.100000000000000
+
+ Qt::AlignCenter
- -
-
+
-
+
16777215
@@ -5160,31 +3989,37 @@ of degrees
- B
+ A
Qt::AlignCenter
- -
-
+
-
+
+
+
+ 0
+ 24
+
+
16777215
24
-
- A
+
+ 1.000000000000000
-
- Qt::AlignCenter
+
+ 0.100000000000000
- -
-
+
-
+
16777215
@@ -5192,7 +4027,7 @@ of degrees
- R
+ G
Qt::AlignCenter
@@ -5200,7 +4035,7 @@ of degrees
-
-
+
0
@@ -5222,7 +4057,7 @@ of degrees
-
-
+
0
@@ -5243,24 +4078,8 @@ of degrees
- -
-
-
-
- 16777215
- 24
-
-
-
- G
-
-
- Qt::AlignCenter
-
-
-
-
-
+
0
@@ -5281,11 +4100,33 @@ of degrees
+ -
+
+
+
+ 16777215
+ 24
+
+
+
+ R
+
+
+ Qt::AlignCenter
+
+
+
-
-
+
+
+
+ 0
+ 0
+
+
- 45
+ 46
16777215
@@ -5297,51 +4138,222 @@ of degrees
- -
-
-
-
- 0
- 24
-
+
-
+
+
+ density
+
+
+
+ -
+
+
+ Density of fog
+
+
+
+ -
+
+
+ end
+
+
+
+ -
+
+
+ Distance to end of fog
+
+
+ 1000.000000000000000
+
+
+
+ -
+
+
+ Distance to start of fog
+
+
+ -
+
- lighting
+ start
- -
-
-
- Qt::Horizontal
-
-
-
-
- 0
- 24
-
-
-
- width
-
-
-
-
-
- 0
- 24
-
-
-
-
-
+
+
+
+ 8
+ 586
+ 80
+ 23
+
+
+
+ Reset
+
+
+
+
+
+ 456
+ 586
+ 110
+ 21
+
+
+
+ enable_scene
+
+
+
+
+
+ road
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+
+ 50
+ 24
+
+
+
+
+ 55
+ 27
+
+
+
+ name
+
+
+
+
+
+ 100
+ 16777215
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+
+ 50
+ 24
+
+
+
+
+ 55
+ 25
+
+
+
+ width
+
+
+
+
+
+ 60
+ 24
+
+
+
+
+ 100
+ 25
+
+
+
+
+
+ -
+
+
+
+ 565
+ 540
+
+
+
+ true
+
+
+
+
+ 0
+ 0
+ 563
+ 540
+
+
+
+
+
+ -
+
+
+
+ 100
+ 16777215
+
+
+
+ Reset
+
+
+
+ -
+
+
+
+ 105
+ 0
+
+
+
+
+ 100
+ 16777215
+
+
+
+ Enable_road
+
+
+
+ -
+
+
+ include_material_info
+
+
+
+
diff --git a/robot_descriptor/icons/link16.png b/robot_descriptor/icons/link16.png
new file mode 100644
index 0000000..b1c7113
Binary files /dev/null and b/robot_descriptor/icons/link16.png differ
diff --git a/robot_descriptor/icons/link24.png b/robot_descriptor/icons/link24.png
new file mode 100644
index 0000000..77ecc24
Binary files /dev/null and b/robot_descriptor/icons/link24.png differ
diff --git a/robot_descriptor/icons/link32.png b/robot_descriptor/icons/link32.png
new file mode 100644
index 0000000..42a4bbd
Binary files /dev/null and b/robot_descriptor/icons/link32.png differ
diff --git a/robot_descriptor/icons/ref16.png b/robot_descriptor/icons/ref16.png
new file mode 100644
index 0000000..e1a9c47
Binary files /dev/null and b/robot_descriptor/icons/ref16.png differ
diff --git a/robot_descriptor/icons/ref24.png b/robot_descriptor/icons/ref24.png
new file mode 100644
index 0000000..a4a3599
Binary files /dev/null and b/robot_descriptor/icons/ref24.png differ
diff --git a/robot_descriptor/icons/ref32.png b/robot_descriptor/icons/ref32.png
new file mode 100644
index 0000000..c00f921
Binary files /dev/null and b/robot_descriptor/icons/ref32.png differ
diff --git a/robot_descriptor/initialize.py b/robot_descriptor/initialize.py
index d7400fe..8001fe5 100644
--- a/robot_descriptor/initialize.py
+++ b/robot_descriptor/initialize.py
@@ -6,7 +6,7 @@
#import Spreadsheet
import xml.etree.ElementTree as ET
-from .RD_parser import initialize_element_tree
+from .RD_utils import initialize_element_tree
#directory to initilize icon
__dirname__ = os.path.join(FreeCAD.getUserAppDataDir(), "Mod", "RobotDescriptor")+"/robot_descriptor/icons/initialize.svg"
#class to store the selected properties
diff --git a/robot_descriptor/model_editor.py b/robot_descriptor/model_editor.py
new file mode 100644
index 0000000..d963118
--- /dev/null
+++ b/robot_descriptor/model_editor.py
@@ -0,0 +1,270 @@
+from typing import Any
+import FreeCAD
+import FreeCADGui
+import robot_descriptor.common as common
+import os
+from PySide2 import QtGui
+import copy
+from .RD_utils import initialize_element_tree
+
+import xml.etree.ElementTree as ET
+
+from .RD_utils import parse_asm4_model
+from PySide2.QtGui import QStandardItemModel,QStandardItem
+from PySide2.QtWidgets import QTreeView,QDialog,QSplitter,QGridLayout,QTabWidget,QHBoxLayout,QWidget
+from PySide2.QtCore import QSize, Qt,QModelIndex,QItemSelectionModel,Signal
+from .sdf_elements import link
+from .sdf_elements import visual
+from .sdf_elements import collision
+
+link_img=QtGui.QImage(os.path.join(common.ICON_PATH,"link24.png"))
+ref_img=QtGui.QImage(os.path.join(common.ICON_PATH,"ref24.png"))
+
+
+#start standard item
+class ModelItem(QStandardItem):
+ def __init__(self,model_editor_cls,text,type='link'):
+ super().__init__()
+ # data to describe the model
+
+ #types ref,link ... .
+ self.text=text
+ self.type=type
+ #set the text to be displayed
+ self.setText(text)
+ self.setEditable(False)
+ self.model_cls=model_editor_cls
+
+ # self.Model_editor_ui=self.model_cls.Model_editor_ui
+
+ #Tasks
+ # 1. Implement function to
+ # i. calculate inertia and write the info to the inertial element ,this might be
+ # implemented in the inertial class
+ # ii. extract maerial data e.g color of link... , and write to material element
+ #
+ # 2. add user roles to get element data after disabled ui icons have been removed
+ # so that calling the on the item with the role will return the element after appending them as required
+ # 3. add slot that can be triggered when user breaks reference so that an element of type reference can
+ # create its own links and not refer to parent ref item , also another to create links to a parent item
+ # and one to update ui when to item is selected in the tree view
+ #4. set tooltip for tree view items , i.e references should give a clue of the parent
+ #5. right click menu will be responsible for creating and breaking links and jumping to the the parent for references
+
+ #linked
+ if self.type !='ref':
+ self.init_elements()
+
+ def init_elements(self):
+ self.collision_element=initialize_element_tree.convdict_2_tree('collision.sdf').get_element
+ self._link_element=initialize_element_tree.convdict_2_tree('link.sdf').get_element
+ self._inertial_element=initialize_element_tree.convdict_2_tree("inertial.sdf").get_element
+ self.surface_element=initialize_element_tree.convdict_2_tree("surface.sdf").get_element
+ self._visual_element=initialize_element_tree.convdict_2_tree("visual.sdf").get_element
+ self._material_element=initialize_element_tree.convdict_2_tree('material.sdf').get_element
+
+
+ def create_ref(self,item):
+
+ self.collision_element=item.collision_element
+ self._link_element=item._link_element
+ self._inertial_element=item._inertial_element
+ self.surface_element=item.surface_element
+ self._visual_element=item._visual_element
+ self._material_element=item._material_element
+ self.type='ref'
+ self.emitDataChanged()
+
+ def break_ref(self):
+ self.init_elements()
+ self.type='link'
+ self.emitDataChanged()
+
+ def selected(self):
+ #this will called when an item is clicked
+ #update elements
+ self.model_cls._link.update_elements(self)
+ self.model_cls._visual.update_elements(self)
+ self.model_cls._collision.update_elements(self)
+
+
+ def data(self, role: int = ...) -> Any:
+ if role==Qt.DisplayRole:
+ return self.text
+
+ if role==Qt.DecorationRole:
+ if self.type=='link':
+ return link_img
+ elif self.type=='ref':
+ return ref_img
+ else:
+ return
+
+
+#end standard Item
+#==============================================
+
+
+#model editor
+class ModelEditor(QDialog):
+
+
+ def __init__(self,elem_struct):
+ # find all objects of type 'App::Link'
+ #doc=FreeCAD.ActiveDocument
+ super(ModelEditor,self).__init__()
+
+ self._elem_struct=elem_struct
+ self.links_hierarchy=parse_asm4_model.read_assembly()
+ if self.links_hierarchy is None:
+ return
+ # self.ModelEditorUi=FreeCADGui.PySideUic.loadUi(os.path.join(common.UI_PATH,'model_editor.ui'))
+
+ #subelements
+ self.current_elems=[]
+ #dictionary of all links and their associated elements
+ #{link name: [link,collison,visual], ...}
+ self.elems={}
+ #used for creating refernces for item of type ref
+ self.referenced_elems={}
+ #ui's
+ self.collision_ui=FreeCADGui.PySideUic.loadUi(os.path.join(common.UI_PATH,'collision.ui'))
+ self.link_ui=FreeCADGui.PySideUic.loadUi(os.path.join(common.UI_PATH,'link.ui'))
+ self.visual_ui=FreeCADGui.PySideUic.loadUi(os.path.join(common.UI_PATH,'visual.ui'))
+ #end ui's
+ #elements
+ self._link=link.link(self.link_ui)
+ self._visual=visual.visual(self.visual_ui)
+ self._collision=collision.collison(self.collision_ui)
+ #end elements
+
+ self.setUpUI()
+
+ #create model
+ self.link_model=QStandardItemModel()
+ self.link_model.setColumnCount(1)
+ self.root_node=self.link_model.invisibleRootItem()
+ self.model_tree_config(self.links_hierarchy["children"],self.root_node)
+
+ #add callback
+ self.config()
+
+ # start header related
+ self.link_model.setHorizontalHeaderLabels(["Model Tree"])
+ #set the tree to resize automatically based on the display requirements
+ #end header related
+
+ #set view model
+ self.view.setModel(self.link_model)
+ #select the first item
+ mdl_idx0=self.link_model.index(0,0,self.view.rootIndex())
+ self.view.selectionModel().select(mdl_idx0,QItemSelectionModel.Select)
+ #display dialog
+ self.exec_()
+#end __init__()
+
+
+ def sizeHint(self) -> QSize:
+ return QSize(1030,764)
+
+ def setUpUI(self):
+ self.setWindowTitle("ModelEditor")
+ #splitter
+ self.splitter=QSplitter(self)
+ self.splitter.setOrientation(Qt.Horizontal)
+ #create the treeview
+ self.view=QTreeView(self.splitter)
+ self.view.setHeaderHidden(False)
+ self.view.setSelectionMode(self.view.SingleSelection)
+ #set layout of the main dialog
+ grid=QGridLayout()
+ self.setLayout(grid)
+ grid.addWidget(self.splitter)
+ #create the tab widget
+ tab=QTabWidget(self.splitter)
+ tab.addTab(self.link_ui,"link")
+ tab.addTab(self.collision_ui,"collision")
+ tab.addTab(self.visual_ui,"visual")
+
+ self.splitter.addWidget(self.view)
+ self.splitter.addWidget(tab)
+
+
+
+ def config(self):
+ self.view.clicked[QModelIndex].connect(self.on_tree_item)
+
+
+ def on_tree_item(self,index):
+ item = self.link_model.itemFromIndex(index)
+ # label=item.data(Qt.DisplayRole)
+ item.selected()
+
+
+ def model_tree_config(self,link_str,std_itm):
+ ref_links=[]
+ #create the tree view structure
+ def setup(link_hierarchy,item):
+ #iterate throuhg all children create items and the to tree
+ #seee parse_asm4_model.py
+ for child in link_hierarchy:
+ name=child["name"]
+ row=ModelItem(self,child["name"],child['type'])
+ item.appendRow(row)
+ #make reference to the index of referenced link
+ #This assumes the link already exists in the referenced_elems dictionary
+ if child['type']=='ref':
+ # row.ref_idx=self.referenced_elems[child["ref_label"]]
+ # #refer to the data in the refered link
+ # #since the links are similar
+ # #this can be updated by right clicking on the tree element and clicking break reference
+ # self.elems[child['name']]=self.elems[child["ref_label"]]
+
+ #just update the ref_links since the link might not be defined yet
+ ref_links.append([row,child["ref_label"],name])
+ #store index to referred link
+ elif child['type']=='link':
+ #add to referenced elements
+ self.referenced_elems[child['name']]=row
+
+ else:
+ pass
+ #deb
+ ####
+ #recursion
+ setup(child["children"],row)
+ return
+ setup(link_str,std_itm)
+ #add ref_link related data
+ for item,ref_label,name in ref_links:
+ # item.ref_idx=self.referenced_elems[ref_label]
+ item.create_ref(self.referenced_elems[ref_label])
+
+#+===============================
+#start command
+#================================
+class Model_properties():
+ """My new command"""
+
+ def GetResources(self):
+ return {"Pixmap" : os.path.join(common.ICON_PATH,"edit.svg"),# the name of a svg file available in the resources
+ "Accel" : "Shift+E", # a default shortcut (optional)
+ "MenuText": "Model Edits",
+ "ToolTip" : "Edit link and joint properties"}
+
+ def Activated(self):
+ if hasattr(FreeCAD.ActiveDocument,"Assembly") or hasattr(FreeCAD.ActiveDocument,"Model"):
+ doc=FreeCAD.ActiveDocument
+ self._root_dict=doc.Robot_Description.Proxy.element_dict
+ self.edits=ModelEditor(self._root_dict)
+ else:
+ FreeCAD.Console.PrintMessage("document does not contain an assembly\n")
+ return
+
+ def IsActive(self):
+ if hasattr(FreeCAD.ActiveDocument, "Robot_Description"):
+ return True
+ else:
+ return False
+
+FreeCADGui.addCommand("Model_Editor", Model_properties())
diff --git a/robot_descriptor/sdf_elements/atmosphere.py b/robot_descriptor/sdf_elements/atmosphere.py
index a18af29..87ad8bf 100644
--- a/robot_descriptor/sdf_elements/atmosphere.py
+++ b/robot_descriptor/sdf_elements/atmosphere.py
@@ -1,6 +1,6 @@
-from .. import RD_globals
+from .. import common
#reponsible for creating an element tree using xml.etree
-from ..RD_parser import initialize_element_tree
+from ..RD_utils import initialize_element_tree
import xml.etree.ElementTree as ET
import FreeCAD
@@ -87,23 +87,23 @@ def configUI(self):
self.ui.atm_temp_grad.valueChanged.connect(self.on_temp_gradient)
#callbacks
def on_atm_temp(self):
- RD_globals.set_xml_data(self._atm_elem,"temperature",False,self.properties.temperature)
+ common.set_xml_data(self._atm_elem,"temperature",False,self.properties.temperature)
def on_type_change(self):
- RD_globals.set_xml_data(self._atm_elem,"atmosphere",True,{"type":self.properties.type})
+ common.set_xml_data(self._atm_elem,"atmosphere",True,{"type":self.properties.type})
def on_atm_pressure(self):
- RD_globals.set_xml_data(self._atm_elem,"pressure",False,self.properties.pressure)
+ common.set_xml_data(self._atm_elem,"pressure",False,self.properties.pressure)
def on_temp_gradient(self):
- RD_globals.set_xml_data(self._atm_elem,"temperature_gradient",False,self.properties.temp_gradient)
+ common.set_xml_data(self._atm_elem,"temperature_gradient",False,self.properties.temp_gradient)
#end callbacks
def update_ui(self):
- self.properties.temperature=float(RD_globals.get_xml_data(self._atm_elem,"temperature",False))
- self.properties.pressure=float(RD_globals.get_xml_data(self._atm_elem,"pressure",False))
- self.properties.temp_gradient=float(RD_globals.get_xml_data(self._atm_elem,"temperature_gradient",False))
+ self.properties.temperature=float(common.get_xml_data(self._atm_elem,"temperature",False))
+ self.properties.pressure=float(common.get_xml_data(self._atm_elem,"pressure",False))
+ self.properties.temp_gradient=float(common.get_xml_data(self._atm_elem,"temperature_gradient",False))
#the reset method should also be used for extracting previously configured values
@@ -117,7 +117,7 @@ def reset(self,default:bool=True):
#use RD_globals parse dict to get the element
doc=FreeCAD.ActiveDocument
_root_dict=doc.Robot_Description.Proxy.element_dict
- el_dict=RD_globals.parse_dict(_root_dict,self.parent_path+[self.tag])
+ el_dict=common.parse_dict(_root_dict,self.parent_path+[self.tag])
if el_dict is not None:
el_str=el_dict['elem_str']
self.merge(el_str)
@@ -128,7 +128,7 @@ def reset(self,default:bool=True):
self.update_ui()
def merge(self, el_str):
- RD_globals.merge_elements(self._atm_elem,ET.fromstring(el_str))
+ common.merge_elements(self._atm_elem,ET.fromstring(el_str))
def is_checked(self):
status=self.ui.atmosphere_group.isChecked()
diff --git a/robot_descriptor/sdf_elements/collision.py b/robot_descriptor/sdf_elements/collision.py
new file mode 100644
index 0000000..7533bab
--- /dev/null
+++ b/robot_descriptor/sdf_elements/collision.py
@@ -0,0 +1,98 @@
+from ..RD_utils import initialize_element_tree
+from .. import common
+from . import surface
+import copy
+import os
+import xml.etree.ElementTree as ET
+import FreeCADGui ,FreeCAD
+
+
+class collision_properties:
+ def __init__(self,ui):
+ self.ui=ui
+#laser retro
+ @property
+ def laser_retro(self):
+ return self.ui.collision_laser_retro_sp.value()
+ @laser_retro.setter
+ def laser_retro(self,value):
+ self.ui.collision_laser_retro_sp.setValue(value)
+
+#max contacts
+ @property
+ def max_contacts(self):
+ return self.ui.collision_max_contacts_sp.value()
+ @max_contacts.setter
+ def max_contacts(self,value):
+ self.ui.collision_max_contacts_sp.setValue(value)
+
+#checkboxes
+ @property
+ def collision_laser_retro_cb(self):
+ return self.ui.collision_laser_retro_cb.isChecked()
+
+ @property
+ def collison_max_contacts_cb(self):
+ return self.ui.collison_max_contacts_cb.isChecked()
+
+
+
+class collison:
+ def __init__(self,parent_ui=None):
+ #model editor ui
+ self.ui=parent_ui
+ self.tag='collision'
+ self.parennt_path=''
+ self.properties=collision_properties(self.ui)
+ self.file_name='collision.sdf'
+ self.collision_elem=initialize_element_tree.convdict_2_tree(self.file_name).get_element
+ #surface element
+ self.surface_ui=FreeCADGui.PySideUic.loadUi(os.path.join(common.UI_PATH,"surface.ui"))
+ self.surface_cls=surface.surface(self.surface_ui)
+ self.ui.collision_scroll.setWidget(self.surface_ui)
+ self.configUI()
+ self.updateUI()
+
+ def update_elements(self,item):
+ self.collision_elem=item.collision_element
+ self.surface_cls.update_element(item)
+ self.updateUI()
+
+ def configUI(self):
+ self.ui.collision_max_contacts_sp.valueChanged.connect(self.on_max_contacts)
+ self.ui.collision_laser_retro_sp.valueChanged.connect(
+ lambda value: common.set_xml_data(self.collision_elem,"laser_retro",False,self.properties.laser_retro)
+ )
+#callabcks
+
+ def on_max_contacts(self):
+ common.set_xml_data(self.collision_elem,"max_contacts",False,self.properties.max_contacts)
+
+
+#end callbacks
+
+ def updateUI(self):
+ data=["max_contacts","laser_retro"]
+ for item in data:
+ setattr(self.properties,item,common.get_xml_data(self.collision_elem,item,False))
+
+
+
+ def reset(self):
+ pass
+
+ @property
+ def element(self):
+ t_collision_elem=copy.deepcopy(self.collision_elem)
+ if not self.properties.collision_laser_retro_cb:
+ t_collision_elem.remove("laser_retro")
+
+ if not self.properties.collison_max_contacts_cb:
+ t_collision_elem.remove("max_contacts")
+
+ t_surface=self.surface_cls.element
+
+ if t_collision_elem.find('surface') is None:
+ t_collision_elem.append(t_surface)
+ return t_collision_elem
+
\ No newline at end of file
diff --git a/robot_descriptor/sdf_elements/light.py b/robot_descriptor/sdf_elements/light.py
index 44d34ba..5f9c10b 100644
--- a/robot_descriptor/sdf_elements/light.py
+++ b/robot_descriptor/sdf_elements/light.py
@@ -1,9 +1,10 @@
+from typing import Any
import xml.etree.ElementTree as ET
from PySide import QtCore
from PySide.QtGui import QMessageBox
import FreeCAD
-from ..RD_parser import initialize_element_tree
-from .. import RD_globals
+from ..RD_utils import initialize_element_tree
+from .. import common
import copy
import re
from PySide.QtGui import QColorDialog
@@ -194,7 +195,7 @@ def pose(self,vals:list):
#light
#=================================================================
-class light(RD_globals.color_pickr):
+class light(common.color_pickr):
def __init__(self,ui) -> None:
self.ui=ui
self.file_name='light.sdf'
@@ -221,6 +222,7 @@ def initialize(self):
del self.pose.attrib["degrees"]
# append pose to light
self._light_element.append(self.pose)
+ #this variable will store all the lights added to th world
self.lights={}
#the lights dictionary format
#
@@ -247,7 +249,7 @@ def add_sun(self):
'quadratic':0.001}
for key in sun_properties.keys():
- RD_globals.set_xml_data(sun,key,False,sun_properties[key])
+ common.set_xml_data(sun,key,False,sun_properties[key])
#append to sun
self.lights['sun']=copy.deepcopy(sun)
@@ -272,7 +274,7 @@ def configUI(self):
#type
self.ui.light_type.currentTextChanged.connect(self.on_type)
#intensity
- self.ui.intensity_sp.valueChanged.connect(self.on_intensity)
+ self.ui.intensity_sp.valueChanged.connect(lambda : common.set_xml_data(self._current_light_element,"intensity",False,self.properties.intensity))
#shadows
self.ui.cast_shadows_check_b.stateChanged.connect(self.on_cast_shadows)
#visualize
@@ -377,7 +379,7 @@ def on_name(self):
#update the current name
self.current_light=name
#update the values in the ui
- self.properties.name=RD_globals.get_xml_data(self._current_light_element,[self.tag,'name'],True)
+ self.properties.name=common.get_xml_data(self._current_light_element,[self.tag,'name'],True)
#update type name in the list widget
#get current iten
current_item=self.ui.light_listWidget.currentRow()
@@ -402,52 +404,49 @@ def on_type(self):
else:
self.ui.direction_groupbox.setEnabled(False)
- def on_intensity(self):
- RD_globals.set_xml_data(self._current_light_element,"intensity",False,self.properties.intensity)
-
def on_cast_shadows(self):
- RD_globals.set_xml_data(self._current_light_element,"cast_shadows",False,self.properties.cast_shadows)
+ common.set_xml_data(self._current_light_element,"cast_shadows",False,self.properties.cast_shadows)
def on_visualize(self):
- RD_globals.set_xml_data(self._current_light_element,"visualize",False,self.properties.visualize)
+ common.set_xml_data(self._current_light_element,"visualize",False,self.properties.visualize)
def on_light(self):
- RD_globals.set_xml_data(self._current_light_element,"light_on",False,self.properties.light_on)
+ common.set_xml_data(self._current_light_element,"light_on",False,self.properties.light_on)
def on_diffuse(self):
- RD_globals.set_xml_data(self._current_light_element,"diffuse",False,self.properties.diffuse)
+ common.set_xml_data(self._current_light_element,"diffuse",False,self.properties.diffuse)
self.set_widget_color('diffuse',self.ui.light_diffuse_color_pkr)
def on_specular(self):
- RD_globals.set_xml_data(self._current_light_element,"specular",False,self.properties.specular)
+ common.set_xml_data(self._current_light_element,"specular",False,self.properties.specular)
self.set_widget_color('specular',self.ui.light_specular_color_pkr)
def on_range(self):
- RD_globals.set_xml_data(self._current_light_element,"range",False,self.properties.range)
+ common.set_xml_data(self._current_light_element,"range",False,self.properties.range)
def on_constant(self):
- RD_globals.set_xml_data(self._current_light_element,"constant",False,self.properties.constant)
+ common.set_xml_data(self._current_light_element,"constant",False,self.properties.constant)
def on_linear(self):
- RD_globals.set_xml_data(self._current_light_element,"linear",False,self.properties.linear)
+ common.set_xml_data(self._current_light_element,"linear",False,self.properties.linear)
def on_quadratic(self):
- RD_globals.set_xml_data(self._current_light_element,"quadratic",False,self.properties.quadratic)
+ common.set_xml_data(self._current_light_element,"quadratic",False,self.properties.quadratic)
def on_pose(self):
- RD_globals.set_xml_data(self._current_light_element,"pose",False,self.properties.pose)
+ common.set_xml_data(self._current_light_element,"pose",False,self.properties.pose)
def on_direction(self):
- RD_globals.set_xml_data(self._current_light_element,"direction",False,self.properties.direction)
+ common.set_xml_data(self._current_light_element,"direction",False,self.properties.direction)
def on_inner_angle(self):
- RD_globals.set_xml_data(self._current_light_element,"inner_angle",False,self.properties.inner_angle)
+ common.set_xml_data(self._current_light_element,"inner_angle",False,self.properties.inner_angle)
def on_outer_angle(self):
- RD_globals.set_xml_data(self._current_light_element,"outer_angle",False,self.properties.outer_angle)
+ common.set_xml_data(self._current_light_element,"outer_angle",False,self.properties.outer_angle)
def on_falloff(self):
- RD_globals.set_xml_data(self._current_light_element,"falloff",False,self.properties.falloff)
+ common.set_xml_data(self._current_light_element,"falloff",False,self.properties.falloff)
def on_add(self):
@@ -512,25 +511,25 @@ def on_remove(self):
#update ui
def update_ui(self):
- self.properties.name=RD_globals.get_xml_data(self._current_light_element,[self.tag,'name'],True)
- self.properties.type=RD_globals.get_xml_data(self._current_light_element,['light','type'],True)
- self.properties.intensity=float(RD_globals.get_xml_data(self._current_light_element,"intensity",False))
- self.properties.cast_shadows=RD_globals.get_xml_data(self._current_light_element,"cast_shadows",False)
- self.properties.visualize=RD_globals.get_xml_data(self._current_light_element,"visualize",False)
- self.properties.light_on=RD_globals.get_xml_data(self._current_light_element,"light_on",False)
- self.properties.diffuse=RD_globals.get_xml_data(self._current_light_element,"diffuse",False)
+ self.properties.name=common.get_xml_data(self._current_light_element,[self.tag,'name'],True)
+ self.properties.type=common.get_xml_data(self._current_light_element,['light','type'],True)
+ self.properties.intensity=float(common.get_xml_data(self._current_light_element,"intensity",False))
+ self.properties.cast_shadows=common.get_xml_data(self._current_light_element,"cast_shadows",False)
+ self.properties.visualize=common.get_xml_data(self._current_light_element,"visualize",False)
+ self.properties.light_on=common.get_xml_data(self._current_light_element,"light_on",False)
+ self.properties.diffuse=common.get_xml_data(self._current_light_element,"diffuse",False)
- self.properties.specular=RD_globals.get_xml_data(self._current_light_element,"specular",False)
- self.properties.range=float(RD_globals.get_xml_data(self._current_light_element,"range",False))
- self.properties.constant=float(RD_globals.get_xml_data(self._current_light_element,"constant",False))
- self.properties.linear=float(RD_globals.get_xml_data(self._current_light_element,"linear",False))
- self.properties.quadratic=float(RD_globals.get_xml_data(self._current_light_element,"quadratic",False))
+ self.properties.specular=common.get_xml_data(self._current_light_element,"specular",False)
+ self.properties.range=float(common.get_xml_data(self._current_light_element,"range",False))
+ self.properties.constant=float(common.get_xml_data(self._current_light_element,"constant",False))
+ self.properties.linear=float(common.get_xml_data(self._current_light_element,"linear",False))
+ self.properties.quadratic=float(common.get_xml_data(self._current_light_element,"quadratic",False))
- self.properties.pose=RD_globals.get_xml_data(self._current_light_element,"pose",False)
- self.properties.direction=RD_globals.get_xml_data(self._current_light_element,"direction",False)
- self.properties.inner_angle=float(RD_globals.get_xml_data(self._current_light_element,"inner_angle",False))
- self.properties.outer_angle=float(RD_globals.get_xml_data(self._current_light_element,"outer_angle",False))
- self.properties.falloff=float(RD_globals.get_xml_data(self._current_light_element,"falloff",False))
+ self.properties.pose=common.get_xml_data(self._current_light_element,"pose",False)
+ self.properties.direction=common.get_xml_data(self._current_light_element,"direction",False)
+ self.properties.inner_angle=float(common.get_xml_data(self._current_light_element,"inner_angle",False))
+ self.properties.outer_angle=float(common.get_xml_data(self._current_light_element,"outer_angle",False))
+ self.properties.falloff=float(common.get_xml_data(self._current_light_element,"falloff",False))
#set color picker button colors
self.set_widget_color('diffuse',self.ui.light_diffuse_color_pkr)
@@ -549,7 +548,7 @@ def reset(self,default:bool=True):
direction=self._light_element.find('direction')
doc=FreeCAD.ActiveDocument
_root_dict=doc.Robot_Description.Proxy.element_dict
- el_dict=RD_globals.parse_dict(_root_dict,self.parent_path+[self.tag])
+ el_dict=common.parse_dict(_root_dict,self.parent_path+[self.tag])
if el_dict is not None:
#clear list widget an light
self.ui.light_listWidget.clear()
@@ -583,6 +582,7 @@ def reset(self,default:bool=True):
@property
def element(self):
+ #get all the lights
el_dict=copy.deepcopy(self.lights)
el_list=[]
#remove elements depending on type selection
diff --git a/robot_descriptor/sdf_elements/link.py b/robot_descriptor/sdf_elements/link.py
new file mode 100644
index 0000000..47bf6e8
--- /dev/null
+++ b/robot_descriptor/sdf_elements/link.py
@@ -0,0 +1,378 @@
+import FreeCAD
+from .. import common
+from ..RD_utils import initialize_element_tree
+import copy
+from PySide import QtCore
+import xml.etree.ElementTree as ET
+import FreeCADGui
+import os
+from PySide2.QtWidgets import QTreeView
+from PySide2.QtGui import QStandardItemModel
+
+class link_properties:
+ def __init__(self,ui) -> None:
+ self.ui=ui
+
+#gravity
+ @property
+ def gravity(self):
+
+ state= self.ui.link_gravity_checkbox.isChecked()
+ if state:
+ return str('true')
+ else:
+ return str('false')
+
+ @gravity.setter
+ def gravity(self,state):
+ if state=='true':
+ self.ui.link_gravity_checkbox.setCheckState(QtCore.Qt.Checked)
+ else:
+ self.ui.link_gravity_checkbox.setCheckState(QtCore.Qt.Unchecked)
+
+#enable wind
+ @property
+ def enable_wind(self):
+ state=self.ui.link_enable_wind_checkbox.isChecked()
+ if state:
+ return str('true')
+ else:
+ return str('false')
+
+ @enable_wind.setter
+ def enable_wind(self,state):
+ self.ui.link_enable_wind_checkbox.setCheckState(QtCore.Qt.Checked) if state=='true' else self.ui.link_enable_wind_checkbox.setCheckState(QtCore.Qt.Unchecked)
+
+
+
+#self_collide
+ @property
+ def self_collide(self):
+ return str('true') if self.ui.link_self_collide_checkbox.isChecked() else str('false')
+
+ @self_collide.setter
+ def self_collide(self,state):
+ self.ui.link_self_collide_checkbox.setCheckState(QtCore.Qt.Checked) if state=='true' else self.ui.link_self_collide_checkbox.setCheckState(QtCore.Qt.Unchecked)
+
+#kinematic
+ @property
+ def kinematic(self):
+ return str('true') if self.ui.link_kinematic_checkbox.isChecked() else str('false')
+ @kinematic.setter
+ def kinematic(self,state):
+ self.ui.link_kinematic_checkbox.setCheckState(QtCore.Qt.Checked) if state=='true' else self.ui.link_kinematic_checkbox.setCheckState(QtCore.Qt.Unchecked)
+
+#velocity decay
+ #linear
+ @property
+ def linear(self):
+ return self.ui.velocity_decay_linear_sp.value()
+ @linear.setter
+ def linear(self,value):
+ self.ui.velocity_decay_linear_sp.setValue(value)
+
+ #angular
+ @property
+ def angular(self):
+ return self.ui.link_angular_vel_decay_sp.value()
+ @angular.setter
+ def angular(self,value):
+ self.ui.link_angular_vel_decay_sp.setValue(value)
+
+#inertial
+#fam -> fluid added mass
+#xx
+ @property
+ def fam_xx(self):
+ return self.ui.fam_xx_sp.value()
+ @fam_xx.setter
+ def fam_xx(self,value):
+ self.ui.fam_xx_sp.setValue(value)
+#xy
+ @property
+ def fam_xy(self):
+ return self.ui.fam_xy_sp.value()
+ @fam_xy.setter
+ def fam_xy(self,value):
+ self.ui.fam_xy_sp.setValue(value)
+#xz
+ @property
+ def fam_xz(self):
+ return self.ui.fam_xz_sp.value()
+ @fam_xz.setter
+ def fam_xz(self,value):
+ self.ui.fam_xz_sp.setValue(value)
+
+#p
+ @property
+ def fam_xp(self):
+ return self.ui.fam_xp_sp.value()
+ @fam_xp.setter
+ def fam_xp(self,value):
+ self.ui.fam_xp_sp.setValue(value)
+
+#xq
+ @property
+ def fam_xq(self):
+ return self.ui.fam_xq_sp.value()
+
+ @fam_xq.setter
+ def fam_xq(self,value):
+ self.ui.fam_xq_sp.setValue(value)
+
+#xr
+ @property
+ def fam_xr(self):
+ return self.ui.value()
+ @fam_xr.setter
+ def fam_xr(self,value):
+ self.ui.fam_xr_sp.setValue(value)
+
+#yy
+ @property
+ def fam_yy(self):
+ return self.ui.fam_yy_sp.value()
+ @fam_yy.setter
+ def fam_yy(self,val):
+ self.ui.fam_yy_sp.setValue(val)
+
+#yz
+ @property
+ def fam_yz(self):
+ return self.ui.fam_yz_sp.value()
+ @fam_yz.setter
+ def fam_yz(self,val):
+ self.ui.fam_yz_sp.setValue(val)
+
+#yp
+ @property
+ def fam_yp(self):
+ return self.ui.fam_yp_sp.value()
+ @fam_yp.setter
+ def fam_yp(self,value):
+ self.ui.fam_yp_sp.setValue(value)
+
+#yq
+ @property
+ def fam_yq(self):
+ return self.ui.fam_yq_sp.value()
+ @fam_yq.setter
+ def fam_yq(self,val):
+ self.ui.fam_yq.setValue(val)
+#yr
+ @property
+ def fam_yr(self):
+ return self.ui.fam_yr_sp.value()
+ @fam_yr.setter
+ def fam_yr(self,val):
+ self.ui.fam_yr_sp.setValue(val)
+
+#zz
+ @property
+ def fam_zz(self):
+ return self.ui.fam_zz_sp.value()
+ @fam_zz.setter
+ def fam_zz(self,value):
+ self.ui.fam_zz_sp.setValue(value)
+#zp
+ @property
+ def fam_zp(self):
+ return self.ui.fam_zp_sp.value()
+ @fam_zp.setter
+ def fam_zp(self,val):
+ self.ui.fam_zp_sp.setValue(val)
+
+#zq
+ @property
+ def fam_zq(self):
+ return self.ui.fam_zq_sp.value()
+ @fam_zq.setter
+ def fam_zp(self,val):
+ self.ui.fam_zq_sp.setValue(val)
+
+#zr
+ @property
+ def fam_zr(self):
+ return self.ui.fam_zr_sp.value()
+ @fam_zr.setter
+ def fam_zr(self,val):
+ return self.ui.fam_zr_sp.setValue(val)
+
+#pp
+ @property
+ def fam_pp(self):
+ return self.ui.fam_pp_sp.value()
+ @fam_pp.setter
+ def fam_pp(self,value):
+ self.ui.fam_pp_sp.setValue(value)
+
+#pq
+ @property
+ def fam_pq(self):
+ return self.ui.fam_pq_sp.value()
+ @fam_pq.setter
+ def fam_pq(self,val):
+ self.ui.fam_pq_sp.setValue(val)
+
+#pr
+ @property
+ def fam_pr(self):
+ return self.ui.fam_pr_sp.value()
+ @fam_pr.setter
+ def fam_pr(self,val):
+ self.ui.fam_pr_sp.setValue(val)
+#qq
+ @property
+ def fam_qq(self):
+ return self.ui.fam_qq_sp.value()
+ @fam_qq.setter
+ def fam_qq(self,val):
+ self.ui.fam_qq_sp.setValue(val)
+
+#qr
+ @property
+ def fam_qr(self):
+ return self.ui.fam_qr_sp.value()
+ @fam_qr.setter
+ def fam_qr(self,val):
+ self.ui.fam_qr_sp.setValue(val)
+
+#rr
+ @property
+ def fam_rr(self):
+ return self.ui.fam_rr_sp.value()
+ @fam_rr.setter
+ def fam_rr(self,val):
+ self.ui.fam_rr_sp.setValue(val)
+
+#======================
+#link
+#====================
+class link:
+ def __init__(self,parent_ui,elem_struct=None):
+ self.ui=parent_ui
+ self.file_name='link.sdf'
+ self.tag='link'
+
+ #models will be store as children of sdf
+ self.parent_path=['sdf','model']
+ self.properties=link_properties(self.ui)
+ self._inertial_element=initialize_element_tree.convdict_2_tree("inertial.sdf").get_element
+
+ self.link_element=initialize_element_tree.convdict_2_tree(self.file_name).get_element
+ # self.link_element.append(self._inertial_element)
+ self._root_dict=elem_struct
+ self.configUI()
+ self.UpdateUi()
+# this will be called for the item
+
+ def update_elements(self,item):
+ self.link_element=item._link_element
+ self._inertial_element=item._inertial_element
+ #update the ui after reset
+ self.UpdateUi()
+
+ def configUI(self):
+ self.ui.link_gravity_checkbox.stateChanged.connect(self.onGravity)
+ self.ui.link_enable_wind_checkbox.stateChanged.connect(self.onEnableWind)
+ self.ui.link_self_collide_checkbox.stateChanged.connect(self.onSelfCollide)
+ self.ui.link_kinematic_checkbox.stateChanged.connect(self.onKinematic)
+ self.ui.velocity_decay_linear_sp.valueChanged.connect(self.onLinear)
+ self.ui.link_angular_vel_decay_sp.valueChanged.connect(self.onAngular)
+ #inertial
+ # fam=self._inertial_element.find(".//fluid_added_mass")
+ # fam every time the lmbda is called fam gets updated
+ #the lambda expression captures self ,therefore updates made to all local variables of self will reflected for
+ # each lambda call
+ self.ui.fam_xx_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'xx',False,self.properties.fam_xx) )
+ self.ui.fam_xy_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'xy',False,self.properties.fam_xy) )
+ self.ui.fam_xz_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'xz',False,self.properties.fam_xz) )
+
+ self.ui.fam_xp_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'xp',False,self.properties.fam_xp) )
+ self.ui.fam_xq_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'xq',False,self.properties.fam_xq) )
+ self.ui.fam_xr_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'xr',False,self.properties.fam_xr) )
+
+ #y
+ self.ui.fam_yy_sp.valueChanged.connect(lambda val:common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'yy',False,self.properties.fam_yy))
+ self.ui.fam_yz_sp.valueChanged.connect(lambda val:common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'yz',False,self.properties.fam_yz))
+
+ self.ui.fam_yp_sp.valueChanged.connect(lambda val:common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'yp',False,self.properties.fam_yp))
+ self.ui.fam_yq_sp.valueChanged.connect(lambda val:common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'yq',False,self.properties.fam_yq))
+ self.ui.fam_yr_sp.valueChanged.connect(lambda val:common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'yr',False,self.properties.fam_yr))
+
+ #z
+ self.ui.fam_zz_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'zz',False,self.properties.fam_zz))
+ self.ui.fam_zp_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'zp',False,self.properties.fam_zp))
+ self.ui.fam_zq_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'zq',False,self.properties.fam_zq))
+ self.ui.fam_zr_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'zr',False,self.properties.fam_zr))
+
+ #p
+ self.ui.fam_pp_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'pp',False,self.properties.fam_pp))
+ self.ui.fam_pq_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'pq',False,self.properties.fam_pq))
+ self.ui.fam_pr_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'pr',False,self.properties.fam_pr))
+
+ self.ui.fam_qq_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'qq',False,self.properties.fam_qq))
+ self.ui.fam_qr_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'qr',False,self.properties.fam_qr))
+ self.ui.fam_rr_sp.valueChanged.connect(lambda val: common.set_xml_data(self._inertial_element.find(".//fluid_added_mass"),'rr',False,self.properties.fam_rr))
+
+
+
+
+#end configUI
+ def onGravity(self):
+ common.set_xml_data(self.link_element,'gravity',False,self.properties.gravity)
+
+ def onEnableWind(self):
+ common.set_xml_data(self.link_element,'enable_wind',False,self.properties.enable_wind)
+
+ def onSelfCollide(self):
+ common.set_xml_data(self.link_element,'self_collide',False,self.properties.self_collide)
+
+ def onKinematic(self):
+ common.set_xml_data(self.link_element,'kinematic',False,self.properties.kinematic)
+
+ def onLinear(self):
+ common.set_xml_data(self.link_element,'linear',False,self.properties.linear)
+
+ def onAngular(self):
+ common.set_xml_data(self.link_element,'angular',False,self.properties.angular)
+
+ #element to be updaed sent to the list
+ def UpdateUi(self):
+ element=self.link_element
+ self.properties.gravity=common.get_xml_data(element,'gravity',False)
+ self.properties.enable_wind=common.get_xml_data(element,'enable_wind',False)
+ self.properties.self_collide=common.get_xml_data(element,'self_collide',False)
+ self.properties.kinematic= common.get_xml_data(element,'kinematic',False)
+ self.properties.linear=common.get_xml_data(element,'linear',False)
+ self.properties.angular=common.get_xml_data(element,'angular',False)
+ fam=self._inertial_element.find(".//fluid_added_mass")
+ elem_ui_pairs={"xx":"fam_xx_sp","xy":"fam_xy_sp","xz":"fam_xz_sp","xp":"fam_xp_sp","xq":"fam_xq_sp","xr":"fam_xr_sp",
+ "yy":"fam_yy_sp","yz":"fam_yz_sp","yp":"fam_yp_sp","yq":"fam_yq_sp","yr":"fam_yr_sp","zz":"fam_zz_sp",
+ "zp":"fam_zp_sp","zq":"fam_zq_sp","zr":"fam_zr_sp","pp":"fam_pp_sp","pr":"fam_pr_sp","pq":"fam_pq_sp",
+ "qq":"fam_qq_sp","qr":"fam_qr_sp","rr":"fam_rr_sp"}
+ for tag in elem_ui_pairs.keys():
+ setattr(self.properties,elem_ui_pairs[tag],common.get_xml_data(fam,tag,False))
+
+ #this needs to reset the data of all links in the model
+ #how will this information be extracted
+ def reset(self,default=True):
+ pass
+ @property
+ def element(self):
+ t_link_elem=copy.deepcopy(self.link_element)
+
+ if not self.ui.link_state_groupbox.isChecked():
+ for tag in ["gravity","enable_wind","self_collide","kinematic"]:
+ t_link_elem.remove(t_link_elem.find(tag))
+
+ if self.ui.link_velocity_decay_groupbox.isChecked():
+ t_link_elem.remove(t_link_elem.find("velocity_decay"))
+
+ t_inertial_elem=copy.deepcopy(self._inertial_element)
+ if self.ui.fluid_added_mass_groupbox.isChecked():
+ t_inertial_elem.remove(t_inertial_elem.find("fluid_added_mass"))
+
+ if t_link_elem.find("inertial") is None:
+ t_link_elem.append(t_inertial_elem)
+ return t_link_elem
\ No newline at end of file
diff --git a/robot_descriptor/sdf_elements/material.py b/robot_descriptor/sdf_elements/material.py
new file mode 100644
index 0000000..e4d05d8
--- /dev/null
+++ b/robot_descriptor/sdf_elements/material.py
@@ -0,0 +1,798 @@
+from .. import common
+from ..RD_utils import initialize_element_tree
+import copy
+from PySide import QtGui,QtCore
+import re
+import math
+import csv
+# import Spreadsheet
+import os
+import xml.etree.ElementTree as ET
+import FreeCAD ,FreeCADGui
+
+#matreial
+class material_properties:
+ def __init__(self,ui) -> None:
+ self.ui=ui
+#script uri
+ @property
+ def script_uri(self):
+ return self.ui.material_script_uri_input.text()
+ @script_uri.setter
+ def script_uri(self,text):
+ self.ui.material_script_uri_input.setText(text)
+
+#script name
+ @property
+ def script_name(self):
+ return self.ui.material_script_name.text()
+ @script_name.setter
+ def script_name(self,text):
+ self.ui.material_script_name.setText(text)
+
+#shader_type
+ @property
+ def shader_type(self):
+ return self.ui.shader_type.currentText()
+ @shader_type.setter
+ def shader_type(self,text):
+ self.ui.shader_type.setCurrentText(text)
+#normal map
+ @property
+ def normal_map(self):
+ return self.ui.material_normal_map_input.text()
+ @normal_map.setter
+ def normal_map(self,text):
+ self.ui.material_normal_map_input.setText(text)
+
+
+
+#render order
+ @property
+ def render_order(self):
+ return self.ui.material_render_order_sp.value()
+ @render_order.setter
+ def render_order(self,value):
+ self.ui.material_render_order_sp.setValue(value)
+
+#shininess
+ @property
+ def shininess(self):
+ return self.ui.material_shininess_sp.value()
+ @shininess.setter
+ def shininess(self,value):
+ self.ui.material_shininess_sp.setValue(value)
+
+#lighting
+ @property
+ def lighting(self):
+ state= self.ui.material_lighting_checkbox.isChecked()
+ if state is True:
+ return str('true')
+ else:
+ return str('false')
+ @lighting.setter
+ def lighting(self,state):
+ if state =='true':
+ self.ui.material_lighting_checkbox.setCheckState(QtCore.Qt.Checked)
+ else:
+ self.ui.material_lighting_checkbox.setCheckState(QtCore.Qt.Unchecked)
+
+
+#ambient
+ @property
+ def ambient(self):
+ return [self.ui.material_ambient_R_sp.value(),self.ui.material_ambient_G_sp.value(),
+ self.ui.material_ambient_B_sp.value(),self.ui.material_ambient_A_sp.value()]
+ @ambient.setter
+ def ambient(self,vals):
+ self.ui.material_ambient_R_sp.setValue(vals[0])
+ self.ui.material_ambient_G_sp.setValue(vals[1])
+ self.ui.material_ambient_B_sp.setValue(vals[2])
+ self.ui.material_ambient_A_sp.setValue(vals[3])
+#diffuse
+ @property
+ def diffuse(self):
+ return [self.ui.material_diffuse_R_sp.value(),self.ui.material_diffuse_G_sp.value(),
+ self.ui.material_diffuse_B_sp.value(),self.ui.material_diffuse_A_sp.value()]
+ @diffuse.setter
+ def diffuse(self,vals):
+ self.ui.material_diffuse_R_sp.setValue(vals[0])
+ self.ui.material_diffuse_G_sp.setValue(vals[1])
+ self.ui.material_diffuse_B_sp.setValue(vals[2])
+ self.ui.material_diffuse_A_sp.setValue(vals[3])
+#specular
+ @property
+ def specular(self):
+ return [self.ui.material_specular_R_sp.value(),self.ui.material_specular_G_sp.value(),
+ self.ui.material_specular_B_sp.value(),self.ui.material_specular_A_sp.value()]
+ @specular.setter
+ def specular(self,vals):
+ self.ui.material_specular_R_sp.setValue(vals[0])
+ self.ui.material_specular_G_sp.setValue(vals[1])
+ self.ui.material_specular_B_sp.setValue(vals[2])
+ self.ui.material_specular_A_sp.setValue(vals[3])
+#emissive
+ @property
+ def emissive(self):
+ return [self.ui.material_emissive_R_sp.value(),self.ui.material_emissive_G_sp.value(),
+ self.ui.material_emissive_B_sp.value(),self.ui.material_emissive_A_sp.value()]
+ @emissive.setter
+ def emissive(self,vals):
+ self.ui.material_emissive_R_sp.setValue(vals[0])
+ self.ui.material_emissive_G_sp.setValue(vals[1])
+ self.ui.material_emissive_B_sp.setValue(vals[2])
+ self.ui.material_emissive_A_sp.setValue(vals[3])
+
+#pbr
+#=================================================
+ @property
+ def double_sided(self):
+ return str('true') if self.ui.material_double_sided_checkBox.isChecked() else str('false')
+
+ @double_sided.setter
+ def double_sided(self,state):
+ self.ui.material_double_sided_checkBox.setCheckState(QtCore.Qt.Checked) if state else self.ui.material_double_sided_checkBox.setCheckState(QtCore.Qt.Unchecked)
+
+#metal_albedo_map
+ @property
+ def metal_albedo_map(self):
+ return self.ui.metal_albedo_map_lineEdit.text()
+ @metal_albedo_map.setter
+ def metal_albedo_map(self,text):
+ self.ui.metal_albedo_map_lineEdit.setText(text)
+
+#metal_roughness_map
+ @property
+ def metal_roughness_map(self):
+ return self.ui.metal_roughness_map_lineEdit.text()
+ @metal_roughness_map.setter
+ def metal_roughness_map(self,text):
+ self.ui.metal_roughness_map_lineEdit.setText(text)
+
+#metal_roughness
+ @property
+ def metal_roughness(self):
+ return self.ui.metal_roughness_lineEdit.text()
+ @metal_roughness.setter
+ def metal_roughness(self,text):
+ self.ui.metal_roughness_lineEdit.setText(text)
+
+#metalness_map
+ @property
+ def metalness_map(self):
+ return self.ui.metalness_map_lineEdit.text()
+ @metalness_map.setter
+ def metalness_map(self,text):
+ self.ui.metalness_map_lineEdit.setText(text)
+
+#metalness
+ @property
+ def metalness(self):
+ return self.ui.metalness_sp.value()
+ @metalness.setter
+ def metalness(self,val):
+
+ self.ui.metalness_sp.setValue(val)
+
+#metal_environment_map
+ @property
+ def metal_environment_map(self):
+ return self.ui.metal_environment_map_lineEdit.text()
+ @metal_environment_map.setter
+ def metal_environment_map(self,text):
+ self.ui.metal_environment_map_lineEdit.setText(text)
+
+#metal_ambient_occlusion_map
+ @property
+ def metal_ambient_occlusion_map(self):
+ return self.ui.metal_ambient_occlusion_map_lineEdit.text()
+ @metal_ambient_occlusion_map.setter
+ def metal_ambient_occlusion_map(self,text):
+ self.ui.metal_ambient_occlusion_map_lineEdit.setText(text)
+
+#metal_emissive_map
+ @property
+ def metal_emissive_map(self):
+ return self.ui.metal_emissive_map_lineEdit.text()
+ @metal_emissive_map.setter
+ def metal_emissive_map(self,text):
+ self.ui.metal_emissive_map_lineEdit.setText(text)
+
+#metal_light_map
+ @property
+ def metal_light_map(self):
+ return self.ui.metal_light_map_lineEdit.text()
+ @metal_light_map.setter
+ def metal_light_map(self,text):
+ self.ui.metal_light_map_lineEdit.setText(text)
+
+#metal_uv_set
+ @property
+ def metal_uv_set(self):
+ return self.ui.metal_uv_set_sp.value()
+ @metal_uv_set.setter
+ def metal_uv_set(self,value):
+ self.ui.metal_uv_set_sp.setValue(value)
+
+#metal_normal_map
+ @property
+ def metal_normal_map(self):
+ return self.ui.metal_normal_map_lineEdit.text()
+ @metal_normal_map.setter
+ def metal_normal_map(self,text):
+ self.ui.metal_normal_map_lineEdit.setText(text)
+
+#metal_normal_map_type
+ @property
+ def metal_normal_map_type(self):
+ return self.ui.metal_normal_map_type_comboBox.currentText()
+
+ @metal_normal_map_type.setter
+ def metal_normal_map_type(self,text):
+ self.ui.metal_normal_map_type_comboBox.setCurrentText(text)
+
+#==========
+#specular
+
+#specular_albedo_map
+ @property
+ def specular_albedo_map(self):
+ return self.ui.specular_albedo_map_lineEdit.text()
+ @specular_albedo_map.setter
+ def specular_albedo_map(self,text):
+ self.ui.specular_albedo_map_lineEdit.setText(text)
+
+#specular_map
+ @property
+ def specular_map(self):
+ self.ui.specular_map_lineEdit.text()
+ @specular_map.setter
+ def specular_map(self,text):
+ self.ui.specular_map_lineEdit.setText(text)
+
+#specular_glossiness
+ @property
+ def specular_glossiness(self):
+ return self.ui.specular_glossiness_sp.value()
+ @specular_glossiness.setter
+ def specular_glossiness(self,val):
+ self.ui.specular_glossiness_sp.setValue(val)
+
+#specular_environment_map
+ @property
+ def specular_environment_map(self):
+ return self.ui.specular_environment_map_lineEdit.text()
+ @specular_environment_map.setter
+ def specular_environment_map(self,text):
+ self.ui.specular_environment_map_lineEdit.setText(text)
+
+#specular_ambient_occlusion_map
+ @property
+ def specular_ambient_occlusion_map(self):
+ return self.ui.specular_ambient_occlusion_map_lineEdit.text()
+ @specular_ambient_occlusion_map.setter
+ def specular_ambient_occlusion_map(self,text):
+ self.ui.specular_ambient_occlusion_map_lineEdit.setText(text)
+
+#specular_emissive_map
+ @property
+ def specular_emissive_map(self):
+ return self.ui.specular_emissive_map_lineEdit.text()
+ @specular_emissive_map.setter
+ def specular_emissive_map(self,text):
+ self.ui.specular_emissive_map_lineEdit.setText(text)
+
+#specular_glossiness_map
+ @property
+ def specular_glossiness_map(self):
+ return self.ui.specular_glossiness_map_lineEdit.text()
+ @specular_glossiness_map.setter
+ def specular_glossiness_map(self,text):
+ self.ui.specular_glossiness_map_lineEdit.setText(text)
+
+#specular_light_map
+ @property
+ def specular_light_map(self):
+ return self.ui.specular_light_map_lineEdit.text()
+ @specular_light_map.setter
+ def specular_light_map(self,text):
+ self.ui.specular_light_map_lineEdit.setText(text)
+
+#specular_uv_set
+ @property
+ def specular_uv_set(self):
+ return self.ui.specular_uv_set_sp.value()
+ @specular_uv_set.setter
+ def specular_uv_set(self,val):
+ self.ui.specular_uv_set_sp.setValue(val)
+
+#specular_normal_map
+ @property
+ def specular_normal_map(self):
+ return self.ui.specular_normal_map_lineEdit.text()
+ @specular_normal_map.setter
+ def specular_normal_map(self,text):
+ self.ui.specular_normal_map_lineEdit.setText(text)
+
+#specular_normal_map_type
+ @property
+ def specular_normal_map_type(self):
+ return self.ui.specular_normal_map_type_comboBox.currentText()
+ @specular_normal_map_type.setter
+ def specular_normal_map_type(self,text):
+ self.ui.specular_normal_map_type_comboBox.setCurrentText(text)
+
+#Read only attributes
+#used for optional properties
+#pbr
+ #metal
+ @property
+ def metal_albedo_map_cb(self):
+ return self.ui.metal_albedo_map_checkBox.isChecked()
+
+ @property
+ def metal_roughness_map_cb(self):
+ return self.ui.metal_roughness_map_checkBox.isChecked()
+
+ @property
+ def metal_roughness_cb(self):
+ return self.ui.metal_roughness_checkBox.isChecked()
+ @property
+ def metalness_map_cb(self):
+ return self.ui.metalness_map_checkBox.isChecked()
+
+ @property
+ def metalness_cb(self):
+ return self.ui.metalness_checkBox.isChecked()
+ @property
+ def metal_environment_map_cb(self):
+ return self.ui.metal_environment_map_checkBox.isChecked()
+ @property
+ def metal_ambient_occlusion_map_cb(self):
+ return self.ui.metal_ambient_occlusion_map_checkBox.isChecked()
+
+ @property
+ def metal_emissive_map_cb(self):
+ return self.ui.metal_emissive_map_checkBox.isChecked()
+ @property
+ def metal_normal_map_cb(self):
+ return self.ui.metal_normal_map_groupBox.isChecked()
+
+ @property
+ def metal_light_map_cb(self):
+ return self.ui.metal_light_map_groupBox.isChecked()
+
+ #specular
+ @property
+ def specular_albedo_map_cb(self):
+ return self.ui.specular_albedo_map_checkBox.isChecked()
+ @property
+ def specular_map_cb(self):
+ return self.ui.specular_map_checkBox.isChecked()
+ @property
+ def specular_glossiness_cb(self):
+ return self.ui.specular_glossiness_checkBox.isChecked()
+ @property
+ def specular_environment_map_cb(self):
+ return self.ui.specular_environment_map_checkBox.isChecked()
+ @property
+ def specular_ambient_occlusion_map_cb(self):
+ return self.ui.specular_ambient_occlusion_map_checkBox.isChecked()
+ @property
+ def specular_emissive_map_cb(self):
+ return self.ui.specular_emissive_map_checkBox.isChecked()
+ @property
+ def specular_glossiness_map_cb(self):
+ return self.ui.specular_glossiness_map_checkBox.isChecked()
+ @property
+ def specular_light_map_cb(self):
+ return self.ui.specular_light_map_groupBox.isChecked()
+ @property
+ def specular_normal_map_cb(self):
+ return self.ui.specular_normal_map_groupBox.isChecked()
+
+ #pbr cb
+ @property
+ def pbr_enabled(self):
+ return self.ui.material_pbr_groupbox.isChecked()
+ #metal cb
+ @property
+ def metal_enabled(self):
+ return self.ui.material_metal_groupbox.isChecked()
+ #speculat cb
+ @property
+ def specular_enabled(self):
+ return self.ui.pbr_specular_groupBox.isChecked()
+
+
+
+#===========================================
+#===========================================
+#material element
+#============================================
+#============================================
+class material(common.color_pickr):
+ #since material has multiple parents let the parent class
+ # the parent and parent path data
+ def __init__(self,ui) -> None:
+ super().__init__()
+ self.ui=ui
+ #use the road tag since material will be implemented as part of the road element
+ self.tag='road'
+ self.parent_path=''
+ self.file_name='material.sdf'
+
+ self._material_element=initialize_element_tree.convdict_2_tree(self.file_name).get_element
+ self.properties=material_properties(self.ui)
+ self.configUI()
+ # self.reset(default=False)
+
+ def update_elements(self,item):
+ self._material_element=item._material_element
+ self.updateUi()
+
+ def configUI(self):
+ self.ui.material_script_uri_input.textEdited.connect(self.on_uri)
+ self.ui.material_script_name.textEdited.connect(self.on_uri_name)
+ self.ui.shader_type.currentTextChanged.connect(self.on_shader_type)
+ self.ui.material_normal_map_input.textEdited.connect(self.on_normal_map)
+ self.ui.material_render_order_sp.valueChanged.connect(self.on_material_render_ord)
+ self.ui.material_shininess_sp.valueChanged.connect(self.on_shininess)
+
+ self.ui.material_lighting_checkbox.stateChanged.connect(
+ lambda : common.set_xml_data(self._material_element,"lighting",False,self.properties.lighting)
+ )
+
+ #ambient
+ self.ui.material_ambient_R_sp.valueChanged.connect(self.on_ambient)
+ self.ui.material_ambient_G_sp.valueChanged.connect(self.on_ambient)
+ self.ui.material_ambient_B_sp.valueChanged.connect(self.on_ambient)
+ self.ui.material_ambient_A_sp.valueChanged.connect(self.on_ambient)
+ #diffuse
+ self.ui.material_diffuse_R_sp.valueChanged.connect(self.on_diffuse)
+ self.ui.material_diffuse_G_sp.valueChanged.connect(self.on_diffuse)
+ self.ui.material_diffuse_B_sp.valueChanged.connect(self.on_diffuse)
+ self.ui.material_diffuse_A_sp.valueChanged.connect(self.on_diffuse)
+ #specular
+ self.ui.material_specular_R_sp.valueChanged.connect(self.on_specular)
+ self.ui.material_specular_G_sp.valueChanged.connect(self.on_specular)
+ self.ui.material_specular_B_sp.valueChanged.connect(self.on_specular)
+ self.ui.material_specular_A_sp.valueChanged.connect(self.on_specular)
+ #emissive
+ self.ui.material_emissive_R_sp.valueChanged.connect(self.on_emissive)
+ self.ui.material_emissive_G_sp.valueChanged.connect(self.on_emissive)
+ self.ui.material_emissive_B_sp.valueChanged.connect(self.on_emissive)
+ self.ui.material_emissive_A_sp.valueChanged.connect(self.on_emissive)
+
+ #color picker buttons
+ self.ui.material_ambient_color_pkr.clicked.connect(self.on_ambient_color_pkr)
+ self.ui.material_diffuse_color_pkr.clicked.connect(self.on_diffuse_color_pkr)
+ self.ui.material_specular_color_pkr.clicked.connect(self.on_specular_color_pkr)
+ self.ui.material_emissive_color_pkr.clicked.connect(self.on_emissive_color_pkr)
+
+
+#pbr
+ #metal
+ #properties under the metal element
+ self.ui.metal_albedo_map_lineEdit.textEdited.connect(self.on_metal_albedo_map)
+
+ self.ui.metal_roughness_map_lineEdit.textEdited.connect(self.on_metal_roughness_map)
+ self.ui.metal_roughness_lineEdit.textEdited.connect(self.on_metal_roughness)
+
+ self.ui.metalness_map_lineEdit.textEdited.connect(self.on_metalness_map)
+
+ self.ui.metalness_sp.valueChanged.connect(self.on_metalness)
+
+ self.ui.metal_environment_map_lineEdit.textEdited.connect(self.on_metal_environment_map)
+
+ self.ui.metal_ambient_occlusion_map_lineEdit.textEdited.connect(self.on_metal_ambient_occlusion_map)
+
+ self.ui.metal_emissive_map_lineEdit.textEdited.connect(self.on_metal_emissive_map)
+
+ self.ui.metal_light_map_lineEdit.textEdited.connect(self.on_metal_light_map)
+
+ self.ui.metal_uv_set_sp.valueChanged.connect(self.on_metal_uv_set)
+
+ self.ui.metal_normal_map_lineEdit.textEdited.connect(self.on_metal_normal_map)
+ self.ui.metal_normal_map_type_comboBox.currentTextChanged.connect(self.on_metal_normal_map_type)
+
+ #specular
+ #elements under the specular subelement
+ specular=self._material_element.find(".//pbr/specular")
+ self.ui.specular_albedo_map_lineEdit.textEdited.connect(self.on_specular_albdedo_map)
+
+ self.ui.specular_map_lineEdit.textEdited.connect(self.on_specular_map)
+
+ self.ui.specular_glossiness_sp.valueChanged.connect(self.on_specular_glossiness)
+
+ self.ui.specular_environment_map_lineEdit.textEdited.connect(self.on_specular_environment_map)
+ self.ui.specular_ambient_occlusion_map_lineEdit.textEdited.connect(self.on_specular_ambient_occlusion_map)
+ self.ui.specular_emissive_map_lineEdit.textEdited.connect(self.on_specular_emissive_map)
+ self.ui.specular_glossiness_map_lineEdit.textEdited.connect(self.on_specular_glossiness_map)
+ self.ui.specular_light_map_lineEdit.textEdited.connect(self.on_specular_light_map)
+
+ self.ui.specular_uv_set_sp.valueChanged.connect(self.on_specular_uv_set)
+
+ self.ui.specular_normal_map_lineEdit.textEdited.connect(self.on_specular_normal_map
+ )
+ self.ui.specular_normal_map_type_comboBox.currentTextChanged.connect(self.on_specular_normal_map_type
+ )
+
+#callbacks
+ #metal
+ def on_metal_albedo_map(self):
+ metal=self._material_element.find('.//pbr/metal')
+ common.set_xml_data(metal,'albedo_map',False,self.properties.metal_albedo_map)
+
+ def on_metal_roughness_map(self):
+ metal=self._material_element.find('.//pbr/metal')
+ common.set_xml_data(metal,'roughness_map',False,self.properties.metal_roughness_map)
+
+ def on_metal_roughness(self):
+ metal=self._material_element.find('.//pbr/metal')
+ common.set_xml_data(metal,"roughness",False,self.properties.metal_roughness)
+
+
+ def on_metalness_map(self):
+ metal=self._material_element.find('.//pbr/metal')
+ common.set_xml_data(metal,"metalness_map",False,self.properties.metalness_map)
+
+ def on_metalness(self):
+ metal=self._material_element.find('.//pbr/metal')
+ common.set_xml_data(metal,"metalness",False,self.properties.metalness)
+
+ def on_metal_environment_map(self):
+ metal=self._material_element.find('.//pbr/metal')
+ common.set_xml_data(metal,"environment_map",False,self.properties.metal_environment_map)
+
+ def on_metal_ambient_occlusion_map(self):
+ metal=self._material_element.find('.//pbr/metal')
+ common.set_xml_data(metal,"ambient_occlusion_map",False,self.properties.metal_ambient_occlusion_map)
+
+ def on_metal_emissive_map(self):
+ metal=self._material_element.find('.//pbr/metal')
+ common.set_xml_data(metal,"emissive_map",False,self.properties.metal_emissive_map)
+
+ def on_metal_light_map(self):
+ metal=self._material_element.find('.//pbr/metal')
+ common.set_xml_data(metal,"light_map",False,self.properties.metal_light_map)
+
+ def on_metal_uv_set(self):
+ metal=self._material_element.find('.//pbr/metal')
+ common.set_xml_data(metal,"light_map",True,{"uv_set":self.properties.metal_uv_set})
+
+
+ def on_metal_normal_map(self):
+ metal=self._material_element.find(' common.set_xml_data(specular,"albedo_map",False,self.properties.specular_albedo_map).//pbr/metal')
+ common.set_xml_data(metal,"normal_map",False,self.properties.metal_normal_map)
+
+
+ def on_metal_normal_map_type(self):
+ metal=self._material_element.find('.//pbr/metal')
+ common.set_xml_data(metal,"normal_map",True,{"type":self.properties.metal_normal_map_type})
+
+ #specular
+
+ def on_specular_albdedo_map(self):
+ specular=self._material_element.find(".//pbr/specular")
+ common.set_xml_data(specular,"albedo_map",False,self.properties.specular_albedo_map)
+
+ def on_specular_map(self):
+ specular=self._material_element.find(".//pbr/specular")
+ common.set_xml_data(specular,"specular_map",False,self.properties.specular_map)
+
+ def on_specular_glossiness(self):
+ specular=self._material_element.find(".//pbr/specular")
+ common.set_xml_data(specular,"glossiness",False,self.properties.specular_glossiness)
+
+
+ def on_specular_environment_map(self):
+ specular=self._material_element.find(".//pbr/specular")
+ common.set_xml_data(specular,"environment_map",False,self.properties.specular_environment_map)
+
+ def on_specular_ambient_occlusion_map(self):
+ specular=self._material_element.find(".//pbr/specular")
+ common.set_xml_data(specular,"ambient_occlusion_map",False,self.properties.specular_ambient_occlusion_map)
+
+ def on_specular_emissive_map(self):
+ specular=self._material_element.find(".//pbr/specular")
+ common.set_xml_data(specular,"emissive_map",False,self.properties.specular_emissive_map)
+
+ def on_specular_glossiness_map(self):
+ specular=self._material_element.find(".//pbr/specular")
+ common.set_xml_data(specular,"glossiness_map",False,self.properties.specular_glossiness_map)
+
+ def on_specular_light_map(self):
+ specular=self._material_element.find(".//pbr/specular")
+ common.set_xml_data(specular,"light_map",False,self.properties.specular_light_map)
+
+ def on_specular_uv_set(self):
+ specular=self._material_element.find(".//pbr/specular")
+ common.set_xml_data(specular,"light_map",True,{"uv_set":self.properties.specular_uv_set})
+
+ def on_specular_normal_map(self):
+ specular=self._material_element.find(".//pbr/specular")
+ common.set_xml_data(specular,"normal_map",False,self.properties.specular_normal_map)
+
+ def on_specular_normal_map_type(self):
+ specular=self._material_element.find(".//pbr/specular")
+ common.set_xml_data(specular,"normal_map",True,{"type":self.properties.specular_normal_map_type})
+
+
+ def on_uri(self):
+ common.set_xml_data(self._material_element,'uri',False,self.properties.script_uri)
+
+ def on_uri_name(self):
+ common.set_xml_data(self._material_element,'name',False,self.properties.script_name)
+
+ def on_shader_type(self):
+ common.set_xml_data(self._material_element,'shader',True,{'type':self.properties.shader_type})
+
+
+#normal map
+ def on_normal_map(self):
+ common.set_xml_data(self._material_element,'normal_map',False,self.properties.normal_map)
+
+#material render order
+ def on_material_render_ord(self):
+ common.set_xml_data(self._material_element,'render_order',False,self.properties.render_order)
+
+ def on_shininess(self):
+ common.set_xml_data(self._material_element,'shininess',False,self.properties.shininess)
+
+ def on_ambient(self):
+ common.set_xml_data(self._material_element,'ambient',False,self.properties.ambient)
+ self.set_widget_color('ambient',self.ui.material_ambient_color_pkr)
+
+ def on_diffuse(self):
+ common.set_xml_data(self._material_element,'diffuse',False,self.properties.diffuse)
+ self.set_widget_color('diffuse',self.ui.material_diffuse_color_pkr)
+
+ def on_specular(self):
+ common.set_xml_data(self._material_element,'specular',False,self.properties.specular)
+ self.set_widget_color('specular',self.ui.material_specular_color_pkr)
+
+ def on_emissive(self):
+ common.set_xml_data(self._material_element,'emissive',False,self.properties.emissive)
+ self.set_widget_color('emissive',self.ui.material_emissive_color_pkr)
+
+ def on_ambient_color_pkr(self):
+ self.color_picker('ambient',self.ui.material_ambient_color_pkr)
+
+ def on_diffuse_color_pkr(self):
+ self.color_picker('diffuse',self.ui.material_diffuse_color_pkr)
+
+ def on_specular_color_pkr(self):
+ self.color_picker('specular',self.ui.material_specular_color_pkr)
+
+ def on_emissive_color_pkr(self):
+ self.color_picker('emissive',self.ui.material_emissive_color_pkr)
+
+ def updateUi(self):
+ self.properties.script_uri=common.get_xml_data(self._material_element,'uri',False)
+ self.properties.script_name=common.get_xml_data(self._material_element,'name',False)
+ self.properties.shader_type=common.get_xml_data(self._material_element,'type')
+ self.properties.normal_map=common.get_xml_data(self._material_element,'normal_map',False)
+ self.properties.render_order=common.get_xml_data(self._material_element,'render_order',False)
+ self.properties.shininess=common.get_xml_data(self._material_element,'shininess',False)
+ self.properties.ambient=common.get_xml_data(self._material_element,'ambient',False)
+ self.properties.diffuse=common.get_xml_data(self._material_element,'diffuse',False)
+ self.properties.specular=common.get_xml_data(self._material_element,'specular',False)
+ self.properties.emissive=common.get_xml_data(self._material_element,'emissive',False)
+ self.properties.lighting=common.get_xml_data(self._material_element,"lighting",False)
+ #pbr
+ #metal
+ metal=self._material_element.find('.//pbr/metal')
+ # { tag : property }
+ #properties is the property name defined in the properties class
+ items={'albedo_map':"metal_albedo_map",'roughness_map':"metal_roughness_map","metalness_map":"metalness_map","metalness":"metalness",
+ "environment_map":"metal_environment_map","ambient_occlusion_map":"metal_ambient_occlusion_map","emissive_map":"metal_emissive_map",
+ "light_map":"metal_light_map","normal_map":"metal_normal_map"}
+ #set the data for all items
+ for tag in items.keys():
+ setattr(self.properties,items[tag],common.get_xml_data(metal,tag,False))
+ #set element attributes
+ self.properties.metal_uv_set=common.get_xml_data(metal,["light_map","uv_set"],True)
+ self.properties.metal_normal_map_type=common.get_xml_data(metal,["normal_map","type"],True)
+ #specular
+ specular=self._material_element.find(".//pbr/specular")
+ #{tag : attribute}
+ specular_items={"albedo_map":"specular_albedo_map","specular_map":"specular_map","glossiness":"specular_glossiness","environment_map":"specular_environment_map",
+ "ambient_occlusion_map": "specular_ambient_occlusion_map","emissive_map":"specular_emissive_map","glossiness_map":"specular_glossiness_map",
+ "light_map":"specular_light_map","normal_map":"specular_normal_map"}
+ for tag in specular_items:
+ setattr(self.properties,specular_items[tag],common.get_xml_data(specular,tag,False))
+
+ self.properties.specular_uv_set=common.get_xml_data(specular,["light_map","uv_set"],True)
+ self.properties.specular_normal_map_type=common.get_xml_data(specular,["normal_map","type"],True)
+
+ #style sheets
+ self.set_widget_color('ambient',self.ui.material_ambient_color_pkr)
+ self.set_widget_color('diffuse',self.ui.material_diffuse_color_pkr)
+ self.set_widget_color('specular',self.ui.material_specular_color_pkr)
+ self.set_widget_color('emissive',self.ui.material_emissive_color_pkr)
+
+ def reset(self,default=True):
+ pass
+
+
+#merger
+#this merge method repeats alot
+ def merge_elements(self,destination_el, source_el):
+ common.merge_elements(destination_el,source_el)
+
+ @property
+ def element(self):
+ #make deep copy to avoid altering local element
+ temp_el=copy.deepcopy(self._material_element)
+ #script
+ if self.ui.material_script_groupBox.isChecked():
+ #if script is checked remove al other color properties
+ tags=['shader','ambient','diffuse','specular','emissive','shininess','render_order'
+ ,'lighting']
+ for elem_tag in tags:
+ temp_el.remove(temp_el.find('.//'+elem_tag))
+ else:
+ temp_el.remove(temp_el.find('.//script'))
+ #shader
+ if self.ui.material_shader_groupBox.isChecked():
+ #if shader is checked check if the normal map is checked and remve it if neccessary
+ if self.properties.normal_map_checkbox is False:
+ shader_el=temp_el.find('.//shader')
+ shader_el.remove(shader_el.find('.//normal_map'))
+
+ else:
+ temp_el.remove(temp_el.find('.//shader'))
+
+ #remove color related configs
+ if self.ui.material_ambient_groupbox.isChecked() is False:
+ temp_el.remove(temp_el.find('.//ambient'))
+
+ if self.ui.material_diffuse_groupbox.isChecked() is False:
+ temp_el.remove(temp_el.find('.//diffuse'))
+
+ if self.ui.material_specular_groupbox.isChecked() is False:
+ temp_el.remove(temp_el.find('.//specular'))
+
+ if self.ui.material_emissive_groupbox.isChecked() is False:
+ temp_el.remove(temp_el.find('.//emissive'))
+
+ #logic for materials related to pbr
+ pbr=temp_el.find('pbr')
+ if self.properties.pbr_enabled and pbr is not None:
+ metal=temp_el.find('.//pbr/metal')
+ if self.properties.metal_enabled and metal is not None:
+ #{tag : property}
+ #where propertty are the propertieswhose names end with with _cb
+ metal_opt_elems={'albedo_map':"metal_albedo_map_cb",'roughness_map':"metal_roughness_map_cb","metalness_map":"metalness_map_cb"
+ ,"metalness":"metalness_cb",
+ "environment_map":"metal_environment_map_cb","ambient_occlusion_map":"metal_ambient_occlusion_map_cb","emissive_map":"metal_emissive_map_cb",
+ "light_map":"metal_light_map_cb","normal_map":"metal_normal_map_cb"}
+ for tag in metal_opt_elems.keys():
+ if getattr(self.properties,metal_opt_elems[tag]) is not True:
+ metal.remove(metal.find('.//'+tag))
+ else:
+ if metal is not None:
+ temp_el.find('.//pbr').remove(metal)
+ #related to specular
+ specular=temp_el.find(".//pbr/specular")
+ if self.properties.specular_enabled and specular is not None:
+ #{tag : property}
+ #where propertty are the properties whose names end with with _cb
+ specular_opts={"albedo_map":"specular_albedo_map_cb","specular_map":"specular_map_cb","glossiness":"specular_glossiness_cb",
+ "environment_map":"specular_environment_map_cb",
+ "ambient_occlusion_map": "specular_ambient_occlusion_map_cb","emissive_map":"specular_emissive_map_cb",
+ "glossiness_map":"specular_glossiness_map_cb",
+ "light_map":"specular_light_map_cb","normal_map":"specular_normal_map_cb"}
+ for tag in specular_opts.keys():
+ if getattr(self.properties,specular_opts[tag]) is not True:
+ specular.remove(specular.find('.//'+tag))
+ else:
+ if specular is not None:
+ temp_el.find('.//pbr').remove(specular)
+ else:
+ if pbr is not None:
+ temp_el.remove(pbr)
+
+ return temp_el
\ No newline at end of file
diff --git a/robot_descriptor/sdf_elements/model.py b/robot_descriptor/sdf_elements/model.py
new file mode 100644
index 0000000..a75a114
--- /dev/null
+++ b/robot_descriptor/sdf_elements/model.py
@@ -0,0 +1,9 @@
+from ..RD_utils import initialize_element_tree
+
+
+class model:
+ def __intit__(self,root_d):
+ self.file_name='model.sdf'
+ self.parent_path=['sdf']
+ self._root_dict=root_d
+ self.model_element=initialize_element_tree.convdict_2_tree(self.file_name)
\ No newline at end of file
diff --git a/robot_descriptor/sdf_elements/physics.py b/robot_descriptor/sdf_elements/physics.py
index 9f91fd8..ebf620e 100644
--- a/robot_descriptor/sdf_elements/physics.py
+++ b/robot_descriptor/sdf_elements/physics.py
@@ -1,7 +1,7 @@
import xml.etree.ElementTree as ET
-from ..RD_parser import initialize_element_tree
-from .. import RD_globals
+from ..RD_utils import initialize_element_tree
+from .. import common
import copy
from PySide import QtCore
@@ -394,67 +394,67 @@ def configUI(self):
#callbacks
def on_type(self):
- RD_globals.set_xml_data(self._ode_elem,"type",False,self.solver.type)
+ common.set_xml_data(self._ode_elem,"type",False,self.solver.type)
def on_min_step_size(self):
- RD_globals.set_xml_data(self._ode_elem,"min_step_size",False,self.solver.min_step_size)
+ common.set_xml_data(self._ode_elem,"min_step_size",False,self.solver.min_step_size)
def on_island_threads(self):
- RD_globals.set_xml_data(self._ode_elem,"island_threads",False,self.solver.island_threads)
+ common.set_xml_data(self._ode_elem,"island_threads",False,self.solver.island_threads)
def on_friction_model(self):
- RD_globals.set_xml_data(self._ode_elem,"friction_model",False,self.solver.friction_model)
+ common.set_xml_data(self._ode_elem,"friction_model",False,self.solver.friction_model)
def on_iters(self):
- RD_globals.set_xml_data(self._ode_elem,"iters",False,self.solver.iters)
+ common.set_xml_data(self._ode_elem,"iters",False,self.solver.iters)
def on_precon_iters(self):
- RD_globals.set_xml_data(self._ode_elem,"precon_iters",False,self.solver.precon_iters)
+ common.set_xml_data(self._ode_elem,"precon_iters",False,self.solver.precon_iters)
def on_sor(self):
- RD_globals.set_xml_data(self._ode_elem,"sor",False,self.solver.sor)
+ common.set_xml_data(self._ode_elem,"sor",False,self.solver.sor)
def on_dynamic_moi_rescaling(self):
- RD_globals.set_xml_data(self._ode_elem,"use_dynamic_moi_rescaling",False,self.solver.use_dynamic_moi_rescaling)
+ common.set_xml_data(self._ode_elem,"use_dynamic_moi_rescaling",False,self.solver.use_dynamic_moi_rescaling)
def on_thread_position_correction(self):
- RD_globals.set_xml_data(self._ode_elem,"thread_position_correction",False,self.solver.thread_position_correction)
+ common.set_xml_data(self._ode_elem,"thread_position_correction",False,self.solver.thread_position_correction)
def on_cfm(self):
- RD_globals.set_xml_data(self._ode_elem,"cfm",False,self.constraints.cfm)
+ common.set_xml_data(self._ode_elem,"cfm",False,self.constraints.cfm)
def on_erp(self):
- RD_globals.set_xml_data(self._ode_elem,"erp",False,self.constraints.erp)
+ common.set_xml_data(self._ode_elem,"erp",False,self.constraints.erp)
def on_contact_max_correction_vel(self):
- RD_globals.set_xml_data(self._ode_elem,"contact_max_correcting_vel",False,self.constraints.contact_max_correcting_vel)
+ common.set_xml_data(self._ode_elem,"contact_max_correcting_vel",False,self.constraints.contact_max_correcting_vel)
def on_contact_surface_layer(self):
- RD_globals.set_xml_data(self._ode_elem,"contact_surface_layer",False,self.constraints.contact_surface_layer)
+ common.set_xml_data(self._ode_elem,"contact_surface_layer",False,self.constraints.contact_surface_layer)
#end callbacks
def update_ui(self):
#solver
- self.solver.type=RD_globals.get_xml_data(self._ode_elem,"type",False)
- self.solver.min_step_size=float(RD_globals.get_xml_data(self._ode_elem,"min_step_size",False))
- self.solver.island_threads=int(RD_globals.get_xml_data(self._ode_elem,"island_threads",False))
- self.solver.iters=float(RD_globals.get_xml_data(self._ode_elem,"iters",False))
- self.solver.precon_iters=int(RD_globals.get_xml_data(self._ode_elem,"precon_iters",False))
- self.solver.sor=float(RD_globals.get_xml_data(self._ode_elem,"sor",False))
- self.solver.friction_model=RD_globals.get_xml_data(self._ode_elem,"friction_model",False)
-
- if RD_globals.get_xml_data(self._ode_elem,"use_dynamic_moi_rescaling",False)=='true':
+ self.solver.type=common.get_xml_data(self._ode_elem,"type",False)
+ self.solver.min_step_size=float(common.get_xml_data(self._ode_elem,"min_step_size",False))
+ self.solver.island_threads=int(common.get_xml_data(self._ode_elem,"island_threads",False))
+ self.solver.iters=float(common.get_xml_data(self._ode_elem,"iters",False))
+ self.solver.precon_iters=int(common.get_xml_data(self._ode_elem,"precon_iters",False))
+ self.solver.sor=float(common.get_xml_data(self._ode_elem,"sor",False))
+ self.solver.friction_model=common.get_xml_data(self._ode_elem,"friction_model",False)
+
+ if common.get_xml_data(self._ode_elem,"use_dynamic_moi_rescaling",False)=='true':
self.solver.use_dynamic_moi_rescaling=True
else:
self.solver.use_dynamic_moi_rescaling=False
- if RD_globals.get_xml_data(self._ode_elem,"thread_position_correction",False)=='true':
+ if common.get_xml_data(self._ode_elem,"thread_position_correction",False)=='true':
self.solver.thread_position_correction=True
else:
self.solver.thread_position_correction=False
#constraints
- self.constraints.cfm=float(RD_globals.get_xml_data(self._ode_elem,"cfm",False))
- self.constraints.erp=float(RD_globals.get_xml_data(self._ode_elem,"erp"))
- self.constraints.contact_max_correcting_vel=float(RD_globals.get_xml_data(self._ode_elem,"contact_max_correcting_vel"))
- self.constraints.contact_surface_layer=float(RD_globals.get_xml_data(self._ode_elem,"contact_surface_layer"))
+ self.constraints.cfm=float(common.get_xml_data(self._ode_elem,"cfm",False))
+ self.constraints.erp=float(common.get_xml_data(self._ode_elem,"erp"))
+ self.constraints.contact_max_correcting_vel=float(common.get_xml_data(self._ode_elem,"contact_max_correcting_vel"))
+ self.constraints.contact_surface_layer=float(common.get_xml_data(self._ode_elem,"contact_surface_layer"))
#this takes an element and updates the internal ones
def reset(self,new_elem:ET.Element):
self._get_ode_elem(new_elem)
@@ -495,45 +495,45 @@ def configUI(self):
self.ui.bullet_split_impulse_penetration_threshold.valueChanged.connect(self.on_splt_impl_pen_tr)
#solver
def on_type(self):
- RD_globals.set_xml_data(self._bullet_element,"solver",False,self.solver.type)
+ common.set_xml_data(self._bullet_element,"solver",False,self.solver.type)
def on_min_step_size(self):
- RD_globals.set_xml_data(self._bullet_element,"min_step_size",False,self.solver.min_step_size)
+ common.set_xml_data(self._bullet_element,"min_step_size",False,self.solver.min_step_size)
def on_iters(self):
- RD_globals.set_xml_data(self._bullet_element,"iters",False,self.solver.iters)
+ common.set_xml_data(self._bullet_element,"iters",False,self.solver.iters)
def on_sor(self):
- RD_globals.set_xml_data(self._bullet_element,"sor",False,self.solver.sor)
+ common.set_xml_data(self._bullet_element,"sor",False,self.solver.sor)
#constraints
def on_cfm(self):
- RD_globals.set_xml_data(self._bullet_element,"cfm",False,self.constraints.cfm)
+ common.set_xml_data(self._bullet_element,"cfm",False,self.constraints.cfm)
def on_erp(self):
- RD_globals.set_xml_data(self._bullet_element,"erp",False,self.constraints.erp)
+ common.set_xml_data(self._bullet_element,"erp",False,self.constraints.erp)
def on_cont_surf_layer(self):
- RD_globals.set_xml_data(self._bullet_element,"contact_surface_layer",False,self.constraints.contact_surface_layer)
+ common.set_xml_data(self._bullet_element,"contact_surface_layer",False,self.constraints.contact_surface_layer)
def on_split_impulse(self):
- RD_globals.set_xml_data(self._bullet_element,"split_impulse",False,self.constraints.split_impulse)
+ common.set_xml_data(self._bullet_element,"split_impulse",False,self.constraints.split_impulse)
def on_splt_impl_pen_tr(self):
- RD_globals.set_xml_data(self._bullet_element,"split_impulse_penetration_threshold",False,self.constraints.split_impulse_penetration_threshold)
+ common.set_xml_data(self._bullet_element,"split_impulse_penetration_threshold",False,self.constraints.split_impulse_penetration_threshold)
def update_ui(self):
#solver ui
- self.solver.type=RD_globals.get_xml_data(self._bullet_element,"type",False)
- self.solver.min_step_size=float(RD_globals.get_xml_data(self._bullet_element,"min_step_size",False))
- self.solver.iters=int(RD_globals.get_xml_data(self._bullet_element,"iters",False))
- self.solver.sor=float(RD_globals.get_xml_data(self._bullet_element,"sor",False))
+ self.solver.type=common.get_xml_data(self._bullet_element,"type",False)
+ self.solver.min_step_size=float(common.get_xml_data(self._bullet_element,"min_step_size",False))
+ self.solver.iters=int(common.get_xml_data(self._bullet_element,"iters",False))
+ self.solver.sor=float(common.get_xml_data(self._bullet_element,"sor",False))
#constrains ui
- self.constraints.cfm=float(RD_globals.get_xml_data(self._bullet_element,"cfm",False))
- self.constraints.erp=float(RD_globals.get_xml_data(self._bullet_element,"erp",False))
- self.constraints.contact_surface_layer=float(RD_globals.get_xml_data(self._bullet_element,"contact_surface_layer"))
- self.constraints.split_impulse_penetration_threshold=float(RD_globals.get_xml_data(self._bullet_element,
+ self.constraints.cfm=float(common.get_xml_data(self._bullet_element,"cfm",False))
+ self.constraints.erp=float(common.get_xml_data(self._bullet_element,"erp",False))
+ self.constraints.contact_surface_layer=float(common.get_xml_data(self._bullet_element,"contact_surface_layer"))
+ self.constraints.split_impulse_penetration_threshold=float(common.get_xml_data(self._bullet_element,
"split_impulse_penetration_threshold"))
- if RD_globals.get_xml_data(self._bullet_element,"split_impulse")=='true':
+ if common.get_xml_data(self._bullet_element,"split_impulse")=='true':
self.constraints.split_impulse=True
else:
self.constraints.split_impulse=False
@@ -579,58 +579,58 @@ def configUI(self):
#callbacks
#properties
def on_min_step_size(self):
- RD_globals.set_xml_data(self._simbody_element,"min_step_size",False,self.properties.min_step_size)
+ common.set_xml_data(self._simbody_element,"min_step_size",False,self.properties.min_step_size)
def on_accuracy(self):
- RD_globals.set_xml_data(self._simbody_element,"accuracy",False,self.properties.accuracy)
+ common.set_xml_data(self._simbody_element,"accuracy",False,self.properties.accuracy)
def on_max_trans_vel(self):
- RD_globals.set_xml_data(self._simbody_element,"max_transient_velocity",False,self.properties.maximum_transient_velocity)
+ common.set_xml_data(self._simbody_element,"max_transient_velocity",False,self.properties.maximum_transient_velocity)
#contact
def on_stiffness(self):
- RD_globals.set_xml_data(self._simbody_element,"stiffness",False,self.contact.stiffness)
+ common.set_xml_data(self._simbody_element,"stiffness",False,self.contact.stiffness)
def on_plst_coef_rest(self):
- RD_globals.set_xml_data(self._simbody_element,"plastic_coef_restitution",False,self.contact.plastic_coef_restitution)
+ common.set_xml_data(self._simbody_element,"plastic_coef_restitution",False,self.contact.plastic_coef_restitution)
def on_plst_imp_vel(self):
- RD_globals.set_xml_data(self._simbody_element,"plastic_impact_velocity",False,self.contact.plastic_impact_velocity)
+ common.set_xml_data(self._simbody_element,"plastic_impact_velocity",False,self.contact.plastic_impact_velocity)
def on_ovr_imp_cpt_vel(self):
- RD_globals.set_xml_data(self._simbody_element,"override_impact_capture_velocity",False,self.contact.override_impact_capture_velocity)
+ common.set_xml_data(self._simbody_element,"override_impact_capture_velocity",False,self.contact.override_impact_capture_velocity)
def on_dissipation(self):
- RD_globals.set_xml_data(self._simbody_element,"dissipation",False,self.contact.dissipation)
+ common.set_xml_data(self._simbody_element,"dissipation",False,self.contact.dissipation)
def on_static_fric(self):
- RD_globals.set_xml_data(self._simbody_element,"static_friction",False,self.contact.static_friction)
+ common.set_xml_data(self._simbody_element,"static_friction",False,self.contact.static_friction)
def on_dyn_fric(self):
- RD_globals.set_xml_data(self._simbody_element,"dynamic_friction",False,self.contact.dynamic_friction)
+ common.set_xml_data(self._simbody_element,"dynamic_friction",False,self.contact.dynamic_friction)
def on_vsc_fric(self):
- RD_globals.set_xml_data(self._simbody_element,"viscous_friction",False,self.contact.viscous_friction)
+ common.set_xml_data(self._simbody_element,"viscous_friction",False,self.contact.viscous_friction)
def on_ovr_st_tr_vel(self):
- RD_globals.set_xml_data(self._simbody_element,"override_stiction_transition_velocity",False,self.contact.override_stiction_transition_velocity)
+ common.set_xml_data(self._simbody_element,"override_stiction_transition_velocity",False,self.contact.override_stiction_transition_velocity)
#update ui
def update_ui(self):
#properties
- self.properties.min_step_size=float(RD_globals.get_xml_data(self._simbody_element,"min_step_size",False))
- self.properties.accuracy=float(RD_globals.get_xml_data(self._simbody_element,"accuracy",False))
- self.properties.maximum_transient_velocity=float(RD_globals.get_xml_data(self._simbody_element,"max_transient_velocity",False))
+ self.properties.min_step_size=float(common.get_xml_data(self._simbody_element,"min_step_size",False))
+ self.properties.accuracy=float(common.get_xml_data(self._simbody_element,"accuracy",False))
+ self.properties.maximum_transient_velocity=float(common.get_xml_data(self._simbody_element,"max_transient_velocity",False))
#contact
- self.contact.stiffness=float(RD_globals.get_xml_data(self._simbody_element,"stiffness",False))
- self.contact.plastic_coef_restitution=float(RD_globals.get_xml_data(self._simbody_element,"plastic_coef_restitution",False))
- self.contact.plastic_impact_velocity=float(RD_globals.get_xml_data(self._simbody_element,"plastic_impact_velocity",False))
- self.contact.override_impact_capture_velocity=float(RD_globals.get_xml_data(self._simbody_element,"override_impact_capture_velocity",False))
- self.contact.dissipation=float(RD_globals.get_xml_data(self._simbody_element,"dissipation",False))
- self.contact.static_friction=float(RD_globals.get_xml_data(self._simbody_element,"static_friction",False))
- self.contact.dynamic_friction=float(RD_globals.get_xml_data(self._simbody_element,"dynamic_friction",False))
- self.contact.viscous_friction=float(RD_globals.get_xml_data(self._simbody_element,"viscous_friction",False))
- self.contact.override_stiction_transition_velocity=float(RD_globals.get_xml_data(self._simbody_element,"override_stiction_transition_velocity",False))
+ self.contact.stiffness=float(common.get_xml_data(self._simbody_element,"stiffness",False))
+ self.contact.plastic_coef_restitution=float(common.get_xml_data(self._simbody_element,"plastic_coef_restitution",False))
+ self.contact.plastic_impact_velocity=float(common.get_xml_data(self._simbody_element,"plastic_impact_velocity",False))
+ self.contact.override_impact_capture_velocity=float(common.get_xml_data(self._simbody_element,"override_impact_capture_velocity",False))
+ self.contact.dissipation=float(common.get_xml_data(self._simbody_element,"dissipation",False))
+ self.contact.static_friction=float(common.get_xml_data(self._simbody_element,"static_friction",False))
+ self.contact.dynamic_friction=float(common.get_xml_data(self._simbody_element,"dynamic_friction",False))
+ self.contact.viscous_friction=float(common.get_xml_data(self._simbody_element,"viscous_friction",False))
+ self.contact.override_stiction_transition_velocity=float(common.get_xml_data(self._simbody_element,"override_stiction_transition_velocity",False))
@property
def element(self):
@@ -657,14 +657,14 @@ def configUI(self):
self.ui.dart_collison_detector.currentTextChanged.connect(self.on_collision)
#callbacks
def on_type(self):
- RD_globals.set_xml_data(self._dart_element,"solver_type",False,self.properties.solver_type)
+ common.set_xml_data(self._dart_element,"solver_type",False,self.properties.solver_type)
def on_collision(self):
- RD_globals.set_xml_data(self._dart_element,"collision_detector",False,self.properties.collision_detector)
+ common.set_xml_data(self._dart_element,"collision_detector",False,self.properties.collision_detector)
def update_ui(self):
- self.properties.solver_type=RD_globals.get_xml_data(self._dart_element,"solver_type",False)
- self.properties.collision_detector=RD_globals.get_xml_data(self._dart_element,"collision_detector",False)
+ self.properties.solver_type=common.get_xml_data(self._dart_element,"solver_type",False)
+ self.properties.collision_detector=common.get_xml_data(self._dart_element,"collision_detector",False)
@property
def element(self):
return self._dart_element
@@ -781,22 +781,22 @@ def on_reset(self):
print("physics resets applied \n")
def on_step_sz(self):
- RD_globals.set_xml_data(self._physics_elem,"max_step_size",False,self.properties.max_step_size)
+ common.set_xml_data(self._physics_elem,"max_step_size",False,self.properties.max_step_size)
def on_real_time_fct(self):
- RD_globals.set_xml_data(self._physics_elem,"real_time_factor",False,self.properties.real_time_factor)
+ common.set_xml_data(self._physics_elem,"real_time_factor",False,self.properties.real_time_factor)
def on_update_rt(self):
- RD_globals.set_xml_data(self._physics_elem,"real_time_update_rate",False,self.properties.real_time_update_rate)
+ common.set_xml_data(self._physics_elem,"real_time_update_rate",False,self.properties.real_time_update_rate)
def on_max_cnt(self):
- RD_globals.set_xml_data(self._physics_elem,"max_contacts",False,self.properties.max_contacts)
+ common.set_xml_data(self._physics_elem,"max_contacts",False,self.properties.max_contacts)
#ode radio button
def on_ode_radio_button(self):
self._physics_elem.remove(self._physics_elem.iter(self.current_type_tag).__next__())
self.current_type_tag="ode"
- RD_globals.set_xml_data(self._physics_elem,self.tag,True,{"type":self.current_type_tag})
+ common.set_xml_data(self._physics_elem,self.tag,True,{"type":self.current_type_tag})
self._physics_elem.append(self._ode.element)
#ode is at index 0
self.ui.physics_type_stack.setCurrentIndex(0)
@@ -805,7 +805,7 @@ def on_ode_radio_button(self):
def on_bullet_radio_button(self):
self._physics_elem.remove(self._physics_elem.iter(self.current_type_tag).__next__())
self.current_type_tag="bullet"
- RD_globals.set_xml_data(self._physics_elem,self.tag,True,{"type":self.current_type_tag})
+ common.set_xml_data(self._physics_elem,self.tag,True,{"type":self.current_type_tag})
self._physics_elem.append(self._bullet.element)
#bullet is at index 1
self.ui.physics_type_stack.setCurrentIndex(1)
@@ -815,7 +815,7 @@ def on_simbody_radio_button(self):
#remove current element
self._physics_elem.remove(self._physics_elem.iter(self.current_type_tag).__next__())
self.current_type_tag="simbody"
- RD_globals.set_xml_data(self._physics_elem,self.tag,True,{"type":self.current_type_tag})
+ common.set_xml_data(self._physics_elem,self.tag,True,{"type":self.current_type_tag})
self._physics_elem.append(self._simbody.element)
#simbody is at index 2
self.ui.physics_type_stack.setCurrentIndex(2)
@@ -825,17 +825,17 @@ def on_dart_radio_button(self):
#remove current element
self._physics_elem.remove(self._physics_elem.iter(self.current_type_tag).__next__())
self.current_type_tag="dart"
- RD_globals.set_xml_data(self._physics_elem,self.tag,True,{"type":self.current_type_tag})
+ common.set_xml_data(self._physics_elem,self.tag,True,{"type":self.current_type_tag})
self._physics_elem.append(self._dart.element)
#dart is at index 3
self.ui.physics_type_stack.setCurrentIndex(3)
def update_ui(self):
- self.properties.max_contacts=int(RD_globals.get_xml_data(self._physics_elem,"max_contacts",False))
- self.properties.real_time_update_rate=float(RD_globals.get_xml_data(self._physics_elem,"real_time_update_rate",False))
- self.properties.real_time_factor=float(RD_globals.get_xml_data(self._physics_elem,"real_time_factor",False))
- self.properties.max_step_size=float(RD_globals.get_xml_data(self._physics_elem,"max_step_size"))
+ self.properties.max_contacts=int(common.get_xml_data(self._physics_elem,"max_contacts",False))
+ self.properties.real_time_update_rate=float(common.get_xml_data(self._physics_elem,"real_time_update_rate",False))
+ self.properties.real_time_factor=float(common.get_xml_data(self._physics_elem,"real_time_factor",False))
+ self.properties.max_step_size=float(common.get_xml_data(self._physics_elem,"max_step_size"))
def reset(self,default:bool=True):
@@ -853,7 +853,7 @@ def reset(self,default:bool=True):
else:
doc=FreeCAD.ActiveDocument
_root_dict=doc.Robot_Description.Proxy.element_dict
- el_dict=RD_globals.parse_dict(_root_dict,self.parent_path+[self.tag])
+ el_dict=common.parse_dict(_root_dict,self.parent_path+[self.tag])
if el_dict is not None:
el_str=el_dict['elem_str']
diff --git a/robot_descriptor/sdf_elements/road.py b/robot_descriptor/sdf_elements/road.py
index 26055e8..19f1259 100644
--- a/robot_descriptor/sdf_elements/road.py
+++ b/robot_descriptor/sdf_elements/road.py
@@ -1,398 +1,109 @@
-from ..import RD_globals
-from ..RD_parser import initialize_element_tree
-import copy
-from PySide import QtGui,QtCore
-import re
+from .. import common
+from ..RD_utils import initialize_element_tree
+import copy
+from PySide import QtGui, QtCore
+import re
import math
import csv
+
# import Spreadsheet
import os
-import xml.etree.ElementTree as ET
-import FreeCAD
-#========================================
-#road properties
-#========================================
+import xml.etree.ElementTree as ET
+import FreeCAD, FreeCADGui
+
+
+# ========================================
+# road properties
+# ========================================
class road_properties:
- def __init__(self,ui) -> None:
- self.ui=ui
-#name property
+ def __init__(self, ui) -> None:
+ self.ui = ui
+
+ # name property
@property
def name(self):
return self.ui.road_name.text()
+
@name.setter
- def name(self,text):
+ def name(self, text):
self.ui.road_name.setText(text)
-#width
+ # width
@property
def width(self):
return self.ui.road_width_sp.value()
+
@width.setter
- def width(self,value):
+ def width(self, value):
self.ui.road_width_sp.setValue(value)
-
-#==================================================
-# road material
-#==================================================
-class material_properties:
- def __init__(self,ui) -> None:
- self.ui=ui
-#script uri
- @property
- def script_uri(self):
- return self.ui.material_script_uri_input.text()
- @script_uri.setter
- def script_uri(self,text):
- self.ui.material_script_uri_input.setText(text)
-
-#script name
- @property
- def script_name(self):
- return self.ui.material_script_name.text()
- @script_name.setter
- def script_name(self,text):
- self.ui.material_script_name.setText(text)
-
-#shader_type
- @property
- def shader_type(self):
- return self.ui.shader_type.currentText()
- @shader_type.setter
- def shader_type(self,text):
- self.ui.shader_type.setCurrentText(text)
-#normal map
- @property
- def normal_map(self):
- return self.ui.material_normal_map_input.text()
- @normal_map.setter
- def normal_map(self,text):
- self.ui.material_normal_map_input.setText(text)
-
-#this checkebox is not part of the sdf data its just used to enable and disable the normal_map input
-# so no need to convert bool to strinf
- @property
- def normal_map_checkbox(self):
- return self.ui.normal_map_checkBox.isChecked()
-
- @normal_map_checkbox.setter
- def normal_map_checkbox(self,state):
- if state is True:
- self.ui.normal_map_checkBox.setState(QtCore.Qt.Checked)
- else:
- self.ui.normal_map_checkBox.setState(QtCore.Qt.Unchecked)
-
-#render order
- @property
- def render_order(self):
- return self.ui.material_render_order_sp.value()
- @render_order.setter
- def render_order(self,value):
- self.ui.material_render_order_sp.setValue(value)
-#shininess
- @property
- def shininess(self):
- return self.ui.materroad_pointsial_shininess_sp.value()
- @shininess.setter
- def shininess(self,value):
- self.ui.material_shininess_sp.setValue(value)
-
-#lighting
- @property
- def lighting(self):
- state= self.ui.material_lighting_checkbox.isChecked()
- if state is True:
- return str('true')
- else:
- return str('false')
- @lighting.setter
- def lighting(self,state):
- if state is True:
- self.ui.material_lighting_checkbox.setState(QtCore.Qt.Checked)
- else:
- self.ui.material_lighting_checkbox.setState(QtCore.Qt.Unchecked)
-
-
-#ambient
- @property
- def ambient(self):
- return [self.ui.material_ambient_R_sp.value(),self.ui.material_ambient_G_sp.value(),
- self.ui.material_ambient_B_sp.value(),self.ui.material_ambient_A_sp.value()]
- @ambient.setter
- def ambient(self,vals):
- self.ui.material_ambient_R_sp.setValue(vals[0])
- self.ui.material_ambient_G_sp.setValue(vals[1])
- self.ui.material_ambient_B_sp.setValue(vals[2])
- self.ui.material_ambient_A_sp.setValue(vals[3])
-#diffuse
- @property
- def diffuse(self):
- return [self.ui.material_diffuse_R_sp.value(),self.ui.material_diffuse_G_sp.value(),
- self.ui.material_diffuse_B_sp.value(),self.ui.material_diffuse_A_sp.value()]
- @diffuse.setter
- def diffuse(self,vals):
- self.ui.material_diffuse_R_sp.setValue(vals[0])
- self.ui.material_diffuse_G_sp.setValue(vals[1])
- self.ui.material_diffuse_B_sp.setValue(vals[2])
- self.ui.material_diffuse_A_sp.setValue(vals[3])
-#specular
- @property
- def specular(self):
- return [self.ui.material_specular_R_sp.value(),self.ui.material_specular_G_sp.value(),
- self.ui.material_specular_B_sp.value(),self.ui.material_specular_A_sp.value()]
- @specular.setter
- def specular(self,vals):
- self.ui.material_specular_R_sp.setValue(vals[0])
- self.ui.material_specular_G_sp.setValue(vals[1])
- self.ui.material_specular_B_sp.setValue(vals[2])
- self.ui.material_specular_A_sp.setValue(vals[3])
-#emissive
- @property
- def emissive(self):
- return [self.ui.material_emissive_R_sp.value(),self.ui.material_emissive_G_sp.value(),
- self.ui.material_emissive_B_sp.value(),self.ui.material_emissive_A_sp.value()]
- @emissive.setter
- def emissive(self,vals):
- self.ui.material_emissive_R_sp.setValue(vals[0])
- self.ui.material_emissive_G_sp.setValue(vals[1])
- self.ui.material_emissive_B_sp.setValue(vals[2])
- self.ui.material_emissive_A_sp.setValue(vals[3])
+# =================================================
+# =================================================
+# road
+# ==================================================
+# =================================================
+from . import material
-#===========================================
-#===========================================
-#material element
-#============================================
-#============================================
-class material(RD_globals.color_pickr):
- def __init__(self,ui) -> None:
- super().__init__()
- self.ui=ui
- #use the road tag since material will be implemented as part of the road element
- self.tag='road'
- self.parent_path=['sdf','world']
- self.file_name='material.sdf'
- self._material_element=initialize_element_tree.convdict_2_tree(self.file_name).get_element
- self.properties=material_properties(self.ui)
- #remove unused material elements
- self._material_element.remove(self._material_element.find('.//pbr'))
- self._material_element.remove(self._material_element.find('.//double_sided'))
- self.configUI()
- self.reset(default=False)
-
- def configUI(self):
- self.ui.material_script_uri_input.textEdited.connect(self.on_uri)
- self.ui.material_script_name.textEdited.connect(self.on_uri_name)
- self.ui.shader_type.currentTextChanged.connect(self.on_shader_type)
- self.ui.normal_map_checkBox.stateChanged.connect(self.on_normal_map_state)
- self.ui.material_normal_map_input.textEdited.connect(self.on_normal_map)
- self.ui.material_render_order_sp.valueChanged.connect(self.on_material_render_ord)
- self.ui.material_shininess_sp.valueChanged.connect(self.on_shininess)
-
- #ambient
- self.ui.material_ambient_R_sp.valueChanged.connect(self.on_ambient)
- self.ui.material_ambient_G_sp.valueChanged.connect(self.on_ambient)
- self.ui.material_ambient_B_sp.valueChanged.connect(self.on_ambient)
- self.ui.material_ambient_A_sp.valueChanged.connect(self.on_ambient)
- #diffuse
- self.ui.material_diffuse_R_sp.valueChanged.connect(self.on_diffuse)
- self.ui.material_diffuse_G_sp.valueChanged.connect(self.on_diffuse)
- self.ui.material_diffuse_B_sp.valueChanged.connect(self.on_diffuse)
- self.ui.material_diffuse_A_sp.valueChanged.connect(self.on_diffuse)
- #specular
- self.ui.material_specular_R_sp.valueChanged.connect(self.on_specular)
- self.ui.material_specular_G_sp.valueChanged.connect(self.on_specular)
- self.ui.material_specular_B_sp.valueChanged.connect(self.on_specular)
- self.ui.material_specular_A_sp.valueChanged.connect(self.on_specular)
- #emissive
- self.ui.material_emissive_R_sp.valueChanged.connect(self.on_emissive)
- self.ui.material_emissive_G_sp.valueChanged.connect(self.on_emissive)
- self.ui.material_emissive_B_sp.valueChanged.connect(self.on_emissive)
- self.ui.material_emissive_A_sp.valueChanged.connect(self.on_emissive)
-
- #color picker buttons
- self.ui.material_ambient_color_pkr.clicked.connect(self.on_ambient_color_pkr)
- self.ui.material_diffuse_color_pkr.clicked.connect(self.on_diffuse_color_pkr)
- self.ui.material_specular_color_pkr.clicked.connect(self.on_specular_color_pkr)
- self.ui.material_emissive_color_pkr.clicked.connect(self.on_emissive_color_pkr)
-
-
- def on_uri(self):
- RD_globals.set_xml_data(self._material_element,'uri',False,self.properties.script_uri)
-
- def on_uri_name(self):
- RD_globals.set_xml_data(self._material_element,'name',False,self.properties.script_name)
-
- def on_shader_type(self):
- RD_globals.set_xml_data(self._material_element,'shader',True,{'type':self.properties.shader_type})
-
-#enable and disable normal map
- def on_normal_map_state(self):
- if self.properties.normal_map_checkbox:
- self.ui.material_normal_map_input.setEnabled(True)
- else:
- self.ui.material_normal_map_input.setEnabled(False)
-
-#normal map
- def on_normal_map(self):
- RD_globals.set_xml_data(self._material_element,'normal_map',False,self.properties.normal_map)
-
-#material render order
- def on_material_render_ord(self):
- RD_globals.set_xml_data(self._material_element,'render_order',False,self.properties.render_order)
-
- def on_shininess(self):
- RD_globals.set_xml_data(self._material_element,'shininess',False,self.properties.shininess)
-
- def on_ambient(self):
- RD_globals.set_xml_data(self._material_element,'ambient',False,self.properties.ambient)
- self.set_widget_color('ambient',self.ui.material_ambient_color_pkr)
-
- def on_diffuse(self):
- RD_globals.set_xml_data(self._material_element,'diffuse',False,self.properties.diffuse)
- self.set_widget_color('diffuse',self.ui.material_diffuse_color_pkr)
-
- def on_specular(self):
- RD_globals.set_xml_data(self._material_element,'specular',False,self.properties.specular)
- self.set_widget_color('specular',self.ui.material_specular_color_pkr)
+class road_material(material.material):
+ def __init__(self, ui):
+ self.ui = ui
- def on_emissive(self):
- RD_globals.set_xml_data(self._material_element,'emissive',False,self.properties.emissive)
- self.set_widget_color('emissive',self.ui.material_emissive_color_pkr)
-
- def on_ambient_color_pkr(self):
- self.color_picker('ambient',self.ui.material_ambient_color_pkr)
-
- def on_diffuse_color_pkr(self):
- self.color_picker('diffuse',self.ui.material_diffuse_color_pkr)
-
- def on_specular_color_pkr(self):
- self.color_picker('specular',self.ui.material_specular_color_pkr)
-
- def on_emissive_color_pkr(self):
- self.color_picker('emissive',self.ui.material_emissive_color_pkr)
-
- def updateUi(self):
- self.properties.script_uri=RD_globals.get_xml_data(self._material_element,'uri',False)
- self.properties.script_name=RD_globals.get_xml_data(self._material_element,'name',False)
- self.properties.shader_type=RD_globals.get_xml_data(self._material_element,'type')
- self.properties.normal_map=RD_globals.get_xml_data(self._material_element,'normal_map',False)
- self.properties.render_order=RD_globals.get_xml_data(self._material_element,'render_order',False)
- self.properties.shininess=RD_globals.get_xml_data(self._material_element,'shininess',False)
- self.properties.ambient=RD_globals.get_xml_data(self._material_element,'ambient',False)
- self.properties.diffuse=RD_globals.get_xml_data(self._material_element,'diffuse',False)
- self.properties.specular=RD_globals.get_xml_data(self._material_element,'specular',False)
- self.properties.emissive=RD_globals.get_xml_data(self._material_element,'emissive',False)
- #style sheets
- self.set_widget_color('ambient',self.ui.material_ambient_color_pkr)
- self.set_widget_color('diffuse',self.ui.material_diffuse_color_pkr)
- self.set_widget_color('specular',self.ui.material_specular_color_pkr)
- self.set_widget_color('emissive',self.ui.material_emissive_color_pkr)
-
- def reset(self,default=True):
+ super().__init__(self.ui)
+ #redefine parent path
+ self.parent_path = ["sdf", "world", "road"]
+ self.reset(default=False)
+
+ def reset(self, default=True):
if default:
- self._material_element=initialize_element_tree.convdict_2_tree(self.file_name).get_element
- #remove unused elements
- self._material_element.remove(self._material_element.find('.//pbr'))
- self._material_element.remove(self._material_element.find('.//double_sided'))
+ self._material_element = initialize_element_tree.convdict_2_tree(
+ self.file_name
+ ).get_element
else:
- doc=FreeCAD.ActiveDocument
- _root_dict=doc.Robot_Description.Proxy.element_dict
- el_dict=RD_globals.parse_dict(_root_dict,self.parent_path+[self.tag])
+ doc = FreeCAD.ActiveDocument
+ _root_dict = doc.Robot_Description.Proxy.element_dict
+ # since material does not exist independently find the parent
+ el_dict = common.parse_dict(_root_dict, self.parent_path)
if el_dict is not None:
- #find the material element from road
- elem=ET.fromstring(el_dict['elem_str']).find('.//material')
- #make check since material might not always be included in the final element tree
- # since its optional
+ # find the material element in parent element
+ elem = ET.fromstring(el_dict["elem_str"]).find(".//material")
+ # make check since material might not always be included in the final element tree
+ # since its optional
if elem is not None:
- self.merge_elements(self._material_element,elem)
+ self.merge_elements(self._material_element, elem)
self.updateUi()
-
-
-#merger
-#this merge method repeats alot
- def merge_elements(self,destination_el, source_el):
- # Update attributes of destination_el with source_el
- destination_el.attrib.update(source_el.attrib)
- if source_el.text:
- destination_el.text = source_el.text
- # Merge child elements recursively
- for child in source_el:
- existing_el = destination_el.find(child.tag)
- if existing_el is not None:
- self.merge_elements(existing_el, child) # Recursively merge the existing element with the new one
- else:
- # If the element doesn't exist in destination, simply append it
- # destination_el.append(child)
- pass
-
- @property
- def element(self):
- #make deep copy to avoid altering local element
- temp_el=copy.deepcopy(self._material_element)
- #script
- if self.ui.material_script_groupBox.isChecked():
- #if script is checked remove al other color properties
- tags=['shader','ambient','diffuse','specular','emissive','shininess','render_order'
- ,'lighting']
- for elem_tag in tags:
- temp_el.remove(temp_el.find('.//'+elem_tag))
- else:
- temp_el.remove(temp_el.find('.//script'))
- #shader
- if self.ui.material_shader_groupBox.isChecked():
- #if shader is checked check if the normal map is checked and remve it if neccessary
- if self.properties.normal_map_checkbox is False:
- shader_el=temp_el.find('.//shader')
- shader_el.remove(shader_el.find('.//normal_map'))
-
- else:
- temp_el.remove(temp_el.find('.//shader'))
-
- #remove color related configs
- if self.ui.material_ambient_groupbox.isChecked() is False:
- temp_el.remove(temp_el.find('.//ambient'))
-
- if self.ui.material_diffuse_groupbox.isChecked() is False:
- temp_el.remove(temp_el.find('.//diffuse'))
-
- if self.ui.material_specular_groupbox.isChecked() is False:
- temp_el.remove(temp_el.find('.//specular'))
-
- if self.ui.material_emissive_groupbox.isChecked() is False:
- temp_el.remove(temp_el.find('.//emissive'))
-
- return temp_el
-
-
-
-#=================================================
-#=================================================
-#road
-#==================================================
-#=================================================
-class road():
- def __init__(self,ui):
- self.ui=ui
- self.parent_path=['sdf','world']
- self.tag='road'
- self.file_name='road.sdf'
- self._road_element=initialize_element_tree.convdict_2_tree(self.file_name).get_element
- self._road_properties=road_properties(self.ui)
- #material element
- self._material=material(self.ui)
- self.point_element=copy.deepcopy(self._road_element.find('.//point'))
- #disable the scroll widget
+
+
+class road:
+ def __init__(self, ui):
+ self.ui = ui
+ self.parent_path = ["sdf", "world"]
+ self.tag = "road"
+ self.file_name = "road.sdf"
+ self._road_element = initialize_element_tree.convdict_2_tree(
+ self.file_name
+ ).get_element
+ self._road_properties = road_properties(self.ui)
+ # material element
+ self.material_widget = FreeCADGui.PySideUic.loadUi(
+ os.path.join(common.UI_PATH, "material.ui")
+ )
+ self._material = road_material(self.material_widget)
+
+ # disable unused material ui elements
+ self.material_widget.material_pbr_groupbox.setEnabled(False)
+ self.material_widget.material_double_sided_checkBox.setEnabled(False)
+ self.point_element = copy.deepcopy(self._road_element.find(".//point"))
+ # disable the scroll widget
+
+ self.ui.road_scroll.setWidget(self.material_widget.widget)
self.ui.road_scroll.setEnabled(False)
-
- #remove elements that will not be edited
-
- #configure the Ui and callbacks
+ # configure the Ui and callbacks
self.configUI()
self.reset(default=False)
-
+
def configUI(self):
self.ui.road_name.textEdited.connect(self.on_road_name)
self.ui.road_width_sp.valueChanged.connect(self.on_road_width)
@@ -400,80 +111,103 @@ def configUI(self):
self.ui.enable_road_checkbox.clicked.connect(self.on_road_checkbox)
def on_road_checkbox(self):
- state=self.ui.enable_road_checkbox.isChecked()
+ state = self.ui.enable_road_checkbox.isChecked()
if state:
self.ui.road_scroll.setEnabled(True)
else:
self.ui.road_scroll.setEnabled(False)
-
+
def on_road_reset(self):
self.reset(default=True)
- print('road resets applied\n')
-
+ print("road resets applied\n")
+
def on_road_name(self):
- RD_globals.set_xml_data(self._road_element,'road',True,{'name':self._road_properties.name})
-
+ common.set_xml_data(
+ self._road_element, "road", True, {"name": self._road_properties.name}
+ )
+
def on_road_width(self):
- RD_globals.set_xml_data(self._road_element,'width',False,self._road_properties.width)
-
+ common.set_xml_data(
+ self._road_element, "width", False, self._road_properties.width
+ )
+
def get_sheet_data(self):
- #get spread sheet with points data
- sheet=FreeCAD.ActiveDocument.points
- data_cells=sheet.getNonEmptyCells()
- #ensure all point data is available since a vector 3 is required
- #all filled cells need to be a multiple of 3
- if len(data_cells)%3 !=0:
- FreeCAD.Console.PrintUserWarning("some data is missing \n points not updated\n")
+ # get spread sheet with points data
+ sheet = FreeCAD.ActiveDocument.points
+ data_cells = sheet.getNonEmptyCells()
+ # ensure all point data is available since a vector 3 is required
+ # all filled cells need to be a multiple of 3
+ if len(data_cells) % 3 != 0:
+ FreeCAD.Console.PrintUserWarning(
+ "some data is missing \n points not updated\n"
+ )
else:
- #remove all points previously available in the tree
- for point in self._road_element.iter('point'):
+ # remove all points previously available in the tree
+ for point in self._road_element.iter("point"):
self._road_element.remove(point)
- #use list comprehension to extract spreadsheet items 3 at a time
- #produces
- #start from 3 since the first 3 are the labels
- for row in [ [sheet.getContents(data_cells[i]), sheet.getContents(data_cells[i+1]), sheet.getContents(data_cells[i+2])]
- for i in range(3,len(data_cells),3)]:
- point=copy.deepcopy(self.point_element)
- point.text=' '.join(map(str,row))
+ # use list comprehension to extract spreadsheet items 3 at a time
+ # produces
+ # start from 3 since the first 3 are the labels
+ for row in [
+ [
+ sheet.getContents(data_cells[i]),
+ sheet.getContents(data_cells[i + 1]),
+ sheet.getContents(data_cells[i + 2]),
+ ]
+ for i in range(3, len(data_cells), 3)
+ ]:
+ point = copy.deepcopy(self.point_element)
+ point.text = " ".join(map(str, row))
self._road_element.append(point)
-
-
+
def updateUI(self):
- self._road_properties.name=RD_globals.get_xml_data(self._road_element,['road','name'],True)
- self._road_properties.width=RD_globals.get_xml_data(self._road_element,'width',False)
-
-
- def reset(self,default=True):
+ self._road_properties.name = common.get_xml_data(
+ self._road_element, ["road", "name"], True
+ )
+ self._road_properties.width = common.get_xml_data(
+ self._road_element, "width", False
+ )
+
+ def reset(self, default=True):
if default:
- self._road_element=initialize_element_tree.convdict_2_tree(self.file_name).get_element
+ self._road_element = initialize_element_tree.convdict_2_tree(
+ self.file_name
+ ).get_element
self._material.reset(default=True)
- self._road_properties.point=None
+ self._road_properties.point = None
else:
- doc=FreeCAD.ActiveDocument
- _root_dict=doc.Robot_Description.Proxy.element_dict
- el_dict=RD_globals.parse_dict(_root_dict,self.parent_path+[self.tag])
+ doc = FreeCAD.ActiveDocument
+ _root_dict = doc.Robot_Description.Proxy.element_dict
+ el_dict = common.parse_dict(_root_dict, self.parent_path + [self.tag])
if el_dict is not None:
- elem=ET.fromstring(el_dict['elem_str'])
- self._road_element=elem
- #remove material from the element
- mat=self._road_element.find('.//material')
- #material is an optional element hence might not be included
-
+ elem = ET.fromstring(el_dict["elem_str"])
+ self._road_element = elem
+ # remove material from the element
+ mat = self._road_element.find(".//material")
+ # material is an optional element hence might not be included
+
if mat is not None:
- self._road_element.remove(mat )
- self.updateUI()
-
+ self._road_element.remove(mat)
+ self._material.reset(default=False)
+
+ # remove unused material elements
+ self._material._material_element.remove(
+ self._material._material_element.find(".//pbr")
+ )
+ self._material._material_element.remove(
+ self._material._material_element.find(".//double_sided")
+ )
+
+ self.updateUI()
+
@property
def element(self):
- #update data in sheet before export
+ # update data in sheet before export
self.get_sheet_data()
-
-
- _elem=copy.deepcopy(self._road_element)
- #check if materialis enabled
- if self.ui.road_material_groupbox.isChecked():
- mat_el=self._material.element
+
+ _elem = copy.deepcopy(self._road_element)
+ # check if materialis enabled
+ if self.ui.include_material_info.isChecked():
+ mat_el = self._material.element
_elem.append(mat_el)
return _elem
-
-
diff --git a/robot_descriptor/sdf_elements/scene.py b/robot_descriptor/sdf_elements/scene.py
index 3a99c0f..9908030 100644
--- a/robot_descriptor/sdf_elements/scene.py
+++ b/robot_descriptor/sdf_elements/scene.py
@@ -1,8 +1,8 @@
-from .. import RD_globals
+from .. import common
import copy
import xml.etree.ElementTree as ET
import FreeCAD
-from ..RD_parser import initialize_element_tree
+from ..RD_utils import initialize_element_tree
from PySide import QtCore
from PySide.QtGui import QColorDialog
import math
@@ -217,7 +217,7 @@ def fog_density(self,value):
#==============================================
#===============================================
-class scene(RD_globals.color_pickr):
+class scene(common.color_pickr):
def __init__(self,ui):
self.ui=ui
self.parent_path=['sdf','world']
@@ -329,91 +329,91 @@ def on_scene_ambient(self):
self.set_widget_color('scene_ambient',self.ui.scene_ambient_color_pkr)
def on_background(self):
- RD_globals.set_xml_data(self._scene_element,"background",False,self.properties.background)
+ common.set_xml_data(self._scene_element,"background",False,self.properties.background)
self.set_widget_color('background',self.ui.scene_background_color_pkr)
def on_time(self):
- RD_globals.set_xml_data(self._scene_element,"time",False,self.properties.time)
+ common.set_xml_data(self._scene_element,"time",False,self.properties.time)
def on_sunrise(self):
- RD_globals.set_xml_data(self._scene_element,"sunrise",False,self.properties.sunrise)
+ common.set_xml_data(self._scene_element,"sunrise",False,self.properties.sunrise)
def on_sunset(self):
- RD_globals.set_xml_data(self._scene_element,"sunset",False,self.properties.sunset)
+ common.set_xml_data(self._scene_element,"sunset",False,self.properties.sunset)
def on_speed(self):
- RD_globals.set_xml_data(self._scene_element,"speed",False,self.properties.speed)
+ common.set_xml_data(self._scene_element,"speed",False,self.properties.speed)
def on_direction(self):
- RD_globals.set_xml_data(self._scene_element,"direction",False,self.properties.direction)
+ common.set_xml_data(self._scene_element,"direction",False,self.properties.direction)
def on_humidity(self):
- RD_globals.set_xml_data(self._scene_element,"humidity",False,self.properties.humidity)
+ common.set_xml_data(self._scene_element,"humidity",False,self.properties.humidity)
def on_cloud_ambient(self):
#write to the ambient in clouds element
- RD_globals.set_xml_data(self._scene_element.find("sky"),"ambient",False,self.properties.clouds_ambient)
+ common.set_xml_data(self._scene_element.find("sky"),"ambient",False,self.properties.clouds_ambient)
self.set_widget_color('clouds_ambient',self.ui.cloud_ambient_color_pkr)
def on_mean_size(self):
- RD_globals.set_xml_data(self._scene_element,"mean_size",False,self.properties.mean_size)
+ common.set_xml_data(self._scene_element,"mean_size",False,self.properties.mean_size)
def on_cube_map(self):
- RD_globals.set_xml_data(self._scene_element,"cubemap_uri",False,self.properties.cubemap_uri)
+ common.set_xml_data(self._scene_element,"cubemap_uri",False,self.properties.cubemap_uri)
def on_shadow(self):
- RD_globals.set_xml_data(self._scene_element,"shadows",False,self.properties.shadows)
+ common.set_xml_data(self._scene_element,"shadows",False,self.properties.shadows)
def on_grid(self):
- RD_globals.set_xml_data(self._scene_element,"grid",False,self.properties.grid)
+ common.set_xml_data(self._scene_element,"grid",False,self.properties.grid)
def on_origin_visual(self):
- RD_globals.set_xml_data(self._scene_element,"origin_visual",False,self.properties.origin_visual)
+ common.set_xml_data(self._scene_element,"origin_visual",False,self.properties.origin_visual)
def on_fog_color(self):
- RD_globals.set_xml_data(self._scene_element,"color",False,self.properties.fog_color)
+ common.set_xml_data(self._scene_element,"color",False,self.properties.fog_color)
self.set_widget_color('fog_color',self.ui.fog_color_picker_btn)
def on_fog_type(self):
- RD_globals.set_xml_data(self._scene_element,"type",False,self.properties.fog_type)
+ common.set_xml_data(self._scene_element,"type",False,self.properties.fog_type)
def on_fog_start(self):
- RD_globals.set_xml_data(self._scene_element,"start",False,self.properties.fog_start)
+ common.set_xml_data(self._scene_element,"start",False,self.properties.fog_start)
def on_fog_end(self):
- RD_globals.set_xml_data(self._scene_element,"end",False,self.properties.fog_end)
+ common.set_xml_data(self._scene_element,"end",False,self.properties.fog_end)
def on_fog_density(self):
- RD_globals.set_xml_data(self._scene_element,"density",False,self.properties.fog_density)
+ common.set_xml_data(self._scene_element,"density",False,self.properties.fog_density)
#callbacks
#end
def update_ui(self):
- self.properties.scene_ambient=RD_globals.extract_vector_n(self._scene_element.find("ambient").text)
+ self.properties.scene_ambient=common.extract_vector_n(self._scene_element.find("ambient").text)
- self.properties.background=RD_globals.get_xml_data(self._scene_element,"background",False)
+ self.properties.background=common.get_xml_data(self._scene_element,"background",False)
- self.properties.time=float(RD_globals.get_xml_data(self._scene_element,"time",False))
- self.properties.sunrise=float(RD_globals.get_xml_data(self._scene_element,"sunrise",False))
- self.properties.sunset=float(RD_globals.get_xml_data(self._scene_element,"sunset",False))
- self.properties.speed=float(RD_globals.get_xml_data(self._scene_element,"speed",False))
- self.properties.direction=float(RD_globals.get_xml_data(self._scene_element,"direction",False))
- self.properties.humidity=float(RD_globals.get_xml_data(self._scene_element,"humidity",False))
-
- self.properties.clouds_ambient=RD_globals.get_xml_data(self._scene_element.find("sky"),"ambient",False)
- self.properties.mean_size=RD_globals.get_xml_data(self._scene_element,"mean_size",False)
+ self.properties.time=float(common.get_xml_data(self._scene_element,"time",False))
+ self.properties.sunrise=float(common.get_xml_data(self._scene_element,"sunrise",False))
+ self.properties.sunset=float(common.get_xml_data(self._scene_element,"sunset",False))
+ self.properties.speed=float(common.get_xml_data(self._scene_element,"speed",False))
+ self.properties.direction=float(common.get_xml_data(self._scene_element,"direction",False))
+ self.properties.humidity=float(common.get_xml_data(self._scene_element,"humidity",False))
+
+ self.properties.clouds_ambient=common.get_xml_data(self._scene_element.find("sky"),"ambient",False)
+ self.properties.mean_size=common.get_xml_data(self._scene_element,"mean_size",False)
- self.properties.cubemap_uri=RD_globals.get_xml_data(self._scene_element,"cubemap_uri",False)
- self.properties.shadows=RD_globals.get_xml_data(self._scene_element,"shadows",False)
- self.properties.grid=RD_globals.get_xml_data(self._scene_element,"grid",False)
- self.properties.origin_visual=RD_globals.get_xml_data(self._scene_element,"origin_visual",False)
- self.properties.fog_color=RD_globals.get_xml_data(self._scene_element,"color",False)
- self.properties.fog_type=RD_globals.get_xml_data(self._scene_element,"type",False)
- self.properties.fog_start=RD_globals.get_xml_data(self._scene_element,"start",False)
- self.properties.fog_end=RD_globals.get_xml_data(self._scene_element,"end",False)
- self.properties.fog_density=RD_globals.get_xml_data(self._scene_element,"density",False)
+ self.properties.cubemap_uri=common.get_xml_data(self._scene_element,"cubemap_uri",False)
+ self.properties.shadows=common.get_xml_data(self._scene_element,"shadows",False)
+ self.properties.grid=common.get_xml_data(self._scene_element,"grid",False)
+ self.properties.origin_visual=common.get_xml_data(self._scene_element,"origin_visual",False)
+ self.properties.fog_color=common.get_xml_data(self._scene_element,"color",False)
+ self.properties.fog_type=common.get_xml_data(self._scene_element,"type",False)
+ self.properties.fog_start=common.get_xml_data(self._scene_element,"start",False)
+ self.properties.fog_end=common.get_xml_data(self._scene_element,"end",False)
+ self.properties.fog_density=common.get_xml_data(self._scene_element,"density",False)
#update color of the color picker buttons
color_list=[['fog_color',self.ui.fog_color_picker_btn],['clouds_ambient',self.ui.cloud_ambient_color_pkr],
@@ -432,26 +432,14 @@ def reset(self,default:bool=True):
doc=FreeCAD.ActiveDocument
_root_dict=doc.Robot_Description.Proxy.element_dict
- el_dict=RD_globals.parse_dict(_root_dict,self.parent_path+[self.tag])
+ el_dict=common.parse_dict(_root_dict,self.parent_path+[self.tag])
if el_dict is not None:
el_str=el_dict["elem_str"]
self.merge_elements(self._scene_element,ET.fromstring(el_str))
self.update_ui()
def merge_elements(self,destination_el, source_el):
- # Update attributes of destination_el with source_el
- destination_el.attrib.update(source_el.attrib)
- if source_el.text:
- destination_el.text = source_el.text
- # Merge child elements recursively
- for child in source_el:
- existing_el = destination_el.find(child.tag)
- if existing_el is not None:
- self.merge_elements(existing_el, child) # Recursively merge the existing element with the new one
- else:
- # If the element doesn't exist in destination, simply append it
- # destination_el.append(child)
- pass
+ common.merge_elements(destination_el,source_el)
@property
def element(self):
diff --git a/robot_descriptor/sdf_elements/spherical_coordinates.py b/robot_descriptor/sdf_elements/spherical_coordinates.py
index ae3bec4..d93f166 100644
--- a/robot_descriptor/sdf_elements/spherical_coordinates.py
+++ b/robot_descriptor/sdf_elements/spherical_coordinates.py
@@ -1,6 +1,6 @@
-from .. import RD_globals
+from .. import common
import xml.etree.ElementTree as ET
-from ..RD_parser import initialize_element_tree
+from ..RD_utils import initialize_element_tree
import copy
import FreeCAD
@@ -134,40 +134,40 @@ def on_reset(self):
print("spherical resets applied \n")
def on_surface_model(self):
- RD_globals.set_xml_data(self._spherical_coord_elem,"surface_model",False,self.properties.surface_model)
+ common.set_xml_data(self._spherical_coord_elem,"surface_model",False,self.properties.surface_model)
def on_world_frame(self):
- RD_globals.set_xml_data(self._spherical_coord_elem,"world_frame_orientation",False,self.properties.world_frame_orientation)
+ common.set_xml_data(self._spherical_coord_elem,"world_frame_orientation",False,self.properties.world_frame_orientation)
def on_latitude_deg(self):
- RD_globals.set_xml_data(self._spherical_coord_elem,"latitude_deg",False,self.properties.latitude_deg)
+ common.set_xml_data(self._spherical_coord_elem,"latitude_deg",False,self.properties.latitude_deg)
def on_longitude(self):
- RD_globals.set_xml_data(self._spherical_coord_elem,"longitude_deg",False,self.properties.longitude_deg)
+ common.set_xml_data(self._spherical_coord_elem,"longitude_deg",False,self.properties.longitude_deg)
def on_elevation(self):
- RD_globals.set_xml_data(self._spherical_coord_elem,"elevation",False,self.properties.elevation)
+ common.set_xml_data(self._spherical_coord_elem,"elevation",False,self.properties.elevation)
def on_s_a_eq(self):
- RD_globals.set_xml_data(self._spherical_coord_elem,"surface_axis_equatorial",False,self.properties.surface_axis_equatorial)
+ common.set_xml_data(self._spherical_coord_elem,"surface_axis_equatorial",False,self.properties.surface_axis_equatorial)
def on_s_a_p(self):
- RD_globals.set_xml_data(self._spherical_coord_elem,"surface_axis_polar",False,self.properties.surface_axis_polar)
+ common.set_xml_data(self._spherical_coord_elem,"surface_axis_polar",False,self.properties.surface_axis_polar)
def on_heading(self):
- RD_globals.set_xml_data(self._spherical_coord_elem,"heading_deg",False,self.properties.heading_deg)
+ common.set_xml_data(self._spherical_coord_elem,"heading_deg",False,self.properties.heading_deg)
#end callbacks
def update_ui(self):
- self.properties.surface_model=RD_globals.get_xml_data(self._spherical_coord_elem,"surface_model",False)
- self.properties.world_frame_orientation=RD_globals.get_xml_data(self._spherical_coord_elem,"world_frame_orientation",False)
- self.properties.latitude_deg=float(RD_globals.get_xml_data(self._spherical_coord_elem,"latitude_deg",False))
- self.properties.longitude_deg=float(RD_globals.get_xml_data(self._spherical_coord_elem,"longitude_deg",False))
- self.properties.elevation=float(RD_globals.get_xml_data(self._spherical_coord_elem,"elevation",False))
- self.properties.surface_axis_equatorial=float(RD_globals.get_xml_data(self._spherical_coord_elem,"surface_axis_equatorial",False))
- self.properties.surface_axis_polar=float(RD_globals.get_xml_data(self._spherical_coord_elem,"surface_axis_polar",False))
- self.properties.heading_deg=float(RD_globals.get_xml_data(self._spherical_coord_elem,"heading_deg",False))
+ self.properties.surface_model=common.get_xml_data(self._spherical_coord_elem,"surface_model",False)
+ self.properties.world_frame_orientation=common.get_xml_data(self._spherical_coord_elem,"world_frame_orientation",False)
+ self.properties.latitude_deg=float(common.get_xml_data(self._spherical_coord_elem,"latitude_deg",False))
+ self.properties.longitude_deg=float(common.get_xml_data(self._spherical_coord_elem,"longitude_deg",False))
+ self.properties.elevation=float(common.get_xml_data(self._spherical_coord_elem,"elevation",False))
+ self.properties.surface_axis_equatorial=float(common.get_xml_data(self._spherical_coord_elem,"surface_axis_equatorial",False))
+ self.properties.surface_axis_polar=float(common.get_xml_data(self._spherical_coord_elem,"surface_axis_polar",False))
+ self.properties.heading_deg=float(common.get_xml_data(self._spherical_coord_elem,"heading_deg",False))
def reset(self,default:bool=True):
@@ -176,7 +176,7 @@ def reset(self,default:bool=True):
else:
doc=FreeCAD.ActiveDocument
_root_dict=doc.Robot_Description.Proxy.element_dict
- el_dict=RD_globals.parse_dict(_root_dict,self.parent_path+[self.tag_name])
+ el_dict=common.parse_dict(_root_dict,self.parent_path+[self.tag_name])
if el_dict is not None:
el_str=el_dict['elem_str']
self.merge(el_str)
@@ -186,7 +186,7 @@ def reset(self,default:bool=True):
self.update_ui()
def merge(self, el_str):
- RD_globals.merge_elements(self._spherical_coord_elem,ET.fromstring(el_str))
+ common.merge_elements(self._spherical_coord_elem,ET.fromstring(el_str))
@property
diff --git a/robot_descriptor/sdf_elements/surface.py b/robot_descriptor/sdf_elements/surface.py
new file mode 100644
index 0000000..97a4162
--- /dev/null
+++ b/robot_descriptor/sdf_elements/surface.py
@@ -0,0 +1,799 @@
+from ..RD_utils import initialize_element_tree
+from .. import common
+from PySide2 import QtGui,QtCore
+import copy
+import xml.etree.ElementTree as ET
+
+class surface_properties:
+ def __init__(self,ui):
+ self.ui=ui
+
+#restitution_coefficient
+ @property
+ def restitution_coefficient(self):
+ return self.ui.collision_restitution_coefficient_sp.value()
+ @restitution_coefficient.setter
+ def restitution_coefficient(self,value):
+ self.ui.collision_restitution_coefficient_sp.setValue(value)
+
+#threshold
+ @property
+ def threshold(self):
+ return self.ui.collision_bounce_threshold_sp.value()
+ @threshold.setter
+ def threshold(self,value):
+ self.ui.collision_bounce_threshold_sp.setValue(value)
+
+#friction
+ #torsional
+ #coefficient
+ @property
+ def coefficient(self):
+ return self.ui.torsional_coeff_sp.value()
+ @coefficient.setter
+ def coefficient(self,value):
+ self.ui.torsional_coeff_sp.setValue(value)
+
+ #use_patch_radius
+ @property
+ def use_patch_radius(self):
+ return str('true') if self.ui.use_patch_radius_cb.isChecked() else str('false')
+ @use_patch_radius.setter
+ def use_patch_radius(self,state):
+ self.ui.use_patch_radius_cb.setCheckState(QtCore.Qt.Checked) if state=='true' else self.ui.use_patch_radius_cb.seCheckState(QtCore.Qt.Unchecked)
+
+ #patch_radius
+ @property
+ def patch_radius(self):
+ return self.ui.torsional_patch_radius_sp.value()
+ @patch_radius.setter
+ def patch_radius(self,value):
+ self.ui.torsional_patch_radius_sp.setValue(value)
+
+ #surface_radius
+ @property
+ def surface_radius(self):
+ return self.ui.torsional_surface_radius_sp.value()
+ @surface_radius.setter
+ def surface_radius(self,value):
+ self.ui.torsional_surface_radius_sp.setValue(value)
+
+ #slip
+ @property
+ def torsional_slip(self):
+ self.ui.torsional_ode_slip_sp.value()
+
+ @torsional_slip.setter
+ def torsional_slip(self,value):
+ self.ui.torsional_ode_slip_sp.setValue(value)
+
+#ode
+ #mu
+ @property
+ def friction_ode_mu(self):
+ return self.ui.surface_ode_mu_sp.value()
+ @friction_ode_mu.setter
+ def friction_ode_mu(self,value):
+ self.ui.surface_ode_mu_sp.setValue(value)
+
+ #mu2
+ @property
+ def friction_ode_mu2(self):
+ return self.ui.surface_ode_mu2_sp.value()
+ @friction_ode_mu2.setter
+ def friction_ode_mu2(self,value):
+ self.ui.surface_ode_mu2_sp.setValue(value)
+
+ #fdir1
+ @property
+ def friction_ode_fdir1(self):
+ return [self.ui.surface_ode_fdir1_x_sp.value(),self.ui.surface_ode_fdir1_y_sp.value(),self.ui.surface_ode_fdir1_z_sp.value()]
+
+ @friction_ode_fdir1.setter
+ def friction_ode_fdir1(self,vals):
+ self.ui.surface_ode_fdir1_x_sp.setValue(vals[0])
+ self.ui.surface_ode_fdir1_y_sp.setValue(vals[1])
+ self.ui.surface_ode_fdir1_z_sp.setValue(vals[2])
+
+ #slip1
+ @property
+ def friction_ode_slip1(self):
+ return self.ui.surface_ode_slip1_sp.value()
+ @friction_ode_slip1.setter
+ def friction_ode_slip1(self,value):
+ self.ui.surface_ode_slip1_sp.setValue(value)
+
+ #slip2
+ @property
+ def friction_ode_slip2(self):
+ return self.ui.surface_ode_slip2_sp.value()
+ @friction_ode_slip2.setter
+ def friction_ode_slip2(self,value):
+ self.ui.surface_ode_slip2_sp.setValue(value)
+
+
+#bullet
+ #friction
+ @property
+ def friction_bullet_friction(self):
+ return self.ui.surface_bullet_friction_sp.value()
+ @friction_bullet_friction.setter
+ def friction_bullet_friction(self,value):
+ self.ui.surface_bullet_friction_sp.setValue(value)
+
+ #friction2
+ @property
+ def friction_bullet_friction2(self):
+ return self.ui.surface_bullet_friction2_sp.value()
+ @friction_bullet_friction2.setter
+ def friction_bullet_friction2(self,value):
+ self.ui.surface_bullet_friction2_sp.setValue(value)
+
+ #rolling_friction
+ @property
+ def friction_bullet_rolling_friction(self):
+ return self.ui.surface_bullet_rolling_friction_sp.value()
+ @friction_bullet_rolling_friction.setter
+ def friction_bullet_rolling_friction(self,value):
+ self.ui.surface_bullet_rolling_friction_sp.setValue(value)
+
+ @property
+ def friction_bullet_fdir1(self):
+ return [self.ui.surface_bullet_fdir1_x_sp.value(),self.ui.surface_bullet_fdir1_x_sp.value(),self.ui.surface_bullet_fdir1_x_sp.value()]
+
+ @friction_bullet_fdir1.setter
+ def friction_bullet_fdir1(self,vals):
+ self.ui.surface_bullet_fdir1_x_sp.setValue(vals[0])
+ self.ui.surface_bullet_fdir1_x_sp.setValue(vals[1])
+ self.ui.surface_bullet_fdir1_x_sp.setValue(vals[2])
+
+
+#contact
+ @property
+ def collide_without_contact(self):
+ return str('true') if self.ui.contact_collide_without_contact_cb.isChecked() else str('false')
+ @collide_without_contact.setter
+ def collide_without_contact(self,state):
+ self.ui.contact_collide_without_contact_cb.setCheckState(QtCore.Qt.Checked) if state=='true' else self.ui.contact_collide_without_contact_cb.setCheckState(QtCore.Qt.Unchecked)
+
+ #collide_without_contact_bitmask
+ @property
+ def collide_without_contact_bitmask(self):
+ return self.ui.contact_collide_without_contact_bitmask_sp.value()
+ @collide_without_contact_bitmask.setter
+ def collide_without_contact_bitmask(self,val):
+ self.ui.contact_collide_without_contact_bitmask_sp.setValue(val)
+
+ @property
+ def collide_bitmask(self):
+ return self.ui.contact_collide_bitmask_sp.value()
+ @collide_bitmask.setter
+ def collide_bitmask(self,value):
+ self.ui.contact_collide_bitmask_sp.setValue(value)
+
+ @property
+ def category_bitmask(self):
+ return self.ui.contact_category_bitmask_sp.value()
+ @category_bitmask.setter
+ def category_bitmask(self,value):
+ self.ui.contact_category_bitmask_sp.setValue(value)
+
+ @property
+ def poissons_ratio(self):
+ return self.ui.contact_poissons_ratio_sp.value()
+ @poissons_ratio.setter
+ def poissons_ratio(self,value):
+ self.ui.contact_poissons_ratio_sp.setValue(value)
+
+ @property
+ def elastic_modulus(self):
+ return self.ui.contact_elastic_modulus_sp.value()
+ @elastic_modulus.setter
+ def elastic_modulus(self,value):
+ self.ui.contact_elastic_modulus_sp.setValue(value)
+ #ode
+
+ @property
+ def contact_ode_soft_cfm(self):
+ return self.ui.contact_ode_soft_cfm_sp.value()
+ @contact_ode_soft_cfm.setter
+ def contact_ode_soft_cfm(self,value):
+ self.ui.contact_ode_soft_cfm_sp.setValue(value)
+
+ @property
+ def contact_ode_soft_erp(self):
+ return self.ui.contact_ode_soft_erp_sp.value()
+ @contact_ode_soft_erp.setter
+ def contact_ode_soft_erp(self,value):
+ self.ui.contact_ode_soft_erp_sp.setValue(value)
+
+ @property
+ def contact_ode_kp(self):
+ return self.ui.contact_ode_kp_sp.value()
+ @contact_ode_kp.setter
+ def contact_ode_kp(self,value):
+ self.ui.contact_ode_kp_sp.setValue(value)
+
+ @property
+ def contact_ode_kd(self):
+ return self.ui.contact_ode_kd_sp.value()
+ @contact_ode_kd.setter
+ def contact_ode_kd(self,value):
+ self.ui.contact_ode_kd_sp.setValue(value)
+
+ @property
+ def contact_ode_max_vel(self):
+ return self.ui.contact_ode_max_vel_sp.value()
+ @contact_ode_max_vel.setter
+ def contact_ode_max_vel(self,value):
+ self.ui.contact_ode_max_vel_sp.setValue(value)
+
+ @property
+ def contact_ode_min_depth(self):
+ return self.ui.contact_ode_min_depth_sp.value()
+ @contact_ode_min_depth.setter
+ def contact_ode_min_depth(self,value):
+ self.ui.contact_ode_min_depth_sp.setValue(value)
+
+ #bullet
+ @property
+ def contact_bullet_soft_cfm(self):
+ return self.ui.contact_bullet_soft_cfm_sp.value()
+ @contact_bullet_soft_cfm.setter
+ def contact_bullet_soft_cfm(self,value):
+ self.ui.contact_bullet_soft_cfm_sp.setValue(value)
+
+ @property
+ def contact_bullet_soft_erp(self):
+ return self.ui.contact_bullet_soft_erp_sp.value()
+ @contact_bullet_soft_erp.setter
+ def contact_bullet_soft_erp(self,value):
+ self.ui.contact_bullet_soft_erp_sp.setValue(value)
+
+ @property
+ def contact_bullet_kp(self):
+ return self.ui.contact_bullet_kp_sp.value()
+ @contact_bullet_kp.setter
+ def contact_bullet_kp(self,value):
+ self.ui.contact_bullet_kp_sp.setValue(value)
+
+ @property
+ def contact_bullet_kd(self):
+ return self.ui.contact_bullet_kd_sp.value()
+ @contact_bullet_kd.setter
+ def contact_bullet_kd(self,value):
+ self.ui.contact_bullet_kd_sp.setValue(value)
+
+ @property
+ def contact_bullet_split_impulse(self):
+ return str('true') if self.ui.contact_bullet_split_impulse_cb.isChecked() else str('false')
+ @contact_bullet_split_impulse.setter
+ def contact_bullet_split_impulse(self,state):
+ self.ui.contact_bullet_split_impulse_cb.setCheckState(QtCore.Qt.Checked) if state=='true' else self.ui.contact_bullet_split_impulse_cb.setCheckState(QtCore.Qt.Unchecked)
+
+ @property
+ def split_impulse_penetration_threshold(self):
+ return self.ui.split_impulse_penetration_threshold_sp.value()
+ @split_impulse_penetration_threshold.setter
+ def split_impulse_penetration_threshold(self,value):
+ self.ui.split_impulse_penetration_threshold_sp.setValue(value)
+
+#soft contact
+ @property
+ def bone_attachment(self):
+ return self.ui.soft_contact_bone_attachment_sp.value()
+ @bone_attachment.setter
+ def bone_attachment(self,value):
+ self.ui.soft_contact_bone_attachment_sp.setValue(value)
+
+
+ @property
+ def stiffness(self):
+ return self.ui.soft_contact_stiffness_sp.value()
+ @stiffness.setter
+ def stiffness(self,value):
+ self.ui.soft_contact_stiffness_sp.setValue(value)
+
+ @property
+ def damping(self):
+ return self.ui.soft_body_damping_sp.value()
+ @damping.setter
+ def damping(self,value):
+ self.ui.soft_body_damping_sp.setValue(value)
+
+ @property
+ def flesh_mass_fraction(self):
+ return self.ui.soft_contact_flesh_mass_fraction_sp.value()
+ @flesh_mass_fraction.setter
+ def flesh_mass_fraction(self,value):
+ self.ui.soft_contact_flesh_mass_fraction_sp.setValue(value)
+
+#=========================================
+#_cb
+#============================================
+ #control checkboxes
+#friction
+ @property
+ def surface_ode_mu_cb(self):
+ return self.ui.surface_ode_mu_cb.isChecked()
+
+ @property
+ def surface_ode_mu2_cb(self):
+ return self.ui.surface_ode_mu2_cb.isChecked()
+
+ @property
+ def surface_ode_slip1_cb(self):
+ return self.ui.surface_ode_slip1_cb.isChecked()
+
+ @property
+ def surface_ode_slip2_cb(self):
+ return self.ui.surface_ode_slip2_cb.isChecked()
+
+ @property
+ def surface_bullet_friction_cb(self):
+ return self.ui.surface_bullet_friction_cb.isChecked()
+
+ @property
+ def surface_bullet_friction2_cb(self):
+ return self.ui.surface_bullet_friction2_cb.isChecked()
+
+ @property
+ def surface_bullet_rolling_friction_cb(self):
+ return self.ui.surface_bullet_rolling_friction_cb.isChecked()
+
+ @property
+ def ode_frdir1_groupbox(self):
+ return self.ui.ode_frdir1_groupbox.isChecked()
+ @property
+ def bullet_frdir1_groupbox(self):
+ return self.ui.bullet_frdir1_groupbox.isChecked()
+
+
+#contact
+ @property
+ def contact_collide_without_contact_bitmask_cb(self):
+ return self.ui.contact_collide_without_contact_bitmask_cb.isChecked()
+
+ @property
+ def contact_collide_bitmask_cb(self):
+ return self.ui.contact_collide_bitmask_cb.isChecked()
+
+ @property
+ def contact_category_bitmask_cb(self):
+ return self.ui.contact_category_bitmask_cb.isChecked()
+
+ @property
+ def contact_poissons_ratio_cb(self):
+ return self.ui.contact_poissons_ratio_cb.isChecked()
+
+ @property
+ def contact_ode_soft_cfm_cb(self):
+ return self.ui.contact_ode_soft_cfm_cb.isChecked()
+
+ @property
+ def contact_ode_soft_erp_cb(self):
+ return self.ui.contact_ode_soft_erp_cb.isChecked()
+
+ @property
+ def contact_ode_kp_cb(self):
+ return self.ui.contact_ode_kp_cb.isChecked()
+
+ @property
+ def contact_ode_kd_cb(self):
+ return self.ui.contact_ode_kd_cb.isChecked()
+
+ @property
+ def contact_ode_max_vel_cb(self):
+ return self.ui.contact_ode_max_vel_cb.isChecked()
+
+ @property
+ def contact_ode_min_depth_cb(self):
+ return self.ui.contact_ode_min_depth_cb.isChecked()
+
+ @property
+ def contact_bullet_soft_cfm_cb(self):
+ return self.ui.contact_bullet_soft_cfm_cb.isChecked()
+
+ @property
+ def contact_bullet_soft_erp_cb(self):
+ return self.ui.contact_bullet_soft_erp_cb.isChecked()
+
+ @property
+ def contact_bullet_kp_cb(self):
+ return self.ui.contact_bullet_kp_cb.isChecked()
+
+ @property
+ def contact_bullet_kd_cb(self):
+ return self.ui.contact_bullet_kd_cb.isChecked()
+
+
+#=======================================
+#=======surface ===================
+#================================
+
+class surface:
+ def __init__(self,ui) -> None:
+ self.ui=ui
+ self.properties=surface_properties(self.ui)
+ self.file_name="surface.sdf"
+ self.tag="surface"
+ self.surface_element=initialize_element_tree.convdict_2_tree(self.file_name).get_element
+ self.configUI()
+ self.updateUI()
+
+
+ def configUI(self):
+ #bounce
+ # bounce=self.surface_element.find('bounce')
+ self.ui.collision_restitution_coefficient_sp.valueChanged.connect(lambda val,bounce=self.surface_element.find('bounce'):
+ common.set_xml_data(bounce,"restitution_coefficient",False,self.properties.restitution_coefficient))
+
+ self.ui.collision_bounce_threshold_sp.valueChanged.connect(lambda val,bounce=self.surface_element.find('bounce'):
+ common.set_xml_data(bounce,"threshold",False,self.properties.threshold))
+
+ #torsional
+ # torsional=self.surface_element.find(".//friction/torsional")
+ self.ui.torsional_coeff_sp.valueChanged.connect(lambda val:
+ common.set_xml_data(self.surface_element.find(".//friction/torsional"),"coefficient",False,self.properties.coefficient))
+ self.ui.use_patch_radius_cb.stateChanged.connect(lambda val:
+ common.set_xml_data(self.surface_element.find(".//friction/torsional"),"use_patch_radius",False,self.properties.use_patch_radius))
+
+ self.ui.torsional_patch_radius_sp.valueChanged.connect(lambda val:
+ common.set_xml_data(self.surface_element.find(".//friction/torsional"),"patch_radius",False,self.properties.patch_radius))
+
+ self.ui.torsional_surface_radius_sp.valueChanged.connect(lambda val:
+ common.set_xml_data(self.surface_element.find(".//friction/torsional"),"surface_radius",False,self.properties.surface_radius))
+
+ self.ui.torsional_ode_slip_sp.valueChanged.connect(lambda val:
+ common.set_xml_data(self.surface_element.find(".//friction/torsional"),"slip",False,self.properties.torsional_slip))
+
+ #frictional_ode
+ # frictional_ode=self.surface_element.find(".//friction/ode")
+
+ self.ui.surface_ode_mu_sp.valueChanged.connect(lambda val:
+ common.set_xml_data(self.surface_element.find(".//friction/ode"),"mu",False,self.properties.friction_ode_mu))
+
+ self.ui.surface_ode_mu2_sp.valueChanged.connect(
+ lambda val:
+ common.set_xml_data(self.surface_element.find(".//friction/ode"),"mu2",False,self.properties.friction_ode_mu2)
+ )
+
+ self.ui.surface_ode_slip1_sp.valueChanged.connect(
+ lambda val:
+ common.set_xml_data(self.surface_element.find(".//friction/ode"),"slip1",False,self.properties.friction_ode_slip1)
+ )
+
+ self.ui.surface_ode_slip2_sp.valueChanged.connect(
+ lambda val:
+ common.set_xml_data(self.surface_element.find(".//friction/ode"),"slip2",False,self.properties.friction_ode_slip2)
+ )
+
+ self.ui.surface_ode_fdir1_x_sp.valueChanged.connect(self.ode_fdir1)
+ self.ui.surface_ode_fdir1_y_sp.valueChanged.connect(self.ode_fdir1)
+ self.ui.surface_ode_fdir1_z_sp.valueChanged.connect(self.ode_fdir1)
+
+ #frictional_bullet
+ # frictional_bullet=self.surface_element.find(".//fiction/bullet")
+ self.ui.surface_bullet_friction_sp.valueChanged.connect(
+ lambda val:
+ common.set_xml_data(self.surface_element.find(".//friction/bullet"),"friction",False,self.properties.friction_bullet_friction))
+ self.ui.surface_bullet_friction2_sp.valueChanged.connect(
+ lambda val:
+ common.set_xml_data(self.surface_element.find(".//friction/bullet"),"friction2",False,self.properties.friction_bullet_friction2)
+ )
+
+ self.ui.surface_bullet_rolling_friction_sp.valueChanged.connect(
+ lambda val:
+ common.set_xml_data(self.surface_element.find(".//friction/bullet"),"rolling_friction",False,self.properties.friction_bullet_rolling_friction)
+ )
+
+
+ self.ui.surface_bullet_fdir1_x_sp.valueChanged.connect(self.bullet_fdir1)
+ self.ui.surface_bullet_fdir1_y_sp.valueChanged.connect(self.bullet_fdir1)
+ self.ui.surface_bullet_fdir1_z_sp.valueChanged.connect(self.bullet_fdir1)
+
+ #contact
+ # contact=self.surface_element.find(".//contact")
+ self.ui.contact_collide_without_contact_cb.stateChanged.connect(self.on_contact_collide_without_contact)
+
+ self.ui.contact_collide_without_contact_bitmask_sp.valueChanged.connect(self.on_contact_collide_without_contact_bitmask)
+
+ self.ui.contact_collide_bitmask_sp.valueChanged.connect(self.on_contact_collide_bitmask)
+
+ self.ui.contact_category_bitmask_sp.valueChanged.connect(self.on_contact_category_bitmask)
+ self.ui.contact_poissons_ratio_sp.valueChanged.connect(self.on_contact_poissons_ratio)
+ self.ui.contact_elastic_modulus_sp.valueChanged.connect(self.on_contact_elastic_modulus)
+
+ #ode
+
+ self.ui.contact_ode_soft_cfm_sp.valueChanged.connect(self.on_contact_ode_soft_cfm)
+ self.ui.contact_ode_soft_erp_sp.valueChanged.connect(self.on_contact_ode_soft_erp)
+ self.ui.contact_ode_kp_sp.valueChanged.connect(self.on_contact_ode_kp)
+ self.ui.contact_ode_kd_sp.valueChanged.connect(self.on_contact_ode_kd)
+ self.ui.contact_ode_max_vel_sp.valueChanged.connect(self.on_contact_ode_max_vel)
+ self.ui.contact_ode_min_depth_sp.valueChanged.connect(self.on_contact_ode_min_depth)
+
+ #bullet
+ # contact_bullet=self.surface_element.find(".//contact/bullet")
+ self.ui.contact_bullet_soft_cfm_sp.valueChanged.connect(self.on_contact_bullet_soft_cfm)
+ self.ui.contact_bullet_soft_erp_sp.valueChanged.connect(self.on_contact_bullet_soft_erp)
+ self.ui.contact_bullet_kp_sp.valueChanged.connect(self.on_contact_bullet_kp)
+ self.ui.split_impulse_penetration_threshold_sp.valueChanged.connect(self.on_split_impulse_penetration_threshold)
+ self.ui.contact_bullet_kd_sp.valueChanged.connect(self.on_contact_bullet_kd)
+ self.ui.contact_bullet_split_impulse_cb.stateChanged.connect(self.on_contact_bullet_split_impulse)
+
+ #soft contact
+ # soft_contact=self.surface_element.find(".//surface/soft_contact")
+ self.ui.soft_contact_bone_attachment_sp.valueChanged.connect(self.on_soft_contact_bone_attachment)
+ self.ui.soft_contact_stiffness_sp.valueChanged.connect(self.on_soft_contact_stiffness)
+ self.ui.soft_body_damping_sp.valueChanged.connect(self.on_soft_body_damping)
+ self.ui.soft_contact_flesh_mass_fraction_sp.valueChanged.connect(self.on_soft_contact_flesh_mass_fraction)
+
+ #contact
+ #bullet
+ def on_contact_bullet_soft_cfm(self):
+ contact_bullet=self.surface_element.find(".//contact/bullet")
+ common.set_xml_data(contact_bullet,"soft_cfm",False,self.properties.contact_bullet_soft_cfm)
+
+ def on_contact_bullet_soft_erp(self):
+ contact_bullet=self.surface_element.find(".//contact/bullet")
+ common.set_xml_data(contact_bullet,"soft_erp",False,self.properties.contact_bullet_soft_erp)
+
+ def on_contact_bullet_kp(self):
+ contact_bullet=self.surface_element.find(".//contact/bullet")
+ common.set_xml_data(contact_bullet,"kp",False,self.properties.contact_bullet_kp)
+
+ def on_split_impulse_penetration_threshold(self):
+ contact_bullet=self.surface_element.find(".//contact/bullet")
+ common.set_xml_data(contact_bullet,"split_impulse_penetration_threshold",False,self.properties.split_impulse_penetration_threshold)
+
+ def on_contact_bullet_kd(self):
+ contact_bullet=self.surface_element.find(".//contact/bullet")
+ common.set_xml_data(contact_bullet,"kd",False,self.properties.contact_bullet_kd)
+
+ def on_contact_bullet_split_impulse(self):
+ contact_bullet=self.surface_element.find(".//contact/bullet")
+ common.set_xml_data(contact_bullet,"split_impulse",False,self.properties.contact_bullet_split_impulse)
+
+ #soft contact
+ def on_soft_contact_bone_attachment(self):
+ soft_contact=self.surface_element.find(".//soft_contact")
+ common.set_xml_data(soft_contact,"bone_attachment",False,self.properties.bone_attachment)
+
+ def on_soft_contact_stiffness(self):
+ soft_contact=self.surface_element.find(".//soft_contact")
+ common.set_xml_data(soft_contact,"stiffness",False,self.properties.stiffness)
+
+ def on_soft_body_damping(self):
+ soft_contact=self.surface_element.find(".//soft_contact")
+ common.set_xml_data(soft_contact,"damping",False,self.properties.damping)
+
+ def on_soft_contact_flesh_mass_fraction(self):
+ soft_contact=self.surface_element.find(".//soft_contact")
+ common.set_xml_data(soft_contact,"flesh_mass_fraction",False,self.properties.flesh_mass_fraction)
+
+ #ode
+
+ def on_contact_ode_soft_cfm(self):
+ contact_ode=self.surface_element.find(".//contact/ode")
+ common.set_xml_data(contact_ode,"soft_cfm",False,self.properties.contact_ode_soft_cfm)
+
+ def on_contact_ode_soft_erp(self):
+ contact_ode=self.surface_element.find(".//contact/ode")
+ common.set_xml_data(contact_ode,"soft_erp",False,self.properties.contact_ode_soft_erp)
+
+ def on_contact_ode_kp(self):
+ contact_ode=self.surface_element.find(".//contact/ode")
+ common.set_xml_data(contact_ode,"kp",False,self.properties.contact_ode_kp)
+
+ def on_contact_ode_kd(self):
+ contact_ode=self.surface_element.find(".//contact/ode")
+ common.set_xml_data(contact_ode,"kd",False,self.properties.contact_ode_kd)
+
+ def on_contact_ode_max_vel(self):
+ contact_ode=self.surface_element.find(".//contact/ode")
+ common.set_xml_data(contact_ode,"max_vel",False,self.properties.contact_ode_max_vel)
+
+ def on_contact_ode_min_depth(self):
+ contact_ode=self.surface_element.find(".//contact/ode")
+ common.set_xml_data(contact_ode,"min_depth",False,self.properties.contact_ode_min_depth)
+
+ #friction
+ #ode
+ def ode_fdir1(self):
+ frictional_ode=self.surface_element.find(".//friction/ode")
+ common.set_xml_data(frictional_ode,"fdir1",False,self.properties.friction_ode_fdir1)
+ #bullet
+
+ def bullet_fdir1(self):
+ frictional_bullet=self.surface_element.find(".//friction/bullet")
+ common.set_xml_data(frictional_bullet,"fdir1",False,self.properties.friction_bullet_fdir1)
+
+ #contact
+ def on_contact_collide_without_contact(self):
+ contact=self.surface_element.find(".//contact")
+ common.set_xml_data(contact,"collide_without_contact",False,self.properties.collide_without_contact)
+
+ def on_contact_collide_without_contact_bitmask(self):
+ contact=self.surface_element.find(".//contact")
+ common.set_xml_data(contact,"collide_without_contact_bitmask",False,self.properties.collide_without_contact_bitmask)
+
+ def on_contact_collide_bitmask(self):
+
+ contact=self.surface_element.find(".//contact")
+ common.set_xml_data(contact,"collide_bitmask",False,self.properties.collide_bitmask)
+
+ def on_contact_category_bitmask(self):
+ contact=self.surface_element.find(".//contact")
+ common.set_xml_data(contact,"category_bitmask",False,self.properties.category_bitmask)
+ def on_contact_poissons_ratio(self):
+ contact=self.surface_element.find(".//contact")
+ common.set_xml_data(contact,"poissons_ratio",False,self.properties.poissons_ratio)
+
+ def on_contact_elastic_modulus(self):
+ contact=self.surface_element.find(".//contact")
+ common.set_xml_data(contact,"elastic_modulus",False,self.properties.elastic_modulus)
+
+
+ def updateUI(self):
+ #bounce
+ bounce=self.surface_element.find('bounce')
+ #{tag : property}
+ bounce_pairs={"restitution_coefficient":"restitution_coefficient",
+ "threshold":"threshold"}
+ for tag in bounce_pairs.keys():
+ setattr(self.properties,bounce_pairs[tag],common.get_xml_data(bounce,tag,False))
+
+ #torsional
+ torsional=self.surface_element.find(".//friction/torsional")
+ #{tag property}
+ torsional_pairs={"coefficient":"coefficient","use_patch_radius":"use_patch_radius",
+ "patch_radius":"patch_radius","surface_radius":"surface_radius","slip":"torsional_slip"}
+ for tag in torsional_pairs.keys():
+ setattr(self.properties,torsional_pairs[tag],common.get_xml_data(torsional,tag,False))
+
+ #friction
+ #ode
+ frictional_ode=self.surface_element.find(".//friction/ode")
+ friction_ode_pairs={"mu":"friction_ode_mu","mu2":"friction_ode_mu2","slip1":"friction_ode_slip1",
+ "slip2":"friction_ode_slip2","fdir1":"friction_ode_fdir1"}
+ for tag in friction_ode_pairs.keys():
+ setattr(self.properties,friction_ode_pairs[tag],common.get_xml_data(frictional_ode,tag,False))
+
+ #bullet
+ frictional_bullet=self.surface_element.find(".//friction/bullet")
+ friction_bullet_pairs={"friction":"friction_bullet_friction","friction2":"friction_bullet_friction2",
+ "rolling_friction":"friction_bullet_rolling_friction","fdir1":"friction_bullet_fdir1"}
+ for tag in friction_bullet_pairs.keys():
+ setattr(self.properties,friction_bullet_pairs[tag],common.get_xml_data(frictional_bullet,tag,False))
+
+ #contact
+ #contact
+ contact=self.surface_element.find(".//contact")
+ contact_pairs={"collide_without_contact":"collide_without_contact","collide_without_contact_bitmask":"collide_without_contact_bitmask",
+ "category_bitmask":"category_bitmask","poissons_ratio":"poissons_ratio","collide_bitmask":"collide_bitmask",
+ "elastic_modulus":"elastic_modulus"}
+ for tag in contact_pairs.keys():
+ setattr(self.properties,contact_pairs[tag],common.get_xml_data(contact,tag,False))
+
+
+ #ode
+ contact_ode=self.surface_element.find(".//contact/ode")
+ contact_ode_pairs={"soft_cfm":"contact_ode_soft_cfm","soft_erp":"contact_ode_soft_erp",
+ "kp":"contact_ode_kp","kd":"contact_ode_kd","max_vel":"contact_ode_max_vel",
+ "min_depth":"contact_ode_min_depth"}
+ for tag in contact_ode_pairs.keys():
+ setattr(self.properties,contact_ode_pairs[tag],common.get_xml_data(contact_ode,tag,False))
+
+ #bullet
+ contact_bullet=self.surface_element.find(".//contact/bullet")
+ contact_bullet_pairs={"soft_cfm":"contact_bullet_soft_cfm","soft_erp":"contact_bullet_soft_erp",
+ "kp":"contact_bullet_kp","kd":"contact_bullet_kd","split_impulse":"contact_bullet_split_impulse",
+ "split_impulse_penetration_threshold":"split_impulse_penetration_threshold"}
+ for tag in contact_bullet_pairs.keys():
+ setattr(self.properties,contact_bullet_pairs[tag],common.get_xml_data(contact_bullet,tag,False))
+
+ #soft contact
+ soft_contact=self.surface_element.find(".//soft_contact")
+ #since properties have the same name as the pairs no need for pairs
+ soft_contact_tags=["bone_attachment","stiffness","damping","flesh_mass_fraction"]
+ for tag in soft_contact_tags:
+ setattr(self.properties,tag,common.get_xml_data(soft_contact,tag,False))
+
+ def reset(self):
+ pass
+
+ def update_element(self,item):
+ self.surface_element=item.surface_element
+ self.updateUI()
+
+ #return element
+ @property
+ def element(self):
+ t_surface_elem=copy.deepcopy(self.surface_element)
+ #modify bounce
+ if not self.ui.collision_bounce_groupbox.isChecked():
+ t_surface_elem.remove(t_surface_elem.find("bounce"))
+
+ #friction
+ friction=t_surface_elem.find(".//friction")
+ if self.ui.surface_friction_groupBox.isChecked():
+ #tor countrysion
+ torsion=friction.find("torsional")
+ if self.ui.friction_torsional_groupBox.isChecked():
+ if not self.ui.torsional_ode_groupbox.isChecked():
+ torsion.remove(torsion.find("ode"))
+ else:
+ friction.remove(friction.find(torsion))
+ #end torsion
+
+ #ode
+ friction_ode=friction.find("ode")
+ if self.ui.friction_ode_groupbox.isChecked():
+
+ elems_attrb_pair={"mu":"surface_ode_mu_cb","mu2":"surface_ode_mu2_cb","slip1":"surface_ode_slip1_cb","slip2":"surface_ode_slip2_cb"
+ ,"fdir1":"ode_frdir1_groupbox"}
+ for tag in elems_attrb_pair.keys():
+ #remove element if its not enabled
+ if not getattr(self.properties,elems_attrb_pair[tag]):
+ friction_ode.remove(friction_ode.find(tag))
+ else:
+ friction.remove(friction.find(friction_ode))
+ #end ode
+
+ #bullet
+ friction_bullet=friction.find("bullet")
+ if self.ui.surface_friction_bullet_groupbox.ischecked():
+ bullet_pairs={"friction":"surface_bullet_friction_cb","friction2":"surface_bullet_friction2_cb","rolling_friction":"surface_bullet_rolling_friction_cb"
+ ,"fdir1":"bullet_frdir1_groupbox"}
+ for tag in bullet_pairs.keys():
+ if not getattr(self.properties,bullet_pairs[tag]):
+ friction_bullet.remove(friction_bullet.find(tag))
+ else:
+ friction.remove(friction_bullet)
+ #end bullet
+ else:
+ #remove friction if its not enabled
+ t_surface_elem.remove(t_surface_elem.find(friction))
+
+ #end friction
+
+ #contact
+ contact=t_surface_elem.find("contact")
+ if self.ui.surface_contact_groupbox.isChecked():
+ contact_pairs={"collide_without_contact_bitmask":"contact_collide_without_contact_bitmask_cb","collide_bitmask":"contact_collide_bitmask_cb",
+ "category_bitmask":"contact_category_bitmask_cb","poissons_ratio":"contact_poissons_ratio_cb","elastic_modulus":"contact_elastic_modulus_cb"}
+ for tag in contact_pairs.keys():
+ if not getattr(self.properties,contact_pairs[tag]):
+ contact.remove(contact.find(tag))
+ #ode
+ contact_ode=contact.find("ode")
+ if self.ui.contact_ode_groupbox.isChecked():
+ ode_pairs={"soft_cfm":"contact_ode_soft_cfm_cb","soft_erp":"contact_ode_soft_erp_cb","kp":"contact_ode_kp_cb","kd":"contact_ode_kd_cb",
+ "max_vel":"contact_ode_max_vel_cb","min_depth":"contact_ode_min_depth_cb"}
+ for tag in ode_pairs.keys():
+ if not getattr(self.properties,ode_pairs[tag]):
+ contact_ode.remove(contact_ode.find(tag))
+ else:
+ contact.remove(contact.find(contact_ode))
+ #end ode
+
+ #bullet
+ contact_bullet=contact.find("bullet")
+ if self.ui.contact_bullet_groupbox.isChecked():
+ bullet_pairs={"soft_cfm":"contact_bullet_soft_cfm_cb","soft_erp":"contact_bullet_soft_erp_cb","kp":"contact_bullet_kp_cb","kd":"contact_bullet_kd_cb"}
+ for tag in bullet_pairs.keys():
+ if not getattr(self.properties,bullet_pairs[tag]):
+ contact_bullet.remove(tag)
+ else:
+ contact.remove(contact.find(contact_bullet))
+ #end bullet
+ else:
+ t_surface_elem.remove(t_surface_elem.find(contact))
+ #end contact
+
+ #soft contact
+ if not self.ui.soft_contact_dart_groupbox.isChecked():
+ t_surface_elem.remove(t_surface_elem.find("soft_contact"))
+
+ return t_surface_elem
\ No newline at end of file
diff --git a/robot_descriptor/sdf_elements/visual.py b/robot_descriptor/sdf_elements/visual.py
new file mode 100644
index 0000000..16ef662
--- /dev/null
+++ b/robot_descriptor/sdf_elements/visual.py
@@ -0,0 +1,125 @@
+from .. import common
+import copy
+import FreeCAD,FreeCADGui
+from PySide2 import QtCore
+from ..RD_utils import initialize_element_tree
+import xml.etree.ElementTree as ET
+import os
+
+from . import material
+
+class visual_properties:
+ def __init__(self,ui):
+ self.ui=ui
+#shadows
+ @property
+ def cast_shadows(self):
+ return str('true') if self.ui.visual_cast_shadows_checkBox.isChecked() else str('false')
+ @cast_shadows.setter
+ def cast_shadows(self,state):
+ self.ui.visual_cast_shadows_checkBox.setCheckState(QtCore.Qt.Checked) if state=='true' else self.ui.visual_cast_shadows_checkBox.setCheckState(QtCore.Qt.Unchecked)
+
+#transparency
+ @property
+ def transparency(self):
+ return self.ui.visual_transparency_sp.value()
+ @transparency.setter
+ def transparency(self,val):
+ self.ui.visual_transparency_sp.setValue(val)
+#laser retro
+ @property
+ def laser_retro(self):
+ return self.ui.visual_laser_retro_sp.value()
+ @laser_retro.setter
+ def laser_retro(self,value):
+ self.ui.visual_laser_retro_sp.setValue(value)
+
+#visibility flags
+ @property
+ def visibility_flags(self):
+ return self.ui.visual_visibility_flags_sp.value()
+ @visibility_flags.setter
+ def visibility_flags(self,value):
+ print(value)
+ self.ui.visual_visibility_flags_sp.setValue(value)
+
+#check boxes
+ @property
+ def visual_laser_retro_cb(self):
+ return self.ui.visual_laser_retro_cb.isChecked()
+
+ @property
+ def visual_transparency_cb(self):
+ return self.ui.visual_transparency_cb.isChecked()
+
+ @property
+ def visual_visibility_flags_cb(self):
+ return self.ui.visual_visibility_flags_cb.isChecked()
+
+
+#=============
+#====================
+class visual:
+ def __init__(self,parent_ui):
+ self.ui=parent_ui
+ self.file_name="visual.sdf"
+ self._visual_elem=initialize_element_tree.convdict_2_tree(self.file_name).get_element
+ self.properties=visual_properties(self.ui)
+ #maertial
+ self._material_ui=FreeCADGui.PySideUic.loadUi(os.path.join(common.UI_PATH,"material.ui"))
+ self._material_cls=material.material(self._material_ui)
+ #add widget to parent widget
+ self.ui.material_scroll.setWidget(self._material_ui.widget)
+ self.configUI()
+ self.updateUI()
+
+
+
+ def configUI(self):
+ self.ui.visual_laser_retro_sp.valueChanged.connect(self.on_laser_retro)
+ self.ui.visual_transparency_sp.valueChanged.connect(self.on_transparency)
+ self.ui.visual_visibility_flags_sp.valueChanged.connect(self.on_visibility_flags)
+ self.ui.visual_cast_shadows_checkBox.stateChanged.connect(self.on_cast_shadows)
+
+ def on_laser_retro(self):
+ element=self._visual_elem
+ common.set_xml_data(element,"laser_retro",False,self.properties.laser_retro)
+
+ def on_transparency(self):
+ element=self._visual_elem
+ common.set_xml_data(element,"transparency",False,self.properties.transparency)
+
+ def on_visibility_flags(self):
+ element=self._visual_elem
+ common.set_xml_data(element,"visibility_flags",False,self.properties.visibility_flags)
+
+ def on_cast_shadows(self):
+ element=self._visual_elem
+ common.set_xml_data(element,"cast_shadows",False,self.properties.cast_shadows)
+
+
+ def updateUI(self):
+ self.properties.laser_retro=common.get_xml_data(self._visual_elem,"laser_retro",False)
+ self.properties.transparency=common.get_xml_data(self._visual_elem,"transparency",False)
+ #this causes an overflow so dont update for now , ui is also disabled ,
+ # t
+ # self.properties.visibility_flags=common.get_xml_data(self._visual_elem,"visibility_flags",False)
+ self.properties.cast_shadows=common.get_xml_data(self._visual_elem,"cast_shadows",False)
+
+ def update_elements(self,item):
+ self._visual_elem=item._visual_element
+ self._material_cls.update_elements(item)
+ self.updateUI()
+
+ @property
+ def element(self):
+ t_visual_elem=copy.deepcopy(self._visual_elem)
+ visual_pairs={"laser_retro":"visual_laser_retro_cb","transparency":"visual_transparency_cb","visibility_flags":"visual_visibility_flags_cb"}
+ for tag in visual_pairs.keys():
+ if not getattr(self.properties,visual_pairs[tag]):
+ t_visual_elem.remove(t_visual_elem.find(tag))
+ if t_visual_elem.find("material") is None:
+ t_visual_elem.append(self._material_cls.element)
+ return t_visual_elem
+
+
\ No newline at end of file
diff --git a/robot_descriptor/sdf_elements/world.py b/robot_descriptor/sdf_elements/world.py
index 2cfa462..f825281 100644
--- a/robot_descriptor/sdf_elements/world.py
+++ b/robot_descriptor/sdf_elements/world.py
@@ -5,11 +5,11 @@
import copy
import xml.etree.ElementTree as ET
-from .. import RD_globals
+from .. import common
#reponsible for creating an element tree using xml.etree
-from ..RD_parser import initialize_element_tree
+from ..RD_utils import initialize_element_tree
-_icon_dir__=os.path.join(RD_globals.ICON_PATH,"world_properties.svg")
+_icon_dir__=os.path.join(common.ICON_PATH,"world_properties.svg")
'''setters will do nothing for optional part '''
@@ -104,13 +104,13 @@ def wind(self,wind_vec:list)->bool:
#------------------------------------------------------
class world():
def __init__(self):
- super(world,self).__init__()
+
self.parent_path=["sdf"]
self.tag='world'
self.file_name="world.sdf"
-
- self.ui_path=os.path.join(RD_globals.UI_PATH,"world.ui")
+ self.ui_path=os.path.join(common.UI_PATH,"world.ui")
self.world_form=FreeCADGui.PySideUic.loadUi(self.ui_path)
+ #get main window for use in aligning
mw=FreeCADGui.getMainWindow()
#centre dialog to main window
self.world_form.move(
@@ -142,19 +142,21 @@ def __init__(self):
self.configUI()
#update ui with previously configured values if available
+
self.reset(False)
-
+ #display window
+ self.world_form.exec_()
#window close event this is called when the (x) widget icon is pressed
def closeEvent(self, event):
print('closing widget\n')
event.accept()
def update_ui(self):
- self.properties.name=RD_globals.get_xml_data(self.world_elem,["world","name"],True)
- self.properties.gravity=RD_globals.get_xml_data(self.world_elem,"gravity",False)
- self.properties.wind=RD_globals.get_xml_data(self.world_elem,"linear_velocity",False)
- self.properties.audio=RD_globals.get_xml_data(self.world_elem,"device",False)
- self.properties.magnetic_field=RD_globals.get_xml_data(self.world_elem,"magnetic_field",False)
+ self.properties.name=common.get_xml_data(self.world_elem,["world","name"],True)
+ self.properties.gravity=common.get_xml_data(self.world_elem,"gravity",False)
+ self.properties.wind=common.get_xml_data(self.world_elem,"linear_velocity",False)
+ self.properties.audio=common.get_xml_data(self.world_elem,"device",False)
+ self.properties.magnetic_field=common.get_xml_data(self.world_elem,"magnetic_field",False)
#this will be called by the reset callback
def reset(self,default:bool=True):
@@ -166,7 +168,7 @@ def reset(self,default:bool=True):
else:
doc=FreeCAD.ActiveDocument
_root_dict=doc.Robot_Description.Proxy.element_dict
- el_dict=RD_globals.parse_dict(_root_dict,self.parent_path+[self.tag])
+ el_dict=common.parse_dict(_root_dict,self.parent_path+[self.tag])
if el_dict is not None:
el_str=el_dict['elem_str']
self.merge(el_str)
@@ -177,7 +179,7 @@ def reset(self,default:bool=True):
self.update_ui()
def merge(self, el_str):
- RD_globals.merge_elements(self.world_elem,ET.fromstring(el_str))
+ common.merge_elements(self.world_elem,ET.fromstring(el_str))
def configUI(self):
self.world_form.world_name_input.textEdited.connect(self.on_world_name)
@@ -204,8 +206,7 @@ def configUI(self):
# reset Pb
self.world_form.world_reset_btn.clicked.connect(self.on_reset)
- #display window
- self.world_form.exec_()
+
def update_element(self):
@@ -230,15 +231,15 @@ def on_reset(self):
def on_world_name(self):
name=self.properties.name
- RD_globals.set_xml_data(self.world_elem,"world",True,{"name":name})
+ common.set_xml_data(self.world_elem,"world",True,{"name":name})
def on_gravity(self):
- RD_globals.set_xml_data(self.world_elem,"gravity",False,self.properties.gravity)
+ common.set_xml_data(self.world_elem,"gravity",False,self.properties.gravity)
def on_magn(self):
- RD_globals.set_xml_data(self.world_elem,"magnetic_field",False,self.properties.magnetic_field)
+ common.set_xml_data(self.world_elem,"magnetic_field",False,self.properties.magnetic_field)
def on_wind(self):
- RD_globals.set_xml_data(self.world_elem,"linear_velocity",False,self.properties.wind)
+ common.set_xml_data(self.world_elem,"linear_velocity",False,self.properties.wind)
def on_audio(self):
- RD_globals.set_xml_data(self.world_elem,"device",False,self.properties.audio)
+ common.set_xml_data(self.world_elem,"device",False,self.properties.audio)
#ok push button pressed callback
def on_ok(self):
@@ -248,33 +249,33 @@ def on_ok(self):
def on_apply_pb(self):
#read string element data from RD_description proxy
updated_elem=self.update_element()
- RD_globals.update_dictionary(self.parent_path,self.tag,updated_elem)
+ common.update_dictionary(self.parent_path,self.tag,updated_elem)
#append elements in hierachy as they are supposed to appear in the tree e.g world is appended
#before atmosphere since its atmospheres parent, this helpsFreeCADGui.PySideUic.loadUi(self.ui_path,self) reduce the complexity
#of having to implement a way of ensuring parents are available
# dont add atmosphere element if the group box is not checked
if self.atmosphere.is_checked():
- RD_globals.update_dictionary(self.atmosphere.parent_path,self.atmosphere.tag,self.atmosphere.atmosphere_element)
+ common.update_dictionary(self.atmosphere.parent_path,self.atmosphere.tag,self.atmosphere.atmosphere_element)
#add physics properties
- RD_globals.update_dictionary(self._physics.parent_path,self._physics.tag,self._physics.element)
+ common.update_dictionary(self._physics.parent_path,self._physics.tag,self._physics.element)
#add spherical coordiates
if self.world_form.spherical_coordinates_groupbox.isChecked():
- RD_globals.update_dictionary(
+ common.update_dictionary(
self._spherical_coordinates.parent_path,
self._spherical_coordinates.tag_name,
self._spherical_coordinates.spherical_cood_elem)
#dont attempt to add a lights if there are no light sources
if len(self._lights.lights) >0:
- RD_globals.update_dictionary(self._lights.parent_path,self._lights.tag,self._lights.element)
+ common.update_dictionary(self._lights.parent_path,self._lights.tag,self._lights.element)
#add scene based on state of a checkbox
if self.world_form.enable_scene_checkBox.isChecked():
- RD_globals.update_dictionary(self._scene.parent_path,self._scene.tag,self._scene.element)
+ common.update_dictionary(self._scene.parent_path,self._scene.tag,self._scene.element)
#append the road element
- if self.world_form.enable_road_checkbox.isChecked():
- RD_globals.update_dictionary(self._road.parent_path,self._road.tag,self._road.element)
+ if self.world_form.include_material_info.isChecked():
+ common.update_dictionary(self._road.parent_path,self._road.tag,self._road.element)
print("updated\n")