Python bindings error when adding two plants to a scene graph in pyDrake - pybind11

I'd like to have two plants in the same builder and scene graph. (I don't want them on the same plant because I'd like to separate their dynamics, but I'd like them to affect each other, hence keeping them on the same builder and scene graph.)
My implementation is the following:
from pydrake.multibody.plant import AddMultibodyPlantSceneGraph
from pydrake.systems.framework import DiagramBuilder
builder = DiagramBuilder()
plant1, scene_graph = AddMultibodyPlantSceneGraph(builder, 0.0)
plant2 = AddMultibodyPlantSceneGraph(builder, 0.0, scene_graph)
When I run this, I get the error:
Traceback (most recent call last):
File "/filepath/2plants1scene.py", line 6, in <module>
plant2 = AddMultibodyPlantSceneGraph(builder, 0.0, scene_graph)
RuntimeError: C++ object must be owned by pybind11 when attempting to release to C++
Is this a bindings issue? The documentation for AddMultibodyPlantSceneGraph makes it seem as though it can add plants to already existing scenes.
The error messages look similar to this issue from 2018: https://github.com/RobotLocomotion/drake/issues/8160
Thanks in advance for any ideas.

Is this a bindings issue?
Regarding your specific error message, you are trying to take one object (whose ownership is governed by unique_ptr<>) and trying to pass it off its owned data twice (or more).
From C++ API:
https://drake.mit.edu/doxygen_cxx/classdrake_1_1multibody_1_1_multibody_plant.html#aac66563a5f3eb9e2041bd4fa8d438827
Note that the scene_graph argument is unique_ptr<>.
So, it's a bindings error insofar as the error message is kinda bad; however, it's more of a semantics issue w/ C++ API.
The documentation for AddMultibodyPlantSceneGraph makes it seem as though it can add plants to already existing scenes.
For reference, here is the core implementation of that method:
https://github.com/RobotLocomotion/drake/blob/v0.32.0/multibody/plant/multibody_plant.cc#L3346-L3370
For your use case, you should only add the SceneGraph to the DiagramBuilder once. Since you want to connect one SceneGraph to multiple MultibodyPlant instances, I would advise that you do not use AddMultibodyPlantSceneGraph, as that is sugar for a 1:1 pairing.
Instead, you should register and connect the SceneGraph manually; I think it would look something like this:
def register_plant_with_scene_graph(scene_graph, plant):
plant.RegsterAsSourceForSceneGraph(scene_graph)
builder.Connect(
plant.get_geometry_poses_output_port(),
scene_graph.get_source_pose_port(plant.get_source_id()),
)
builder.Connect(
scene_graph.get_query_output_port(),
plant.get_geometry_query_input_port(),
)
builder = DiagramBuilder()
scene_graph = builder.AddSystem(SceneGraph())
plant_1 = builder.AddSystem(MultibodyPlant(time_step=0.0))
register_plant_with_scene_graph(scene_graph, plant_1)
plant_2 = builder.AddSystem(MultibodyPlant(time_step=0.0))
register_plant_with_scene_graph(scene_graph, plant_2)
As Sean warned above, you will need to be careful with this pairing.

Related

QVT copy operation on models

I need to make changes in an instance of a model (preserving the original) using QVT. I thought in using the copy() operation which is defined in the QVT Documentation (As one of Orerations on models), but I don't understand how to use it, I have tried to execute the next code and look if the Out instance is copied from the In instance, but didn't have any luck:
modeltype MMNotation "strict"
uses 'http://www.eclipse.org/gmf/runtime/1.0.2/notation';
transformation QVTONotationTransformation(in SourceNotation: MMNotation,
out TargetNotation: MMNotation);
main() {
TargetNotation := SourceNotation.copy();
}
Looks like a bug in total model assignment. Please raise a Bugzilla. I think you should have got a warning that you cannot assign to a created model.
Try using deepclone of the root element instead, or assignment of the contents of the copy.
Regards
Ed Willink

OPAL-Regarding implementing construct call graph in OPAL

In Paper [A Software Product Line for Static Analyses(2014)], there is an illustration related constructing call graph(Listing7).
In this example, Line14 is related to construct call graph. while i check the src code and API, what i could find is DefaultCHACallGraphDomain.scala which has no implementation of construct call graph.
As my purpose is using OPAL to construct call graph. Is there any demo or documents help me understanding existing CallGraphDomain in OPAL? currently, i can only find some class declaration.
I'll be really appreciated if anyone can give me some suggestions related this topic.
Thanks in advance.
Jiang
The interface that was shown in the paper doesn't exist anymore, so you can totally forget about it.
The default interface to get a CallGraph class is provided by the Project object you retrieve when you load the bytecode a Java project.
A general code Example:
val project = ... // a java project
val computedCallGraph = project.get(/* Some call graph key */)
val callGraph = computedCallGraph.callGraph // the final call graph interface.
The computed call graph contains several things. It contains the entry points, unresolved method calls, exceptions when something went wrong at the construction time and the actual call graph.
OPAL provides you several call graph algorithms, you can retrieve each by passing the corresponding call graph key to the Project's get method.
Currently, the following two keys are available and can be passed to Project.get (more information is available in the documentation of this classes):
CHACallGraphKey
VTACallGraphKey
Analysis mode - Library vs Application
To construct a valid call graph for a software project it depends on the project kind which analysis mode to chose. While applications provide complete information (except incomplete projects, class loading and so on), software libraries are intended to be used by other projects. However, those two different scenarios have to be kept in mind, when construction call graphs. More details can be found here: org.opalj.AnalysisModes
OPAL offers the following analysis modes:
DesktopApplication (safe for application call graphs)
LibraryWithClosePackagesAssumption (safe for call graphs that are used for security-insensitive analyses)
LibraryWithOpenPackagesAssumption (very conservative/safe for security analyses)
The analysis mode can be either configured in OPAL's config file or set as project setting at runtime. You can find the config file in the Common project under /src/main/resources/reference.conf.
All of those analysis modes are supported by the the CHACallGraphKey while VTACallGraphKey only supports applications so far.
NOTE: The interface may change in upcoming versions again.

MATLAB: overriding table() methods

SETUP Win7 64b, R2015b, 16 GB of RAM, CPU i7-2700
The table() is a fundamental Matlab class which is also sealed, hence I cannot subclass it.
I want to fix some methods of this class and add new ones.
For instance, table.disp() is fundamentally broken, e.g. try NOT disp(table(rand(1e7,1))), or forget the ; in the command window. The variable takes only 76 MB in RAM but the display is unbuffered and it will stall your system!
Can I override methods like table.disp() without writing into matlabroot\toolbox\matlab\datatypes\#table?
Can I extend the table class with a new method under C:\MATLAB\#table\ismatrixlike.m? Why do I get
ismatrixlike(table)
Undefined function 'ismatrixlike' for input arguments of type 'table'.
Obviously, I did
addpath C:\MATLAB\
rehash toolboxcache
I also tried clear all.
The path has (alphabetic) precedence over matlabroot, but is missing a table.m class definition. If I add the native class defition to C:\MATLAB\#table, then I can run my new method (after a clear all). However:
>> methods(table)
Methods for class table:
classVarNames ismatrixlike table varfun
convertColumn renameVarNames unstack
only lists the methods in the new \#table folder, even though (some of) the old methods still work, e.g.
size(table)
This partly solves the problem, since now, the native \#table\private folder is not accessible anymore and therefore many native methods are broken!
Why am I doing this? Because I do not want to wait another 2 years before the table() is fixed. I already lost entire days because I simply forgot a ; in the command window and I cannot force a restart on my pc if it is running multiday simulations, but I have to wait for the disk-swap to end :(.
APPENDIX
More context about disp(table(rand(1e7,1))). This is what happens when I hit it (and luckily I am fast enough to CTRL-C out of it):
The culprit is line 172 of table.disp() which converts the numeric array into a cellstring (with the padding too!):
[cells, err, isLeft] = sprintfc(f, x, b);
After experimenting with several alternatives, I adopted the solution that intereferes the least with Matlab's native #table implementation and it's easily removed if things go awry.
The solution:
copy the whole #table folder, i.e. fullfile(matlabroot,'toolbox','matlab','datatypes','#table'), into a destination where you have write permissions.
I picked the destination to be fullfile(matlabroot,'toolbox','local','myfiles') since I do not have to bother with OS cross-compatibility, i.e. matlabroot takes care of that for me.
paste into the destination your #table folder with the new, overloaded and overriding methods (partially overwriting the copied original files)
add the destination to the matlab path, before the original #table, e.g. addpath your_destination -begin
Effects, pros and cons:
The native #table class/methods are now shadowed, try e.g. which table -all. However, this effect is quite clear, easily detectable and easily removed (delete destintation and remove path);
No weird conflicts between native #table (now shadowed) and new #table;
All methods, new and old, are visible, try methods(table);
Private table methods are accessible...
... but you are forced to use them.
Exposing the new methods (user-implemented) to the private ones requires more maintenance and direct handling of version conflicts in the table implementations.
You need write permissions on some eligible destination.
For those interested about the details, you can look into, https://github.com/okomarov/tableutils. Specifically the install_tableutils (the readme might not be updated).
The following works for me:
Define a modified disp function, say disp_modified.m, as follows, and put it in your path:
function disp_modified(t)
if istable(t)
%// Do whatever you want to display tables
builtin('disp', '''disp'' function intercepted!')
else
%// For non-tables, call `disp` normally
builtin('disp', t)
end
Define disp as a function handle to the modifed function (you can do that in startup.m to always have it by default):
disp = #disp_modified;
After this, in the command window I get
>> disp(1:5)
1 2 3 4 5
>> disp({1 2 3 'bb'})
[1] [2] [3] 'bb'
>> disp(table(rand(1e3,1)))
'disp' function intercepted!
Depending on the usage of the new class perhaps you could follow a cleaner approach. The proposed approach described in your post has the drawback that perhaps code used in your updated environment would not be easily portable to a new environment, or a program executed in your environment may demonstrate different behavior in a different environment.
Some questions you could consider (and perhaps clarify) would be: How do you intend to use the new class? Do you want to replace all the existing table uses? Do you want to be able to use it instead of a table class argument? Or do you want to alter the table so that each usage of the original table class in your environment uses the new class.
If you just need a new improved table for your usage, you could consider encapsulating the original table class in a new class. E.g MyTable, delegate all the methods you do not need to the original table methods, replace the methods you would like to improve or add new ones.
Update: Just saw the complete solution in Github and understood what you intended to do. Nice work. I will leave the post in case anyone finds it useful.

Can't launch from an object

I'm using the current version of the TypeSafe Scala/eclipse IDE. I have an object (which I called PositionObj to give it a unique name). PositionObj contains a main method. Yet when I try Run as > Scala application I get a pop-up message saying:
PositionObj needs to be an 'object' (it is currently a 'class').
In fact it's not a class, and there is no class with that name. Any thoughts about why this is happening and how I can get around it?
Here is the relevant code.
object PositionObj { ...
def main(args: Array[String] = Array[String]()): Unit = {
// This is just to see if anything happens.
println(position(3).p1Rqmts.keys.head)
}
...
Thanks.
Based on your answered-to code, try removing the default argument, since this might be creating a different code signature
I should have done this before, but now I notice that there is a compiler error message that says that the compiler couldn't handle the code because it was too big for a method. That's consistent with my experience with the problem. When I comment out a large table of data, everything works fine. So I'm now convinced that the problem was simply that the program was organized in a way that pieces of it were too large to be handled by the compiler.
I got around the problem by chopping my data table into multiple parts and including each one in a separate object. That worked even though all the objects were then included in the overall program. It was not the size of the program overall; it was the size of large chunks.
The compiler error message was somewhat misleading in that it said the problem was that a method was too large. In fact, my data table was a val in an object and not within a method. But as I said, chopping it up into separate objects and combing them with software solved the problem.

Is there difference in defining DropTarget in View and in Editor?

The code is:
DropTarget target = new DropTarget(sqlViewer.getTextWidget(),
DND.DROP_DEFAULT | DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK);
Transfer[] types = new Transfer[] {TreeLeafListTransfer.getInstance(),
TextTransfer.getInstance(), FileTransfer.getInstance()};
target.setTransfer(types);
target.addDropListener(new DropTreeLeafAdapter(sqlViewer));
And it works normally for a view, but fails in an editor. What's the difference?
upd: Whtat is most strange - if I surround it with a try/catch block, it still fails without exception.
edit: The problem is bigger than just DnD not working. The whole editor fails to instantiate because of this block. Just an empty window appears.
it works normally for a view, but fails in an editor. What's the difference?
The difference should be in the transfert type:
To recap, transfer types allow drag sources to specify what kinds of object they allow to be dragged out of their widget, and they allow drop targets to specify what kinds of objects they are willing to receive.
For each transfer type, there is a subclass of org.eclipse.swt.dnd.Transfer. These subclasses implement the marshaling behavior that converts between objects and bytes, allowing drag and drop transfers between applications.
May be the list of Transfer type you are using is not quite compatible with the target (an Editor)? See this thread for more test around that.
Another item to consider is the proper setup of a TransferDropTargetListener (like in this thread).
Since I have not yet fully tested eclipse DnD, I cannot give you much more details on this topic, but hopefully that will give you something to start your own analysis.