Merged from branch 'branches/wrap_mods' into 'trunk'
commit
c964bec14e
327
.cproject
327
.cproject
|
|
@ -308,6 +308,14 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testGaussianFactor.run" path="linear/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testGaussianFactor.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="all" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
|
@ -334,7 +342,6 @@
|
|||
</target>
|
||||
<target name="tests/testBayesTree.run" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>tests/testBayesTree.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
|
@ -342,7 +349,6 @@
|
|||
</target>
|
||||
<target name="testBinaryBayesNet.run" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testBinaryBayesNet.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
|
@ -390,7 +396,6 @@
|
|||
</target>
|
||||
<target name="testSymbolicBayesNet.run" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testSymbolicBayesNet.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
|
@ -398,7 +403,6 @@
|
|||
</target>
|
||||
<target name="tests/testSymbolicFactor.run" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>tests/testSymbolicFactor.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
|
@ -406,7 +410,6 @@
|
|||
</target>
|
||||
<target name="testSymbolicFactorGraph.run" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testSymbolicFactorGraph.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
|
@ -422,20 +425,11 @@
|
|||
</target>
|
||||
<target name="tests/testBayesTree" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>tests/testBayesTree</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testGaussianFactor.run" path="linear/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testGaussianFactor.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testPoseRTV.run" path="build/gtsam_unstable/dynamics" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
|
|
@ -524,22 +518,6 @@
|
|||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="tests/testPose2.run" path="build_retract/gtsam/geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>tests/testPose2.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="tests/testPose3.run" path="build_retract/gtsam/geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>tests/testPose3.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="all" path="CppUnitLite" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
|
@ -556,6 +534,22 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="tests/testPose2.run" path="build_retract/gtsam/geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>tests/testPose2.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="tests/testPose3.run" path="build_retract/gtsam/geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>tests/testPose3.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="all" path="spqr_mini" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
|
@ -580,26 +574,26 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="all" path="build_wrap" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<target name="testValues.run" path="build/gtsam/nonlinear" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>all</buildTarget>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testValues.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="build_wrap" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<target name="testOrdering.run" path="build/gtsam/nonlinear" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>check</buildTarget>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testOrdering.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="clean" path="build_wrap" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<target name="testKey.run" path="build/gtsam/nonlinear" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>clean</buildTarget>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testKey.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
|
|
@ -684,26 +678,26 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testValues.run" path="build/gtsam/nonlinear" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<target name="all" path="build_wrap" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testValues.run</buildTarget>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>all</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testOrdering.run" path="build/gtsam/nonlinear" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<target name="check" path="build_wrap" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testOrdering.run</buildTarget>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>check</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testKey.run" path="build/gtsam/nonlinear" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<target name="clean" path="build_wrap" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testKey.run</buildTarget>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>clean</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
|
|
@ -958,7 +952,6 @@
|
|||
</target>
|
||||
<target name="testGraph.run" path="build/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testGraph.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
|
@ -966,7 +959,6 @@
|
|||
</target>
|
||||
<target name="testJunctionTree.run" path="build/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testJunctionTree.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
|
@ -974,7 +966,6 @@
|
|||
</target>
|
||||
<target name="testSymbolicBayesNetB.run" path="build/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testSymbolicBayesNetB.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
|
@ -1110,7 +1101,6 @@
|
|||
</target>
|
||||
<target name="testErrors.run" path="linear" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testErrors.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
|
@ -1574,6 +1564,7 @@
|
|||
</target>
|
||||
<target name="testSimulated2DOriented.run" path="slam" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testSimulated2DOriented.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
|
@ -1613,6 +1604,7 @@
|
|||
</target>
|
||||
<target name="testSimulated2D.run" path="slam" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testSimulated2D.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
|
@ -1620,6 +1612,7 @@
|
|||
</target>
|
||||
<target name="testSimulated3D.run" path="slam" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testSimulated3D.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
|
@ -1835,6 +1828,7 @@
|
|||
</target>
|
||||
<target name="tests/testGaussianISAM2" path="build/slam" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>tests/testGaussianISAM2</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
|
@ -1856,6 +1850,102 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testRot3.run" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testRot3.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testRot2.run" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testRot2.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testPose3.run" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testPose3.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="timeRot3.run" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>timeRot3.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testPose2.run" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testPose2.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testCal3_S2.run" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testCal3_S2.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testSimpleCamera.run" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testSimpleCamera.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testHomography2.run" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testHomography2.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testCalibratedCamera.run" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testCalibratedCamera.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>check</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="clean" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>clean</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testPoint2.run" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testPoint2.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="install" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
|
@ -2057,7 +2147,6 @@
|
|||
</target>
|
||||
<target name="Generate DEB Package" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>cpack</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>-G DEB</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
|
@ -2065,7 +2154,6 @@
|
|||
</target>
|
||||
<target name="Generate RPM Package" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>cpack</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>-G RPM</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
|
@ -2073,7 +2161,6 @@
|
|||
</target>
|
||||
<target name="Generate TGZ Package" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>cpack</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>-G TGZ</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
|
@ -2081,7 +2168,6 @@
|
|||
</target>
|
||||
<target name="Generate TGZ Source Package" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>cpack</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>--config CPackSourceConfig.cmake</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
|
@ -2207,98 +2293,34 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testRot3.run" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<target name="testSpirit.run" path="build/wrap" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testRot3.run</buildTarget>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testSpirit.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testRot2.run" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<target name="testWrap.run" path="build/wrap" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testRot2.run</buildTarget>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testWrap.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testPose3.run" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<target name="check.wrap" path="build/wrap" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testPose3.run</buildTarget>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>check.wrap</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="timeRot3.run" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<target name="wrap" path="build/wrap" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>timeRot3.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testPose2.run" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testPose2.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testCal3_S2.run" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testCal3_S2.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testSimpleCamera.run" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testSimpleCamera.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testHomography2.run" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testHomography2.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testCalibratedCamera.run" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testCalibratedCamera.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>check</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="clean" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>clean</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testPoint2.run" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testPoint2.run</buildTarget>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>wrap</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
|
|
@ -2342,46 +2364,7 @@
|
|||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testSpirit.run" path="build/wrap" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testSpirit.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testWrap.run" path="build/wrap" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testWrap.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check.wrap" path="build/wrap" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>check.wrap</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="wrap_gtsam" path="build/wrap" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>wrap_gtsam</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="wrap" path="build/wrap" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>wrap</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
</buildTargets>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
</cproject>
|
||||
|
|
|
|||
|
|
@ -36,41 +36,47 @@ else()
|
|||
set(GTSAM_UNSTABLE_AVAILABLE 0)
|
||||
endif()
|
||||
|
||||
|
||||
# Configurable Options
|
||||
option(GTSAM_BUILD_TESTS "Enable/Disable building of tests" ON)
|
||||
option(GTSAM_BUILD_TIMING "Enable/Disable building of timing scripts" ON)
|
||||
option(GTSAM_BUILD_EXAMPLES "Enable/Disable building of examples" ON)
|
||||
if(GTSAM_UNSTABLE_AVAILABLE)
|
||||
option(GTSAM_BUILD_UNSTABLE "Enable/Disable libgtsam_unstable" OFF)
|
||||
option(GTSAM_BUILD_UNSTABLE "Enable/Disable libgtsam_unstable" ON)
|
||||
endif()
|
||||
option(GTSAM_BUILD_WRAP "Enable/Disable building of matlab wrap utility (necessary for matlab interface)" ON)
|
||||
if(MSVC)
|
||||
option(GTSAM_BUILD_SHARED_LIBRARY "Enable/Disable building of a shared version of gtsam" OFF)
|
||||
else()
|
||||
if(NOT MSVC)
|
||||
option(GTSAM_BUILD_SHARED_LIBRARY "Enable/Disable building of a shared version of gtsam" ON)
|
||||
endif()
|
||||
option(GTSAM_BUILD_STATIC_LIBRARY "Enable/Disable building of a static version of gtsam" ON)
|
||||
option(GTSAM_USE_QUATERNIONS "Enable/Disable using an internal Quaternion representation for rotations instead of rotation matrices" OFF)
|
||||
if(MSVC)
|
||||
option(GTSAM_BUILD_CONVENIENCE_LIBRARIES "Enable/Disable use of convenience libraries for faster development rebuilds, but slower install" OFF)
|
||||
option(GTSAM_BUILD_STATIC_LIBRARY "Enable/Disable building of a static version of gtsam" ON)
|
||||
else()
|
||||
set(GTSAM_BUILD_STATIC_LIBRARY ON)
|
||||
endif()
|
||||
option(GTSAM_USE_QUATERNIONS "Enable/Disable using an internal Quaternion representation for rotations instead of rotation matrices" OFF)
|
||||
if(NOT MSVC)
|
||||
option(GTSAM_BUILD_CONVENIENCE_LIBRARIES "Enable/Disable use of convenience libraries for faster development rebuilds, but slower install" ON)
|
||||
endif()
|
||||
option(GTSAM_INSTALL_MATLAB_TOOLBOX "Enable/Disable installation of matlab toolbox" ON)
|
||||
option(GTSAM_INSTALL_MATLAB_EXAMPLES "Enable/Disable installation of matlab examples" ON)
|
||||
option(GTSAM_INSTALL_MATLAB_TESTS "Enable/Disable installation of matlab tests" ON)
|
||||
option(GTSAM_INSTALL_WRAP "Enable/Disable installation of wrap utility" ON)
|
||||
|
||||
set(GTSAM_TOOLBOX_INSTALL_PATH ${CMAKE_INSTALL_PREFIX}/borg/toolbox CACHE DOCSTRING "Path to install matlab toolbox")
|
||||
set(GTSAM_WRAP_HEADER_PATH ${PROJECT_SOURCE_DIR}/wrap CACHE DOCSTRING "Path to directory of matlab.h")
|
||||
|
||||
# Options relating to MATLAB wrapper
|
||||
# TODO: Check for matlab mex binary before handling building of binaries
|
||||
option(GTSAM_INSTALL_MATLAB_TOOLBOX "Enable/Disable installation of matlab toolbox" ON)
|
||||
option(GTSAM_BUILD_WRAP "Enable/Disable building of matlab wrap utility (necessary for matlab interface)" ON)
|
||||
option(GTSAM_INSTALL_WRAP "Enable/Disable installation of wrap utility for wrapping other libraries" ON)
|
||||
set(GTSAM_TOOLBOX_INSTALL_PATH "" CACHE DOCSTRING "Matlab toolbox destination, blank defaults to CMAKE_INSTALL_PREFIX/borg/toolbox")
|
||||
set(GTSAM_BUILD_MEX_BINARY_FLAGS "" CACHE STRING "Extra flags for running Matlab MEX compilation")
|
||||
set(MEX_COMMAND "mex" CACHE FILEPATH "Command to use for executing mex (if on path, 'mex' will work)")
|
||||
|
||||
# Check / set dependent variables for MATLAB wrapper
|
||||
set(GTSAM_WRAP_HEADER_PATH "${PROJECT_SOURCE_DIR}/wrap")
|
||||
if(GTSAM_INSTALL_MATLAB_TOOLBOX AND NOT GTSAM_BUILD_WRAP)
|
||||
message(FATAL_ERROR "GTSAM_INSTALL_MATLAB_TOOLBOX is enabled, please also enable GTSAM_BUILD_WRAP")
|
||||
endif()
|
||||
if(GTSAM_INSTALL_WRAP AND NOT GTSAM_BUILD_WRAP)
|
||||
message(FATAL_ERROR "GTSAM_INSTALL_WRAP is enabled, please also enable GTSAM_BUILD_WRAP")
|
||||
endif()
|
||||
if(NOT GTSAM_TOOLBOX_INSTALL_PATH)
|
||||
set(GTSAM_TOOLBOX_INSTALL_PATH "${CMAKE_INSTALL_PREFIX}/borg/toolbox")
|
||||
endif()
|
||||
|
||||
# Flags for building/installing mex files
|
||||
option(GTSAM_BUILD_MEX_BIN "Enable/Disable building of matlab mex files" OFF)
|
||||
option(GTSAM_INSTALL_MEX_BIN "Enable/Disable installing matlab mex binaries" OFF)
|
||||
set(GTSAM_BUILD_MEX_BINARY_FLAGS "" CACHE STRING "Flags for running Matlab MEX compilation")
|
||||
set(MEX_COMMAND "mex" CACHE STRING "Command to use for executing mex (if on path, 'mex' will work)")
|
||||
|
||||
# Flags for choosing default packaging tools
|
||||
set(CPACK_SOURCE_GENERATOR "TGZ" CACHE STRING "CPack Default Source Generator")
|
||||
|
|
@ -90,7 +96,7 @@ endif(GTSAM_USE_QUATERNIONS)
|
|||
# Flags to determine whether tests and examples are build during 'make install'
|
||||
# Note that these remove the targets from the 'all'
|
||||
option(GTSAM_DISABLE_TESTS_ON_INSTALL "Disables building tests during install" ON)
|
||||
option(GTSAM_DISABLE_EXAMPLES_ON_INSTALL "Disables buildint examples during install" OFF)
|
||||
option(GTSAM_DISABLE_EXAMPLES_ON_INSTALL "Disables building examples during install" OFF)
|
||||
|
||||
# Pull in infrastructure
|
||||
if (GTSAM_BUILD_TESTS)
|
||||
|
|
@ -103,7 +109,8 @@ endif()
|
|||
if(CYGWIN OR MSVC OR WIN32)
|
||||
set(Boost_USE_STATIC_LIBS 1)
|
||||
endif()
|
||||
find_package(Boost 1.43 COMPONENTS serialization REQUIRED)
|
||||
find_package(Boost 1.43 COMPONENTS serialization system filesystem thread date_time REQUIRED)
|
||||
set(GTSAM_BOOST_LIBRARIES ${Boost_SERIALIZATION_LIBRARY})
|
||||
|
||||
# General build settings
|
||||
include_directories(
|
||||
|
|
@ -134,7 +141,9 @@ if (GTSAM_BUILD_EXAMPLES)
|
|||
endif(GTSAM_BUILD_EXAMPLES)
|
||||
|
||||
# Matlab toolbox
|
||||
add_subdirectory(matlab)
|
||||
if (GTSAM_INSTALL_MATLAB_TOOLBOX)
|
||||
add_subdirectory(matlab)
|
||||
endif()
|
||||
|
||||
# Build gtsam_unstable
|
||||
if (GTSAM_BUILD_UNSTABLE)
|
||||
|
|
@ -168,11 +177,12 @@ message(STATUS "Build flags ")
|
|||
print_config_flag(${GTSAM_BUILD_TIMING} "Build Timing scripts ")
|
||||
print_config_flag(${GTSAM_BUILD_EXAMPLES} "Build Examples ")
|
||||
print_config_flag(${GTSAM_BUILD_TESTS} "Build Tests ")
|
||||
print_config_flag(${GTSAM_BUILD_WRAP} "Build Wrap ")
|
||||
print_config_flag(${GTSAM_BUILD_SHARED_LIBRARY} "Build shared GTSAM Library ")
|
||||
print_config_flag(${GTSAM_BUILD_STATIC_LIBRARY} "Build static GTSAM Library ")
|
||||
if(NOT MSVC)
|
||||
print_config_flag(${GTSAM_BUILD_SHARED_LIBRARY} "Build shared GTSAM Library ")
|
||||
print_config_flag(${GTSAM_BUILD_STATIC_LIBRARY} "Build static GTSAM Library ")
|
||||
print_config_flag(${GTSAM_BUILD_CONVENIENCE_LIBRARIES} "Build Convenience Libraries ")
|
||||
endif()
|
||||
print_config_flag(${GTSAM_BUILD_TYPE_POSTFIXES} "Put build-type in library name ")
|
||||
print_config_flag(${GTSAM_BUILD_CONVENIENCE_LIBRARIES} "Build Convenience Libraries ")
|
||||
if(GTSAM_UNSTABLE_AVAILABLE)
|
||||
print_config_flag(${GTSAM_BUILD_UNSTABLE} "Build libgtsam_unstable ")
|
||||
endif()
|
||||
|
|
@ -192,11 +202,8 @@ print_config_flag(${GTSAM_USE_QUATERNIONS} "Quaternions as default R
|
|||
|
||||
message(STATUS "MATLAB toolbox flags ")
|
||||
print_config_flag(${GTSAM_INSTALL_MATLAB_TOOLBOX} "Install matlab toolbox ")
|
||||
print_config_flag(${GTSAM_INSTALL_MATLAB_EXAMPLES} "Install matlab examples ")
|
||||
print_config_flag(${GTSAM_INSTALL_MATLAB_TESTS} "Install matlab tests ")
|
||||
print_config_flag(${GTSAM_BUILD_WRAP} "Build Wrap ")
|
||||
print_config_flag(${GTSAM_INSTALL_WRAP} "Install wrap utility ")
|
||||
print_config_flag(${GTSAM_BUILD_MEX_BIN} "Build MEX binaries ")
|
||||
print_config_flag(${GTSAM_INSTALL_MEX_BIN} "Install MEX binaries ")
|
||||
message(STATUS "===============================================================")
|
||||
|
||||
# Include CPack *after* all flags
|
||||
|
|
|
|||
252
gtsam.h
252
gtsam.h
|
|
@ -6,19 +6,26 @@
|
|||
*
|
||||
* Requirements:
|
||||
* Classes must start with an uppercase letter
|
||||
* Only one Method/Constructor per line
|
||||
* - Can wrap a typedef
|
||||
* Only one Method/Constructor per line, though methods/constructors can extend across multiple lines
|
||||
* Methods can return
|
||||
* - Eigen types: Matrix, Vector
|
||||
* - C/C++ basic types: string, bool, size_t, size_t, double, char, unsigned char
|
||||
* - void
|
||||
* - Any class with which be copied with boost::make_shared()
|
||||
* - boost::shared_ptr of any object type
|
||||
* Limitations on methods
|
||||
* - Parsing does not support overloading
|
||||
* - There can only be one method (static or otherwise) with a given name
|
||||
* Constructors
|
||||
* - Overloads are supported
|
||||
* - A class with no constructors can be returned from other functions but not allocated directly in MATLAB
|
||||
* Methods
|
||||
* - Constness has no effect
|
||||
* Methods must start with a lowercase letter
|
||||
* Static methods must start with a letter (upper or lowercase) and use the "static" keyword
|
||||
* - Specify by-value (not reference) return types, even if C++ method returns reference
|
||||
* - Must start with a lowercase letter
|
||||
* - Overloads are supported
|
||||
* Static methods
|
||||
* - Must start with a letter (upper or lowercase) and use the "static" keyword
|
||||
* - The first letter will be made uppercase in the generated MATLAB interface
|
||||
* - Overloads are supported
|
||||
* Arguments to functions any of
|
||||
* - Eigen types: Matrix, Vector
|
||||
* - Eigen types and classes as an optionally const reference
|
||||
|
|
@ -35,7 +42,7 @@
|
|||
* Namespace usage
|
||||
* - Namespaces can be specified for classes in arguments and return values
|
||||
* - In each case, the namespace must be fully specified, e.g., "namespace1::namespace2::ClassName"
|
||||
* Using namespace
|
||||
* Using namespace: FIXME: this functionality is currently broken
|
||||
* - To use a namespace (e.g., generate a "using namespace x" line in cpp files), add "using namespace x;"
|
||||
* - This declaration applies to all classes *after* the declaration, regardless of brackets
|
||||
* Includes in C++ wrappers
|
||||
|
|
@ -44,17 +51,34 @@
|
|||
* - To override, add a full include statement just before the class statement
|
||||
* - An override include can be added for a namespace by placing it just before the namespace statement
|
||||
* - Both classes and namespace accept exactly one namespace
|
||||
* Overriding type dependency checks
|
||||
* Using classes defined in other modules
|
||||
* - If you are using a class 'OtherClass' not wrapped in this definition file, add "class OtherClass;" to avoid a dependency error
|
||||
* - Limitation: this only works if the class does not need a namespace specification
|
||||
* Virtual inheritance
|
||||
* - Specify fully-qualified base classes, i.e. "virtual class Derived : module::Base {"
|
||||
* - Mark with 'virtual' keyword, e.g. "virtual class Base {", and also "virtual class Derived : module::Base {"
|
||||
* - Forward declarations must also be marked virtual, e.g. "virtual class module::Base;" and
|
||||
* also "virtual class module::Derived;"
|
||||
* - Pure virtual (abstract) classes should list no constructors in this interface file
|
||||
* - Virtual classes must have a clone() function in C++ (though it does not have to be included
|
||||
* in the MATLAB interface). clone() will be called whenever an object copy is needed, instead
|
||||
* of using the copy constructor (which is used for non-virtual objects).
|
||||
* Templates
|
||||
* - Basic templates are supported either with an explicit list of types to instantiate,
|
||||
* e.g. template<T = {gtsam::Pose2, gtsam::Rot2, gtsam::Point3}> class Class1 { ... };
|
||||
* or with typedefs, e.g.
|
||||
* template<T, U> class Class2 { ... };
|
||||
* typedef Class2<Type1, Type2> MyInstantiatedClass;
|
||||
* - To create new instantiations in other modules, you must copy-and-paste the whole class definition
|
||||
* into the new module, but use only your new instantiation types.
|
||||
* - When forward-declaring template instantiations, use the generated/typedefed name, e.g.
|
||||
* class gtsam::Class1Pose2;
|
||||
* class gtsam::MyInstantiatedClass;
|
||||
*/
|
||||
|
||||
/**
|
||||
* Status:
|
||||
* - TODO: global functions
|
||||
* - TODO: default values for arguments
|
||||
* - TODO: overloaded functions
|
||||
* - TODO: signatures for constructors can be ambiguous if two types have the same first letter
|
||||
* - TODO: Handle gtsam::Rot3M conversions to quaternions
|
||||
*/
|
||||
|
||||
|
|
@ -64,7 +88,17 @@ namespace gtsam {
|
|||
// base
|
||||
//*************************************************************************
|
||||
|
||||
class LieVector {
|
||||
virtual class Value {
|
||||
// No constructors because this is an abstract class
|
||||
|
||||
// Testable
|
||||
void print(string s) const;
|
||||
|
||||
// Manifold
|
||||
size_t dim() const;
|
||||
};
|
||||
|
||||
virtual class LieVector : gtsam::Value {
|
||||
// Standard constructors
|
||||
LieVector();
|
||||
LieVector(Vector v);
|
||||
|
|
@ -96,7 +130,7 @@ class LieVector {
|
|||
// geometry
|
||||
//*************************************************************************
|
||||
|
||||
class Point2 {
|
||||
virtual class Point2 : gtsam::Value {
|
||||
// Standard Constructors
|
||||
Point2();
|
||||
Point2(double x, double y);
|
||||
|
|
@ -128,7 +162,7 @@ class Point2 {
|
|||
Vector vector() const;
|
||||
};
|
||||
|
||||
class StereoPoint2 {
|
||||
virtual class StereoPoint2 : gtsam::Value {
|
||||
// Standard Constructors
|
||||
StereoPoint2();
|
||||
StereoPoint2(double uL, double uR, double v);
|
||||
|
|
@ -157,7 +191,7 @@ class StereoPoint2 {
|
|||
Vector vector() const;
|
||||
};
|
||||
|
||||
class Point3 {
|
||||
virtual class Point3 : gtsam::Value {
|
||||
// Standard Constructors
|
||||
Point3();
|
||||
Point3(double x, double y, double z);
|
||||
|
|
@ -190,7 +224,7 @@ class Point3 {
|
|||
double z() const;
|
||||
};
|
||||
|
||||
class Rot2 {
|
||||
virtual class Rot2 : gtsam::Value {
|
||||
// Standard Constructors and Named Constructors
|
||||
Rot2();
|
||||
Rot2(double theta);
|
||||
|
|
@ -232,14 +266,14 @@ class Rot2 {
|
|||
Matrix matrix() const;
|
||||
};
|
||||
|
||||
class Rot3 {
|
||||
virtual class Rot3 : gtsam::Value {
|
||||
// Standard Constructors and Named Constructors
|
||||
Rot3();
|
||||
Rot3(Matrix R);
|
||||
static gtsam::Rot3 Rx(double t);
|
||||
static gtsam::Rot3 Ry(double t);
|
||||
static gtsam::Rot3 Rz(double t);
|
||||
// static gtsam::Rot3 RzRyRx(double x, double y, double z); // FIXME: overloaded functions don't work yet
|
||||
static gtsam::Rot3 RzRyRx(double x, double y, double z); // FIXME: overloaded functions don't work yet
|
||||
static gtsam::Rot3 RzRyRx(Vector xyz);
|
||||
static gtsam::Rot3 yaw(double t); // positive yaw is to right (as in aircraft heading)
|
||||
static gtsam::Rot3 pitch(double t); // positive pitch is up (increasing aircraft altitude)
|
||||
|
|
@ -261,7 +295,7 @@ class Rot3 {
|
|||
// Manifold
|
||||
static size_t Dim();
|
||||
size_t dim() const;
|
||||
// gtsam::Rot3 retractCayley(Vector v) const; // FIXME, does not exist in both Matrix and Quaternion options
|
||||
gtsam::Rot3 retractCayley(Vector v) const; // FIXME, does not exist in both Matrix and Quaternion options
|
||||
gtsam::Rot3 retract(Vector v) const;
|
||||
Vector localCoordinates(const gtsam::Rot3& p) const;
|
||||
|
||||
|
|
@ -284,7 +318,7 @@ class Rot3 {
|
|||
// Vector toQuaternion() const; // FIXME: Can't cast to Vector properly
|
||||
};
|
||||
|
||||
class Pose2 {
|
||||
virtual class Pose2 : gtsam::Value {
|
||||
// Standard Constructor
|
||||
Pose2();
|
||||
Pose2(double x, double y, double theta);
|
||||
|
|
@ -330,12 +364,12 @@ class Pose2 {
|
|||
Matrix matrix() const;
|
||||
};
|
||||
|
||||
class Pose3 {
|
||||
virtual class Pose3 : gtsam::Value {
|
||||
// Standard Constructors
|
||||
Pose3();
|
||||
Pose3(const gtsam::Pose3& pose);
|
||||
Pose3(const gtsam::Rot3& r, const gtsam::Point3& t);
|
||||
// Pose3(const gtsam::Pose2& pose2); // FIXME: shadows Pose3(Pose3 pose)
|
||||
Pose3(const gtsam::Pose2& pose2); // FIXME: shadows Pose3(Pose3 pose)
|
||||
Pose3(Matrix t);
|
||||
|
||||
// Testable
|
||||
|
|
@ -373,19 +407,20 @@ class Pose3 {
|
|||
double y() const;
|
||||
double z() const;
|
||||
Matrix matrix() const;
|
||||
// gtsam::Pose3 transform_to(const gtsam::Pose3& pose) const; // FIXME: shadows other transform_to()
|
||||
gtsam::Pose3 transform_to(const gtsam::Pose3& pose) const; // FIXME: shadows other transform_to()
|
||||
double range(const gtsam::Point3& point);
|
||||
// double range(const gtsam::Pose3& pose); // FIXME: shadows other range
|
||||
double range(const gtsam::Pose3& pose);
|
||||
};
|
||||
|
||||
class Cal3_S2 {
|
||||
virtual class Cal3_S2 : gtsam::Value {
|
||||
// Standard Constructors
|
||||
Cal3_S2();
|
||||
Cal3_S2(double fx, double fy, double s, double u0, double v0);
|
||||
Cal3_S2(Vector v);
|
||||
|
||||
// Testable
|
||||
void print(string s) const;
|
||||
bool equals(const gtsam::Cal3_S2& pose, double tol) const;
|
||||
bool equals(const gtsam::Cal3_S2& rhs, double tol) const;
|
||||
|
||||
// Manifold
|
||||
static size_t Dim();
|
||||
|
|
@ -409,6 +444,37 @@ class Cal3_S2 {
|
|||
Matrix matrix_inverse() const;
|
||||
};
|
||||
|
||||
virtual class Cal3DS2 : gtsam::Value {
|
||||
// Standard Constructors
|
||||
Cal3DS2();
|
||||
Cal3DS2(double fx, double fy, double s, double u0, double v0, double k1, double k2, double k3, double k4);
|
||||
Cal3DS2(Vector v);
|
||||
|
||||
// Testable
|
||||
void print(string s) const;
|
||||
bool equals(const gtsam::Cal3DS2& rhs, double tol) const;
|
||||
|
||||
// Manifold
|
||||
static size_t Dim();
|
||||
size_t dim() const;
|
||||
gtsam::Cal3DS2 retract(Vector v) const;
|
||||
Vector localCoordinates(const gtsam::Cal3DS2& c) const;
|
||||
|
||||
// Action on Point2
|
||||
gtsam::Point2 uncalibrate(const gtsam::Point2& p) const;
|
||||
// TODO: D2d functions that start with an uppercase letter
|
||||
|
||||
// Standard Interface
|
||||
double fx() const;
|
||||
double fy() const;
|
||||
double skew() const;
|
||||
double px() const;
|
||||
double py() const;
|
||||
Vector vector() const;
|
||||
Vector k() const;
|
||||
//Matrix K() const; //FIXME: Uppercase
|
||||
};
|
||||
|
||||
class Cal3_S2Stereo {
|
||||
// Standard Constructors
|
||||
Cal3_S2Stereo();
|
||||
|
|
@ -428,7 +494,7 @@ class Cal3_S2Stereo {
|
|||
double baseline() const;
|
||||
};
|
||||
|
||||
class CalibratedCamera {
|
||||
virtual class CalibratedCamera : gtsam::Value {
|
||||
// Standard Constructors and Named Constructors
|
||||
CalibratedCamera();
|
||||
CalibratedCamera(const gtsam::Pose3& pose);
|
||||
|
|
@ -458,14 +524,14 @@ class CalibratedCamera {
|
|||
double range(const gtsam::Point3& p) const; // TODO: Other overloaded range methods
|
||||
};
|
||||
|
||||
class SimpleCamera {
|
||||
virtual class SimpleCamera : gtsam::Value {
|
||||
// Standard Constructors and Named Constructors
|
||||
SimpleCamera();
|
||||
SimpleCamera(const gtsam::Pose3& pose);
|
||||
SimpleCamera(const gtsam::Pose3& pose, const gtsam::Cal3_S2& K);
|
||||
static gtsam::SimpleCamera level(const gtsam::Cal3_S2& K,
|
||||
const gtsam::Pose2& pose, double height);
|
||||
// static gtsam::SimpleCamera level(const gtsam::Pose2& pose, double height); // FIXME overload
|
||||
static gtsam::SimpleCamera level(const gtsam::Pose2& pose, double height); // FIXME overload
|
||||
static gtsam::SimpleCamera lookat(const gtsam::Point3& eye,
|
||||
const gtsam::Point3& target, const gtsam::Point3& upVector,
|
||||
const gtsam::Cal3_S2& K);
|
||||
|
|
@ -490,7 +556,7 @@ class SimpleCamera {
|
|||
gtsam::Point2 project(const gtsam::Point3& point);
|
||||
gtsam::Point3 backproject(const gtsam::Point2& p, double depth) const;
|
||||
double range(const gtsam::Point3& point);
|
||||
// double range(const gtsam::Pose3& point); // FIXME, overload
|
||||
double range(const gtsam::Pose3& point); // FIXME, overload
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
|
|
@ -679,17 +745,17 @@ class VariableIndex {
|
|||
|
||||
#include <gtsam/linear/NoiseModel.h>
|
||||
namespace noiseModel {
|
||||
class Base {
|
||||
virtual class Base {
|
||||
};
|
||||
|
||||
class Gaussian {
|
||||
virtual class Gaussian : gtsam::noiseModel::Base {
|
||||
static gtsam::noiseModel::Gaussian* SqrtInformation(Matrix R);
|
||||
static gtsam::noiseModel::Gaussian* Covariance(Matrix R);
|
||||
// Matrix R() const; // FIXME: cannot parse!!!
|
||||
void print(string s) const;
|
||||
};
|
||||
|
||||
class Diagonal {
|
||||
virtual class Diagonal : gtsam::noiseModel::Gaussian {
|
||||
static gtsam::noiseModel::Diagonal* Sigmas(Vector sigmas);
|
||||
static gtsam::noiseModel::Diagonal* Variances(Vector variances);
|
||||
static gtsam::noiseModel::Diagonal* Precisions(Vector precisions);
|
||||
|
|
@ -697,14 +763,14 @@ class Diagonal {
|
|||
void print(string s) const;
|
||||
};
|
||||
|
||||
class Isotropic {
|
||||
virtual class Isotropic : gtsam::noiseModel::Diagonal {
|
||||
static gtsam::noiseModel::Isotropic* Sigma(size_t dim, double sigma);
|
||||
static gtsam::noiseModel::Isotropic* Variance(size_t dim, double varianace);
|
||||
static gtsam::noiseModel::Isotropic* Precision(size_t dim, double precision);
|
||||
void print(string s) const;
|
||||
};
|
||||
|
||||
class Unit {
|
||||
virtual class Unit : gtsam::noiseModel::Isotropic {
|
||||
static gtsam::noiseModel::Unit* Create(size_t dim);
|
||||
void print(string s) const;
|
||||
};
|
||||
|
|
@ -759,7 +825,7 @@ class GaussianBayesNet {
|
|||
void push_front(gtsam::GaussianConditional* conditional);
|
||||
};
|
||||
|
||||
class GaussianFactor {
|
||||
virtual class GaussianFactor {
|
||||
void print(string s) const;
|
||||
bool equals(const gtsam::GaussianFactor& lf, double tol) const;
|
||||
double error(const gtsam::VectorValues& c) const;
|
||||
|
|
@ -767,7 +833,7 @@ class GaussianFactor {
|
|||
size_t size() const;
|
||||
};
|
||||
|
||||
class JacobianFactor {
|
||||
virtual class JacobianFactor : gtsam::GaussianFactor {
|
||||
JacobianFactor();
|
||||
JacobianFactor(Vector b_in);
|
||||
JacobianFactor(size_t i1, Matrix A1, Vector b,
|
||||
|
|
@ -787,7 +853,7 @@ class JacobianFactor {
|
|||
gtsam::GaussianFactor* negate() const;
|
||||
};
|
||||
|
||||
class HessianFactor {
|
||||
virtual class HessianFactor : gtsam::GaussianFactor {
|
||||
HessianFactor(const gtsam::HessianFactor& gf);
|
||||
HessianFactor();
|
||||
HessianFactor(size_t j, Matrix G, Vector g, double f);
|
||||
|
|
@ -811,22 +877,19 @@ class GaussianFactorGraph {
|
|||
GaussianFactorGraph(const gtsam::GaussianBayesNet& CBN);
|
||||
|
||||
// From FactorGraph
|
||||
void push_back(gtsam::GaussianFactor* factor);
|
||||
void print(string s) const;
|
||||
bool equals(const gtsam::GaussianFactorGraph& lfgraph, double tol) const;
|
||||
size_t size() const;
|
||||
gtsam::GaussianFactor* at(size_t idx) const;
|
||||
|
||||
// Building the graph
|
||||
void add(gtsam::JacobianFactor* factor);
|
||||
// all these won't work as MATLAB can't handle overloading
|
||||
// void add(Vector b);
|
||||
// void add(size_t key1, Matrix A1, Vector b, const gtsam::SharedDiagonal& model);
|
||||
// void add(size_t key1, Matrix A1, size_t key2, Matrix A2, Vector b,
|
||||
// const gtsam::SharedDiagonal& model);
|
||||
// void add(size_t key1, Matrix A1, size_t key2, Matrix A2, size_t key3, Matrix A3,
|
||||
// Vector b, const gtsam::SharedDiagonal& model);
|
||||
// void add(gtsam::HessianFactor* factor);
|
||||
void push_back(gtsam::GaussianFactor* factor);
|
||||
void add(Vector b);
|
||||
void add(size_t key1, Matrix A1, Vector b, const gtsam::noiseModel::Diagonal* model);
|
||||
void add(size_t key1, Matrix A1, size_t key2, Matrix A2, Vector b,
|
||||
const gtsam::noiseModel::Diagonal* model);
|
||||
void add(size_t key1, Matrix A1, size_t key2, Matrix A2, size_t key3, Matrix A3,
|
||||
Vector b, const gtsam::noiseModel::Diagonal* model);
|
||||
|
||||
// error and probability
|
||||
double error(const gtsam::VectorValues& c) const;
|
||||
|
|
@ -909,29 +972,55 @@ class Ordering {
|
|||
void insert(size_t key, size_t order);
|
||||
void push_back(size_t key);
|
||||
void permuteWithInverse(const gtsam::Permutation& inversePermutation);
|
||||
// FIXME: Wrap InvertedMap as well
|
||||
//InvertedMap invert() const;
|
||||
gtsam::InvertedOrdering invert() const;
|
||||
};
|
||||
|
||||
#include <gtsam/nonlinear/Ordering.h>
|
||||
class InvertedOrdering {
|
||||
InvertedOrdering();
|
||||
|
||||
// FIXME: add bracket operator overload
|
||||
|
||||
bool empty() const;
|
||||
size_t size() const;
|
||||
bool count(size_t index) const; // Use as a boolean function with implicit cast
|
||||
|
||||
void clear();
|
||||
};
|
||||
|
||||
class NonlinearFactorGraph {
|
||||
NonlinearFactorGraph();
|
||||
void print(string s) const;
|
||||
double error(const gtsam::Values& c) const;
|
||||
double probPrime(const gtsam::Values& c) const;
|
||||
gtsam::NonlinearFactor* at(size_t i) const;
|
||||
void add(const gtsam::NonlinearFactor* factor);
|
||||
gtsam::Ordering* orderingCOLAMD(const gtsam::Values& c) const;
|
||||
// Ordering* orderingCOLAMDConstrained(const gtsam::Values& c, const std::map<gtsam::Key,int>& constraints) const;
|
||||
gtsam::GaussianFactorGraph* linearize(const gtsam::Values& c, const gtsam::Ordering& ordering) const;
|
||||
gtsam::NonlinearFactorGraph clone() const;
|
||||
};
|
||||
|
||||
class NonlinearFactor {
|
||||
// NonlinearFactor(); // FIXME: don't use this - creates an abstract class
|
||||
virtual class NonlinearFactor {
|
||||
void print(string s) const;
|
||||
void equals(const gtsam::NonlinearFactor& other, double tol) const;
|
||||
gtsam::KeyVector keys() const;
|
||||
size_t size() const;
|
||||
size_t dim() const; // FIXME: Doesn't link
|
||||
size_t dim() const;
|
||||
double error(const gtsam::Values& c) const;
|
||||
bool active(const gtsam::Values& c) const;
|
||||
gtsam::GaussianFactor* linearize(const gtsam::Values& c, const gtsam::Ordering& ordering) const;
|
||||
gtsam::NonlinearFactor* clone() const;
|
||||
// gtsam::NonlinearFactor* rekey(const gtsam::KeyVector& newKeys) const; //FIXME: Conversion from KeyVector to std::vector does not happen
|
||||
};
|
||||
|
||||
class Values {
|
||||
Values();
|
||||
size_t size() const;
|
||||
void print(string s) const;
|
||||
void insert(size_t j, const gtsam::Value& value);
|
||||
bool exists(size_t j) const;
|
||||
gtsam::Value at(size_t j) const;
|
||||
};
|
||||
|
||||
// Actually a FastList<Key>
|
||||
|
|
@ -1012,13 +1101,13 @@ class LevenbergMarquardtParams {
|
|||
LevenbergMarquardtParams();
|
||||
void print(string s) const;
|
||||
|
||||
double getMaxIterations() const;
|
||||
size_t getMaxIterations() const;
|
||||
double getRelativeErrorTol() const;
|
||||
double getAbsoluteErrorTol() const;
|
||||
double getErrorTol() const;
|
||||
string getVerbosity() const;
|
||||
|
||||
void setMaxIterations(double value);
|
||||
void setMaxIterations(size_t value);
|
||||
void setRelativeErrorTol(double value);
|
||||
void setAbsoluteErrorTol(double value);
|
||||
void setErrorTol(double value);
|
||||
|
|
@ -1040,6 +1129,59 @@ class LevenbergMarquardtParams {
|
|||
void setVerbosityLM(string s);
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
// Nonlinear factor types
|
||||
//*************************************************************************
|
||||
template<T = {gtsam::LieVector, gtsam::Point2, gtsam::StereoPoint2, gtsam::Point3, gtsam::Rot2, gtsam::Rot3, gtsam::Pose2, gtsam::Pose3, gtsam::Cal3_S2, gtsam::CalibratedCamera, gtsam::SimpleCamera}>
|
||||
virtual class PriorFactor : gtsam::NonlinearFactor {
|
||||
PriorFactor(size_t key, const T& prior, const gtsam::noiseModel::Base* noiseModel);
|
||||
};
|
||||
|
||||
|
||||
template<T = {gtsam::LieVector, gtsam::Point2, gtsam::Point3, gtsam::Rot2, gtsam::Rot3, gtsam::Pose2, gtsam::Pose3}>
|
||||
virtual class BetweenFactor : gtsam::NonlinearFactor {
|
||||
BetweenFactor(size_t key1, size_t key2, const T& relativePose, const gtsam::noiseModel::Base* noiseModel);
|
||||
};
|
||||
|
||||
|
||||
template<T = {gtsam::LieVector, gtsam::Point2, gtsam::StereoPoint2, gtsam::Point3, gtsam::Rot2, gtsam::Rot3, gtsam::Pose2, gtsam::Pose3, gtsam::Cal3_S2, gtsam::CalibratedCamera, gtsam::SimpleCamera}>
|
||||
virtual class NonlinearEquality : gtsam::NonlinearFactor {
|
||||
// Constructor - forces exact evaluation
|
||||
NonlinearEquality(size_t j, const T& feasible);
|
||||
// Constructor - allows inexact evaluation
|
||||
NonlinearEquality(size_t j, const T& feasible, double error_gain);
|
||||
};
|
||||
|
||||
|
||||
template<POSE, POINT>
|
||||
virtual class RangeFactor : gtsam::NonlinearFactor {
|
||||
RangeFactor(size_t key1, size_t key2, double measured, const gtsam::noiseModel::Base* noiseModel);
|
||||
};
|
||||
|
||||
typedef gtsam::RangeFactor<gtsam::Pose2, gtsam::Point2> RangeFactor2D;
|
||||
typedef gtsam::RangeFactor<gtsam::Pose3, gtsam::Point3> RangeFactor3D;
|
||||
typedef gtsam::RangeFactor<gtsam::CalibratedCamera, gtsam::Point3> RangeFactorCalibratedCamera;
|
||||
typedef gtsam::RangeFactor<gtsam::SimpleCamera, gtsam::Point3> RangeFactorSimpleCamera;
|
||||
|
||||
template<POSE, POINT, ROT>
|
||||
virtual class BearingFactor : gtsam::NonlinearFactor {
|
||||
BearingFactor(size_t key1, size_t key2, const ROT& measured, const gtsam::noiseModel::Base* noiseModel);
|
||||
};
|
||||
|
||||
typedef gtsam::BearingFactor<gtsam::Pose2, gtsam::Point2, gtsam::Rot2> BearingFactor2D;
|
||||
|
||||
|
||||
#include <ProjectionFactor.h>
|
||||
template<POSE, LANDMARK, CALIBRATION>
|
||||
virtual class GenericProjectionFactor : gtsam::NonlinearFactor {
|
||||
GenericProjectionFactor(const gtsam::Point2& measured, const gtsam::noiseModel::Base* noiseModel,
|
||||
size_t poseKey, size_t pointKey, const CALIBRATION* k);
|
||||
gtsam::Point2 measured() const;
|
||||
CALIBRATION* calibration() const;
|
||||
};
|
||||
typedef gtsam::GenericProjectionFactor<gtsam::Pose3, gtsam::Point3, gtsam::Cal3_S2> GenericProjectionFactorCal3_S2;
|
||||
typedef gtsam::GenericProjectionFactor<gtsam::Pose3, gtsam::Point3, gtsam::Cal3DS2> GenericProjectionFactorCal3DS2;
|
||||
|
||||
}///\namespace gtsam
|
||||
|
||||
//*************************************************************************
|
||||
|
|
|
|||
|
|
@ -95,9 +95,6 @@ if (GTSAM_BUILD_STATIC_LIBRARY)
|
|||
list(APPEND GTSAM_EXPORTED_TARGETS gtsam-static)
|
||||
set(GTSAM_EXPORTED_TARGETS "${GTSAM_EXPORTED_TARGETS}" PARENT_SCOPE)
|
||||
set(gtsam-lib gtsam-static)
|
||||
if(NOT GTSAM_BUILD_SHARED_LIBRARY)
|
||||
set(gtsam-prefer-shared gtsam-static)
|
||||
endif()
|
||||
endif (GTSAM_BUILD_STATIC_LIBRARY)
|
||||
|
||||
if (GTSAM_BUILD_SHARED_LIBRARY)
|
||||
|
|
@ -115,34 +112,23 @@ if (GTSAM_BUILD_SHARED_LIBRARY)
|
|||
if (NOT GTSAM_BUILD_STATIC_LIBRARY)
|
||||
set(gtsam-lib "gtsam-shared")
|
||||
endif()
|
||||
set(gtsam-prefer-shared gtsam-shared)
|
||||
endif(GTSAM_BUILD_SHARED_LIBRARY)
|
||||
|
||||
# Create the matlab toolbox for the gtsam library
|
||||
if (GTSAM_BUILD_WRAP)
|
||||
if (GTSAM_INSTALL_MATLAB_TOOLBOX)
|
||||
# Set up codegen
|
||||
include(GtsamMatlabWrap)
|
||||
|
||||
# TODO: generate these includes programmatically
|
||||
# Choose include flags depending on build process
|
||||
if (GTSAM_BUILD_MEX_BIN)
|
||||
set(MEX_INCLUDE_ROOT ${GTSAM_SOURCE_ROOT_DIR})
|
||||
set(MEX_LIB_ROOT ${CMAKE_BINARY_DIR})
|
||||
set(GTSAM_LIB_DIR ${MEX_LIB_ROOT}/gtsam)
|
||||
else()
|
||||
set(MEX_INCLUDE_ROOT ${CMAKE_INSTALL_PREFIX}/include)
|
||||
set(MEX_LIB_ROOT ${CMAKE_INSTALL_PREFIX}/lib)
|
||||
set(GTSAM_LIB_DIR ${MEX_LIB_ROOT})
|
||||
endif()
|
||||
set(MEX_INCLUDE_ROOT ${GTSAM_SOURCE_ROOT_DIR})
|
||||
set(MEX_LIB_ROOT ${CMAKE_BINARY_DIR})
|
||||
set(GTSAM_LIB_DIR ${MEX_LIB_ROOT}/gtsam)
|
||||
|
||||
# Generate, build and install toolbox
|
||||
string(TOUPPER ${CMAKE_BUILD_TYPE} build_type_toupper)
|
||||
get_target_property(gtsam_library_file ${gtsam-prefer-shared} LOCATION_${build_type_toupper})
|
||||
set(mexFlags "${GTSAM_BUILD_MEX_BINARY_FLAGS} -I${Boost_INCLUDE_DIR} -I${MEX_INCLUDE_ROOT} -I${MEX_INCLUDE_ROOT}/gtsam -I${MEX_INCLUDE_ROOT}/gtsam/base -I${MEX_INCLUDE_ROOT}/gtsam/geometry -I${MEX_INCLUDE_ROOT}/gtsam/linear -I${MEX_INCLUDE_ROOT}/gtsam/discrete -I${MEX_INCLUDE_ROOT}/gtsam/inference -I${MEX_INCLUDE_ROOT}/gtsam/nonlinear -I${MEX_INCLUDE_ROOT}/gtsam/slam ${gtsam_library_file}")
|
||||
# Lots of escapes '\' here because they get eaten during subsequent calls to 'set'
|
||||
set(mexFlags "${mexFlags} -g COMPFLAGS=\\\"$$COMPFLAGS ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${build_type_toupper}}\\\"")
|
||||
set(mexFlags ${GTSAM_BUILD_MEX_BINARY_FLAGS} -I${Boost_INCLUDE_DIR} -I${MEX_INCLUDE_ROOT} -I${MEX_INCLUDE_ROOT}/gtsam -I${MEX_INCLUDE_ROOT}/gtsam/base -I${MEX_INCLUDE_ROOT}/gtsam/geometry -I${MEX_INCLUDE_ROOT}/gtsam/linear -I${MEX_INCLUDE_ROOT}/gtsam/discrete -I${MEX_INCLUDE_ROOT}/gtsam/inference -I${MEX_INCLUDE_ROOT}/gtsam/nonlinear -I${MEX_INCLUDE_ROOT}/gtsam/slam)
|
||||
|
||||
# Macro to handle details of setting up targets
|
||||
# FIXME: issue with dependency between wrap_gtsam and wrap_gtsam_build, only shows up on CMake 2.8.3
|
||||
wrap_library(gtsam "${mexFlags}" "../")
|
||||
wrap_library(gtsam "${mexFlags}" "../" "")
|
||||
endif ()
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/pool/singleton_pool.hpp>
|
||||
#include <gtsam/base/Value.h>
|
||||
|
||||
|
|
@ -37,7 +37,8 @@ public:
|
|||
|
||||
/**
|
||||
* Create a duplicate object returned as a pointer to the generic Value interface.
|
||||
* For the sake of performance, this function use singleton pool allocator instead of the normal heap allocator
|
||||
* For the sake of performance, this function use singleton pool allocator instead of the normal heap allocator.
|
||||
* The result must be deleted with Value::deallocate_, not with the 'delete' operator.
|
||||
*/
|
||||
virtual Value* clone_() const {
|
||||
void *place = boost::singleton_pool<PoolTag, sizeof(DERIVED)>::malloc();
|
||||
|
|
@ -53,6 +54,13 @@ public:
|
|||
boost::singleton_pool<PoolTag, sizeof(DERIVED)>::free((void*)this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone this value (normal clone on the heap, delete with 'delete' operator)
|
||||
*/
|
||||
virtual boost::shared_ptr<Value> clone() const {
|
||||
return boost::make_shared<DERIVED>(static_cast<const DERIVED&>(*this));
|
||||
}
|
||||
|
||||
/// equals implementing generic Value interface
|
||||
virtual bool equals_(const Value& p, double tol = 1e-9) const {
|
||||
// Cast the base class Value pointer to a derived class pointer
|
||||
|
|
|
|||
|
|
@ -101,12 +101,15 @@ namespace gtsam {
|
|||
class Value {
|
||||
public:
|
||||
|
||||
/** Allocate and construct a clone of this value */
|
||||
/** Clone this value in a special memory pool, must be deleted with Value::deallocate_, *not* with the 'delete' operator. */
|
||||
virtual Value* clone_() const = 0;
|
||||
|
||||
/** Deallocate a raw pointer of this value */
|
||||
virtual void deallocate_() const = 0;
|
||||
|
||||
/** Clone this value (normal clone on the heap, delete with 'delete' operator) */
|
||||
virtual boost::shared_ptr<Value> clone() const = 0;
|
||||
|
||||
/** Compare this Value with another for equality. */
|
||||
virtual bool equals_(const Value& other, double tol = 1e-9) const = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -83,32 +83,32 @@ namespace gtsam {
|
|||
push_back(fg);
|
||||
}
|
||||
|
||||
/** Add a Jacobian factor */
|
||||
void add(const boost::shared_ptr<JacobianFactor>& factor) {
|
||||
factors_.push_back(boost::shared_ptr<GaussianFactor>(factor));
|
||||
/** Add a factor by value - makes a copy */
|
||||
void add(const GaussianFactor& factor) {
|
||||
factors_.push_back(factor.clone());
|
||||
}
|
||||
|
||||
/** Add a Hessian factor */
|
||||
void add(const boost::shared_ptr<HessianFactor>& factor) {
|
||||
factors_.push_back(boost::shared_ptr<GaussianFactor>(factor));
|
||||
/** Add a factor by pointer - stores pointer without copying the factor */
|
||||
void add(const sharedFactor& factor) {
|
||||
factors_.push_back(factor);
|
||||
}
|
||||
|
||||
/** Add a null factor */
|
||||
void add(const Vector& b) {
|
||||
add(JacobianFactor::shared_ptr(new JacobianFactor(b)));
|
||||
add(JacobianFactor(b));
|
||||
}
|
||||
|
||||
/** Add a unary factor */
|
||||
void add(Index key1, const Matrix& A1,
|
||||
const Vector& b, const SharedDiagonal& model) {
|
||||
add(JacobianFactor::shared_ptr(new JacobianFactor(key1,A1,b,model)));
|
||||
add(JacobianFactor(key1,A1,b,model));
|
||||
}
|
||||
|
||||
/** Add a binary factor */
|
||||
void add(Index key1, const Matrix& A1,
|
||||
Index key2, const Matrix& A2,
|
||||
const Vector& b, const SharedDiagonal& model) {
|
||||
add(JacobianFactor::shared_ptr(new JacobianFactor(key1,A1,key2,A2,b,model)));
|
||||
add(JacobianFactor(key1,A1,key2,A2,b,model));
|
||||
}
|
||||
|
||||
/** Add a ternary factor */
|
||||
|
|
@ -116,13 +116,13 @@ namespace gtsam {
|
|||
Index key2, const Matrix& A2,
|
||||
Index key3, const Matrix& A3,
|
||||
const Vector& b, const SharedDiagonal& model) {
|
||||
add(JacobianFactor::shared_ptr(new JacobianFactor(key1,A1,key2,A2,key3,A3,b,model)));
|
||||
add(JacobianFactor(key1,A1,key2,A2,key3,A3,b,model));
|
||||
}
|
||||
|
||||
/** Add an n-ary factor */
|
||||
void add(const std::vector<std::pair<Index, Matrix> > &terms,
|
||||
const Vector &b, const SharedDiagonal& model) {
|
||||
add(JacobianFactor::shared_ptr(new JacobianFactor(terms,b,model)));
|
||||
add(JacobianFactor(terms,b,model));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
* @author Frank Dellaert
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtsam/linear/GaussianDensity.h>
|
||||
#include <gtsam/linear/NoiseModel.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -419,7 +419,7 @@ namespace gtsam {
|
|||
maps_.reserve(maps_.size() + dimensions.size());
|
||||
BOOST_FOREACH(size_t dim, dimensions) {
|
||||
maps_.push_back(values_.segment(varStart, dim));
|
||||
varStart += dim; // varStart is continued from first for loop
|
||||
varStart += (int)dim; // varStart is continued from first for loop
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,9 +55,14 @@ namespace gtsam {
|
|||
/** Unnormalized probability. O(n) */
|
||||
double probPrime(const Values& c) const;
|
||||
|
||||
template<class F>
|
||||
void add(const F& factor) {
|
||||
this->push_back(boost::shared_ptr<F>(new F(factor)));
|
||||
/// Add a factor by value - copies the factor object
|
||||
void add(const NonlinearFactor& factor) {
|
||||
this->push_back(factor.clone());
|
||||
}
|
||||
|
||||
/// Add a factor by pointer - stores pointer without copying factor object
|
||||
void add(const sharedFactor& factor) {
|
||||
this->push_back(factor);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -45,23 +45,23 @@ public:
|
|||
Verbosity verbosity; ///< The printing verbosity during optimization (default SILENT)
|
||||
|
||||
NonlinearOptimizerParams() :
|
||||
maxIterations(100.0), relativeErrorTol(1e-5), absoluteErrorTol(1e-5),
|
||||
maxIterations(100), relativeErrorTol(1e-5), absoluteErrorTol(1e-5),
|
||||
errorTol(0.0), verbosity(SILENT) {}
|
||||
|
||||
virtual ~NonlinearOptimizerParams() {}
|
||||
virtual void print(const std::string& str = "") const ;
|
||||
|
||||
inline double getMaxIterations() const { return maxIterations; }
|
||||
inline double getRelativeErrorTol() const { return relativeErrorTol; }
|
||||
inline double getAbsoluteErrorTol() const { return absoluteErrorTol; }
|
||||
inline double getErrorTol() const { return errorTol; }
|
||||
inline std::string getVerbosity() const { return verbosityTranslator(verbosity); }
|
||||
size_t getMaxIterations() const { return maxIterations; }
|
||||
double getRelativeErrorTol() const { return relativeErrorTol; }
|
||||
double getAbsoluteErrorTol() const { return absoluteErrorTol; }
|
||||
double getErrorTol() const { return errorTol; }
|
||||
std::string getVerbosity() const { return verbosityTranslator(verbosity); }
|
||||
|
||||
inline void setMaxIterations(double value) { maxIterations = value; }
|
||||
inline void setRelativeErrorTol(double value) { relativeErrorTol = value; }
|
||||
inline void setAbsoluteErrorTol(double value) { absoluteErrorTol = value; }
|
||||
inline void setErrorTol(double value) { errorTol = value ; }
|
||||
inline void setVerbosity(const std::string &src) { verbosity = verbosityTranslator(src); }
|
||||
void setMaxIterations(size_t value) { maxIterations = value; }
|
||||
void setRelativeErrorTol(double value) { relativeErrorTol = value; }
|
||||
void setAbsoluteErrorTol(double value) { absoluteErrorTol = value; }
|
||||
void setErrorTol(double value) { errorTol = value ; }
|
||||
void setVerbosity(const std::string &src) { verbosity = verbosityTranslator(src); }
|
||||
|
||||
Verbosity verbosityTranslator(const std::string &s) const;
|
||||
std::string verbosityTranslator(Verbosity value) const;
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ public:
|
|||
iterator end() { return order_.end(); }
|
||||
|
||||
/// Test if the key exists in the ordering.
|
||||
bool exists(Key key) const { return order_.count(key); }
|
||||
bool exists(Key key) const { return order_.count(key) > 0; }
|
||||
|
||||
///TODO: comment
|
||||
std::pair<iterator,bool> tryInsert(Key key, Index order) { return tryInsert(std::make_pair(key,order)); }
|
||||
|
|
@ -233,7 +233,10 @@ private:
|
|||
ar & BOOST_SERIALIZATION_NVP(order_);
|
||||
ar & BOOST_SERIALIZATION_NVP(nVars_);
|
||||
}
|
||||
};
|
||||
}; // \class Ordering
|
||||
|
||||
// typedef for use with matlab
|
||||
typedef Ordering::InvertedMap InvertedOrdering;
|
||||
|
||||
/**
|
||||
* @class Unordered
|
||||
|
|
|
|||
|
|
@ -25,12 +25,12 @@ namespace gtsam {
|
|||
/**
|
||||
* Binary factor for a bearing measurement
|
||||
*/
|
||||
template<class POSE, class POINT>
|
||||
template<class POSE, class POINT, class ROT = typename POSE::Rotation>
|
||||
class BearingFactor: public NoiseModelFactor2<POSE, POINT> {
|
||||
private:
|
||||
|
||||
typedef POSE Pose;
|
||||
typedef typename Pose::Rotation Rot;
|
||||
typedef ROT Rot;
|
||||
typedef POINT Point;
|
||||
|
||||
typedef BearingFactor<POSE, POINT> This;
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ namespace gtsam {
|
|||
* @param K shared pointer to the constant calibration
|
||||
*/
|
||||
GenericProjectionFactor(const Point2& measured, const SharedNoiseModel& model,
|
||||
const Key poseKey, Key pointKey, const shared_ptrK& K) :
|
||||
Key poseKey, Key pointKey, const boost::shared_ptr<CALIBRATION>& K) :
|
||||
Base(model, poseKey, pointKey), measured_(measured), K_(K) {
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,10 +15,12 @@ add_custom_target(check.unstable COMMAND ${CMAKE_CTEST_COMMAND} --output-on-fail
|
|||
foreach(subdir ${gtsam_unstable_subdirs})
|
||||
# Build convenience libraries
|
||||
file(GLOB subdir_srcs "${subdir}/*.cpp")
|
||||
set(${subdir}_srcs ${subdir_srcs})
|
||||
file(GLOB subdir_headers "${subdir}/*.h")
|
||||
set(${subdir}_srcs ${subdir_srcs} ${subdir_headers})
|
||||
gtsam_assign_source_folders("${${subdir}_srcs}") # Create MSVC structure
|
||||
if (subdir_srcs AND GTSAM_BUILD_CONVENIENCE_LIBRARIES)
|
||||
message(STATUS "Building Convenience Library: ${subdir}_unstable")
|
||||
add_library("${subdir}_unstable" STATIC ${subdir_srcs})
|
||||
add_library("${subdir}_unstable" STATIC ${${subdir}_srcs})
|
||||
endif()
|
||||
|
||||
# Build local library and tests
|
||||
|
|
@ -36,7 +38,9 @@ set(gtsam_unstable_srcs
|
|||
${slam_srcs}
|
||||
)
|
||||
|
||||
option (GTSAM_UNSTABLE_BUILD_SHARED_LIBRARY "Enable/Disable building of a shared version of gtsam_unstable" ON)
|
||||
if(NOT MSVC)
|
||||
option (GTSAM_UNSTABLE_BUILD_SHARED_LIBRARY "Enable/Disable building of a shared version of gtsam_unstable" ON)
|
||||
endif()
|
||||
|
||||
# Versions - same as core gtsam library
|
||||
set(gtsam_unstable_version ${GTSAM_VERSION_MAJOR}.${GTSAM_VERSION_MINOR}.${GTSAM_VERSION_PATCH})
|
||||
|
|
@ -73,28 +77,21 @@ if (GTSAM_UNSTABLE_BUILD_SHARED_LIBRARY)
|
|||
endif(GTSAM_UNSTABLE_BUILD_SHARED_LIBRARY)
|
||||
|
||||
# Wrap version for gtsam_unstable
|
||||
if (GTSAM_BUILD_WRAP)
|
||||
if (GTSAM_INSTALL_MATLAB_TOOLBOX)
|
||||
# Set up codegen
|
||||
include(GtsamMatlabWrap)
|
||||
|
||||
# TODO: generate these includes programmatically
|
||||
# Choose include flags depending on build process
|
||||
if (GTSAM_BUILD_MEX_BIN)
|
||||
set(MEX_INCLUDE_ROOT ${GTSAM_SOURCE_ROOT_DIR})
|
||||
set(MEX_LIB_ROOT ${CMAKE_BINARY_DIR})
|
||||
set(GTSAM_LIB_DIR ${MEX_LIB_ROOT}/gtsam)
|
||||
set(GTSAM_UNSTABLE_LIB_DIR ${MEX_LIB_ROOT}/gtsam_unstable)
|
||||
else()
|
||||
set(MEX_INCLUDE_ROOT ${CMAKE_INSTALL_PREFIX}/include)
|
||||
set(MEX_LIB_ROOT ${CMAKE_INSTALL_PREFIX}/lib)
|
||||
set(GTSAM_LIB_DIR ${MEX_LIB_ROOT})
|
||||
set(GTSAM_UNSTABLE_LIB_DIR ${MEX_LIB_ROOT})
|
||||
endif()
|
||||
set(MEX_INCLUDE_ROOT ${GTSAM_SOURCE_ROOT_DIR})
|
||||
set(MEX_LIB_ROOT ${CMAKE_BINARY_DIR})
|
||||
set(GTSAM_LIB_DIR ${MEX_LIB_ROOT}/gtsam)
|
||||
set(GTSAM_UNSTABLE_LIB_DIR ${MEX_LIB_ROOT}/gtsam_unstable)
|
||||
|
||||
# Generate, build and install toolbox
|
||||
set(mexFlags "-I${Boost_INCLUDE_DIR} -I${MEX_INCLUDE_ROOT} -I${MEX_INCLUDE_ROOT}/gtsam_unstable -I${MEX_INCLUDE_ROOT}/gtsam_unstable/dynamics -I${MEX_INCLUDE_ROOT}/gtsam_unstable/discrete -L${GTSAM_UNSTABLE_LIB_DIR} -L${GTSAM_LIB_DIR} -lgtsam -lgtsam_unstable")
|
||||
set(mexFlags -I${Boost_INCLUDE_DIR} -I${MEX_INCLUDE_ROOT} -I${MEX_INCLUDE_ROOT}/gtsam_unstable -I${MEX_INCLUDE_ROOT}/gtsam_unstable/dynamics -I${MEX_INCLUDE_ROOT}/gtsam_unstable/discrete)
|
||||
|
||||
# Macro to handle details of setting up targets
|
||||
wrap_library(gtsam_unstable "${mexFlags}" "./")
|
||||
wrap_library(gtsam_unstable "${mexFlags}" "./" gtsam)
|
||||
|
||||
endif(GTSAM_BUILD_WRAP)
|
||||
endif(GTSAM_INSTALL_MATLAB_TOOLBOX)
|
||||
|
|
|
|||
|
|
@ -77,8 +77,6 @@ public:
|
|||
const Vector& gyro() const { return gyro_; }
|
||||
const Vector& accel() const { return accel_; }
|
||||
Vector z() const { return concatVectors(2, &accel_, &gyro_); }
|
||||
const Key& key1() const { return this->key1_; }
|
||||
const Key& key2() const { return this->key2_; }
|
||||
|
||||
/**
|
||||
* Error evaluation with optional derivatives - calculates
|
||||
|
|
|
|||
|
|
@ -70,8 +70,6 @@ public:
|
|||
const Vector& gyro() const { return gyro_; }
|
||||
const Vector& accel() const { return accel_; }
|
||||
Vector z() const { return concatVectors(2, &accel_, &gyro_); }
|
||||
const Key& key1() const { return this->key1_; }
|
||||
const Key& key2() const { return this->key2_; }
|
||||
|
||||
/**
|
||||
* Error evaluation with optional derivatives - calculates
|
||||
|
|
|
|||
|
|
@ -3,10 +3,12 @@
|
|||
*/
|
||||
|
||||
// specify the classes from gtsam we are using
|
||||
class gtsam::Point3;
|
||||
class gtsam::Rot3;
|
||||
class gtsam::Pose3;
|
||||
class gtsam::SharedNoiseModel;
|
||||
virtual class gtsam::Value;
|
||||
virtual class gtsam::Point3;
|
||||
virtual class gtsam::Rot3;
|
||||
virtual class gtsam::Pose3;
|
||||
virtual class gtsam::noiseModel::Base;
|
||||
virtual class gtsam::NonlinearFactor;
|
||||
|
||||
namespace gtsam {
|
||||
|
||||
|
|
@ -18,7 +20,7 @@ class Dummy {
|
|||
};
|
||||
|
||||
#include <gtsam_unstable/dynamics/PoseRTV.h>
|
||||
class PoseRTV {
|
||||
virtual class PoseRTV : gtsam::Value {
|
||||
PoseRTV();
|
||||
PoseRTV(Vector rtv);
|
||||
PoseRTV(const gtsam::Point3& pt, const gtsam::Rot3& rot, const gtsam::Point3& vel);
|
||||
|
|
@ -66,6 +68,107 @@ class PoseRTV {
|
|||
Vector translationIntegrationVec(const gtsam::PoseRTV& x2, double dt) const;
|
||||
};
|
||||
|
||||
|
||||
// Nonlinear factors from gtsam, for our Value types
|
||||
#include <gtsam/slam/PriorFactor.h>
|
||||
template<T = {gtsam::PoseRTV}>
|
||||
virtual class PriorFactor : gtsam::NonlinearFactor {
|
||||
PriorFactor(size_t key, const T& prior, const gtsam::noiseModel::Base* noiseModel);
|
||||
};
|
||||
|
||||
|
||||
#include <gtsam/slam/BetweenFactor.h>
|
||||
template<T = {gtsam::PoseRTV}>
|
||||
virtual class BetweenFactor : gtsam::NonlinearFactor {
|
||||
BetweenFactor(size_t key1, size_t key2, const T& relativePose, const gtsam::noiseModel::Base* noiseModel);
|
||||
};
|
||||
|
||||
|
||||
#include <gtsam/slam/RangeFactor.h>
|
||||
template<POSE, POINT>
|
||||
virtual class RangeFactor : gtsam::NonlinearFactor {
|
||||
RangeFactor(size_t key1, size_t key2, double measured, const gtsam::noiseModel::Base* noiseModel);
|
||||
};
|
||||
|
||||
typedef gtsam::RangeFactor<gtsam::PoseRTV, gtsam::PoseRTV> RangeFactorRTV;
|
||||
|
||||
|
||||
#include <gtsam/nonlinear/NonlinearEquality.h>
|
||||
template<T = {gtsam::PoseRTV}>
|
||||
virtual class NonlinearEquality : gtsam::NonlinearFactor {
|
||||
// Constructor - forces exact evaluation
|
||||
NonlinearEquality(size_t j, const T& feasible);
|
||||
// Constructor - allows inexact evaluation
|
||||
NonlinearEquality(size_t j, const T& feasible, double error_gain);
|
||||
};
|
||||
|
||||
|
||||
template<POSE = {gtsam::PoseRTV}>
|
||||
virtual class IMUFactor : gtsam::NonlinearFactor {
|
||||
/** Standard constructor */
|
||||
IMUFactor(Vector accel, Vector gyro,
|
||||
double dt, size_t key1, size_t key2, const gtsam::noiseModel::Base* model);
|
||||
|
||||
/** Full IMU vector specification */
|
||||
IMUFactor(Vector imu_vector,
|
||||
double dt, size_t key1, size_t key2, const gtsam::noiseModel::Base* model);
|
||||
|
||||
Vector gyro() const;
|
||||
Vector accel() const;
|
||||
Vector z() const;
|
||||
size_t key1() const;
|
||||
size_t key2() const;
|
||||
};
|
||||
|
||||
|
||||
template<POSE = {gtsam::PoseRTV}>
|
||||
virtual class FullIMUFactor : gtsam::NonlinearFactor {
|
||||
/** Standard constructor */
|
||||
FullIMUFactor(Vector accel, Vector gyro,
|
||||
double dt, size_t key1, size_t key2, const gtsam::noiseModel::Base* model);
|
||||
|
||||
/** Single IMU vector - imu = [accel, gyro] */
|
||||
FullIMUFactor(Vector imu,
|
||||
double dt, size_t key1, size_t key2, const gtsam::noiseModel::Base* model);
|
||||
|
||||
Vector gyro() const;
|
||||
Vector accel() const;
|
||||
Vector z() const;
|
||||
size_t key1() const;
|
||||
size_t key2() const;
|
||||
};
|
||||
|
||||
|
||||
#include <DynamicsPriors.h>
|
||||
virtual class DHeightPrior : gtsam::NonlinearFactor {
|
||||
DHeightPrior(size_t key, double height, const gtsam::noiseModel::Base* model);
|
||||
};
|
||||
|
||||
|
||||
#include <DynamicsPriors.h>
|
||||
virtual class DRollPrior : gtsam::NonlinearFactor {
|
||||
/** allows for explicit roll parameterization - uses canonical coordinate */
|
||||
DRollPrior(size_t key, double wx, const gtsam::noiseModel::Base* model);
|
||||
/** Forces roll to zero */
|
||||
DRollPrior(size_t key, const gtsam::noiseModel::Base* model);
|
||||
};
|
||||
|
||||
|
||||
#include <DynamicsPriors.h>
|
||||
virtual class VelocityPrior : gtsam::NonlinearFactor {
|
||||
VelocityPrior(size_t key, Vector vel, const gtsam::noiseModel::Base* model);
|
||||
};
|
||||
|
||||
|
||||
#include <DynamicsPriors.h>
|
||||
virtual class DGroundConstraint : gtsam::NonlinearFactor {
|
||||
// Primary constructor allows for variable height of the "floor"
|
||||
DGroundConstraint(size_t key, double height, const gtsam::noiseModel::Base* model);
|
||||
// Fully specify vector - use only for debugging
|
||||
DGroundConstraint(size_t key, Vector constraint, const gtsam::noiseModel::Base* model);
|
||||
};
|
||||
|
||||
|
||||
}///\namespace gtsam
|
||||
|
||||
#include <gtsam_unstable/dynamics/imuSystem.h>
|
||||
|
|
@ -84,18 +187,18 @@ class Graph {
|
|||
void print(string s) const;
|
||||
|
||||
// prior factors
|
||||
void addPrior(size_t key, const gtsam::PoseRTV& pose, const gtsam::SharedNoiseModel& noiseModel);
|
||||
void addPrior(size_t key, const gtsam::PoseRTV& pose, const gtsam::noiseModel::Base* noiseModel);
|
||||
void addConstraint(size_t key, const gtsam::PoseRTV& pose);
|
||||
void addHeightPrior(size_t key, double z, const gtsam::SharedNoiseModel& noiseModel);
|
||||
void addHeightPrior(size_t key, double z, const gtsam::noiseModel::Base* noiseModel);
|
||||
|
||||
// inertial factors
|
||||
void addFullIMUMeasurement(size_t key1, size_t key2, const Vector& accel, const Vector& gyro, double dt, const gtsam::SharedNoiseModel& noiseModel);
|
||||
void addIMUMeasurement(size_t key1, size_t key2, const Vector& accel, const Vector& gyro, double dt, const gtsam::SharedNoiseModel& noiseModel);
|
||||
void addVelocityConstraint(size_t key1, size_t key2, double dt, const gtsam::SharedNoiseModel& noiseModel);
|
||||
void addFullIMUMeasurement(size_t key1, size_t key2, const Vector& accel, const Vector& gyro, double dt, const gtsam::noiseModel::Base* noiseModel);
|
||||
void addIMUMeasurement(size_t key1, size_t key2, const Vector& accel, const Vector& gyro, double dt, const gtsam::noiseModel::Base* noiseModel);
|
||||
void addVelocityConstraint(size_t key1, size_t key2, double dt, const gtsam::noiseModel::Base* noiseModel);
|
||||
|
||||
// other measurements
|
||||
void addBetween(size_t key1, size_t key2, const gtsam::PoseRTV& z, const gtsam::SharedNoiseModel& noiseModel);
|
||||
void addRange(size_t key1, size_t key2, double z, const gtsam::SharedNoiseModel& noiseModel);
|
||||
void addBetween(size_t key1, size_t key2, const gtsam::PoseRTV& z, const gtsam::noiseModel::Base* noiseModel);
|
||||
void addRange(size_t key1, size_t key2, double z, const gtsam::noiseModel::Base* noiseModel);
|
||||
|
||||
// optimization
|
||||
imu::Values optimize(const imu::Values& init) const;
|
||||
|
|
|
|||
|
|
@ -1,37 +1,29 @@
|
|||
# Install matlab components
|
||||
if (GTSAM_BUILD_WRAP)
|
||||
if (GTSAM_INSTALL_MATLAB_TOOLBOX)
|
||||
# Utility functions
|
||||
message(STATUS "Installing Matlab Utility Functions")
|
||||
# Matlab files: *.m and *.fig
|
||||
file(GLOB matlab_utils_m "${GTSAM_SOURCE_ROOT_DIR}/matlab/*.m")
|
||||
file(GLOB matlab_utils_fig "${GTSAM_SOURCE_ROOT_DIR}/matlab/*.fig")
|
||||
set(matlab_utils ${matlab_utils_m} ${matlab_utils_fig})
|
||||
install(FILES ${matlab_utils} DESTINATION ${GTSAM_TOOLBOX_INSTALL_PATH}/gtsam)
|
||||
|
||||
# Tests
|
||||
if (GTSAM_INSTALL_MATLAB_TESTS)
|
||||
message(STATUS "Installing Matlab Toolbox Tests")
|
||||
file(GLOB matlab_tests "${GTSAM_SOURCE_ROOT_DIR}/matlab/tests/*.m")
|
||||
install(FILES ${matlab_tests} DESTINATION ${GTSAM_TOOLBOX_INSTALL_PATH}/gtsam/tests)
|
||||
endif ()
|
||||
|
||||
# Examples
|
||||
if (GTSAM_INSTALL_MATLAB_EXAMPLES)
|
||||
message(STATUS "Installing Matlab Toolbox Examples")
|
||||
# Matlab files: *.m and *.fig
|
||||
file(GLOB matlab_examples_m "${GTSAM_SOURCE_ROOT_DIR}/matlab/examples/*.m")
|
||||
file(GLOB matlab_examples_fig "${GTSAM_SOURCE_ROOT_DIR}/matlab/examples/*.fig")
|
||||
set(matlab_examples ${matlab_examples_m} ${matlab_examples_fig})
|
||||
install(FILES ${matlab_examples} DESTINATION ${GTSAM_TOOLBOX_INSTALL_PATH}/gtsam/examples)
|
||||
|
||||
message(STATUS "Installing Matlab Toolbox Examples (Data)")
|
||||
# Data files: *.graph and *.txt
|
||||
file(GLOB matlab_examples_data_graph "${GTSAM_SOURCE_ROOT_DIR}/examples/Data/*.graph")
|
||||
file(GLOB matlab_examples_data_txt "${GTSAM_SOURCE_ROOT_DIR}/examples/Data/*.txt")
|
||||
set(matlab_examples_data ${matlab_examples_data_graph} ${matlab_examples_data_txt})
|
||||
install(FILES ${matlab_examples_data} DESTINATION ${GTSAM_TOOLBOX_INSTALL_PATH}/gtsam/Data)
|
||||
endif ()
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# Utility functions
|
||||
message(STATUS "Installing Matlab Utility Functions")
|
||||
# Matlab files: *.m and *.fig
|
||||
file(GLOB matlab_utils_m "${GTSAM_SOURCE_ROOT_DIR}/matlab/*.m")
|
||||
file(GLOB matlab_utils_fig "${GTSAM_SOURCE_ROOT_DIR}/matlab/*.fig")
|
||||
set(matlab_utils ${matlab_utils_m} ${matlab_utils_fig})
|
||||
install(FILES ${matlab_utils} DESTINATION ${GTSAM_TOOLBOX_INSTALL_PATH}/gtsam)
|
||||
|
||||
# Tests
|
||||
message(STATUS "Installing Matlab Toolbox Tests")
|
||||
file(GLOB matlab_tests "${GTSAM_SOURCE_ROOT_DIR}/matlab/tests/*.m")
|
||||
install(FILES ${matlab_tests} DESTINATION ${GTSAM_TOOLBOX_INSTALL_PATH}/gtsam/tests)
|
||||
|
||||
# Examples
|
||||
message(STATUS "Installing Matlab Toolbox Examples")
|
||||
# Matlab files: *.m and *.fig
|
||||
file(GLOB matlab_examples_m "${GTSAM_SOURCE_ROOT_DIR}/matlab/examples/*.m")
|
||||
file(GLOB matlab_examples_fig "${GTSAM_SOURCE_ROOT_DIR}/matlab/examples/*.fig")
|
||||
set(matlab_examples ${matlab_examples_m} ${matlab_examples_fig})
|
||||
install(FILES ${matlab_examples} DESTINATION ${GTSAM_TOOLBOX_INSTALL_PATH}/gtsam/examples)
|
||||
|
||||
message(STATUS "Installing Matlab Toolbox Examples (Data)")
|
||||
# Data files: *.graph and *.txt
|
||||
file(GLOB matlab_examples_data_graph "${GTSAM_SOURCE_ROOT_DIR}/examples/Data/*.graph")
|
||||
file(GLOB matlab_examples_data_txt "${GTSAM_SOURCE_ROOT_DIR}/examples/Data/*.txt")
|
||||
set(matlab_examples_data ${matlab_examples_data_graph} ${matlab_examples_data_txt})
|
||||
install(FILES ${matlab_examples_data} DESTINATION ${GTSAM_TOOLBOX_INSTALL_PATH}/gtsam/Data)
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ data.K = truth.K;
|
|||
for i=1:options.nrCameras
|
||||
theta = (i-1)*2*pi/options.nrCameras;
|
||||
t = gtsamPoint3([r*cos(theta), r*sin(theta), height]');
|
||||
truth.cameras{i} = gtsamSimpleCamera_lookat(t, gtsamPoint3, gtsamPoint3([0,0,1]'), truth.K);
|
||||
truth.cameras{i} = gtsamSimpleCamera.Lookat(t, gtsamPoint3, gtsamPoint3([0,0,1]'), truth.K);
|
||||
% Create measurements
|
||||
for j=1:nrPoints
|
||||
% All landmarks seen in every frame
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ function [noiseModels,isam,result] = VisualISAMInitialize(data,truth,options)
|
|||
isam = visualSLAMISAM(options.reorderInterval);
|
||||
|
||||
%% Set Noise parameters
|
||||
noiseModels.pose = gtsamnoiseModelDiagonal_Sigmas([0.001 0.001 0.001 0.1 0.1 0.1]');
|
||||
noiseModels.odometry = gtsamnoiseModelDiagonal_Sigmas([0.001 0.001 0.001 0.1 0.1 0.1]');
|
||||
noiseModels.point = gtsamnoiseModelIsotropic_Sigma(3, 0.1);
|
||||
noiseModels.measurement = gtsamnoiseModelIsotropic_Sigma(2, 1.0);
|
||||
noiseModels.pose = gtsamnoiseModelDiagonal.Sigmas([0.001 0.001 0.001 0.1 0.1 0.1]');
|
||||
noiseModels.odometry = gtsamnoiseModelDiagonal.Sigmas([0.001 0.001 0.001 0.1 0.1 0.1]');
|
||||
noiseModels.point = gtsamnoiseModelIsotropic.Sigma(3, 0.1);
|
||||
noiseModels.measurement = gtsamnoiseModelIsotropic.Sigma(2, 1.0);
|
||||
|
||||
%% Add constraints/priors
|
||||
% TODO: should not be from ground truth!
|
||||
|
|
|
|||
|
|
@ -20,13 +20,13 @@ graph = pose2SLAMGraph;
|
|||
|
||||
%% Add two odometry factors
|
||||
odometry = gtsamPose2(2.0, 0.0, 0.0); % create a measurement for both factors (the same in this case)
|
||||
odometryNoise = gtsamnoiseModelDiagonal_Sigmas([0.2; 0.2; 0.1]); % 20cm std on x,y, 0.1 rad on theta
|
||||
odometryNoise = gtsamnoiseModelDiagonal.Sigmas([0.2; 0.2; 0.1]); % 20cm std on x,y, 0.1 rad on theta
|
||||
graph.addRelativePose(1, 2, odometry, odometryNoise);
|
||||
graph.addRelativePose(2, 3, odometry, odometryNoise);
|
||||
|
||||
%% Add three "GPS" measurements
|
||||
% We use Pose2 Priors here with high variance on theta
|
||||
noiseModel = gtsamnoiseModelDiagonal_Sigmas([0.1; 0.1; 10]);
|
||||
noiseModel = gtsamnoiseModelDiagonal.Sigmas([0.1; 0.1; 10]);
|
||||
graph.addPosePrior(1, gtsamPose2(0.0, 0.0, 0.0), noiseModel);
|
||||
graph.addPosePrior(2, gtsamPose2(2.0, 0.0, 0.0), noiseModel);
|
||||
graph.addPosePrior(3, gtsamPose2(4.0, 0.0, 0.0), noiseModel);
|
||||
|
|
|
|||
|
|
@ -20,12 +20,12 @@ graph = pose2SLAMGraph;
|
|||
|
||||
%% Add a Gaussian prior on pose x_1
|
||||
priorMean = gtsamPose2(0.0, 0.0, 0.0); % prior mean is at origin
|
||||
priorNoise = gtsamnoiseModelDiagonal_Sigmas([0.3; 0.3; 0.1]); % 30cm std on x,y, 0.1 rad on theta
|
||||
priorNoise = gtsamnoiseModelDiagonal.Sigmas([0.3; 0.3; 0.1]); % 30cm std on x,y, 0.1 rad on theta
|
||||
graph.addPosePrior(1, priorMean, priorNoise); % add directly to graph
|
||||
|
||||
%% Add two odometry factors
|
||||
odometry = gtsamPose2(2.0, 0.0, 0.0); % create a measurement for both factors (the same in this case)
|
||||
odometryNoise = gtsamnoiseModelDiagonal_Sigmas([0.2; 0.2; 0.1]); % 20cm std on x,y, 0.1 rad on theta
|
||||
odometryNoise = gtsamnoiseModelDiagonal.Sigmas([0.2; 0.2; 0.1]); % 20cm std on x,y, 0.1 rad on theta
|
||||
graph.addRelativePose(1, 2, odometry, odometryNoise);
|
||||
graph.addRelativePose(2, 3, odometry, odometryNoise);
|
||||
|
||||
|
|
|
|||
|
|
@ -28,18 +28,18 @@ graph = planarSLAMGraph;
|
|||
|
||||
%% Add prior
|
||||
priorMean = gtsamPose2(0.0, 0.0, 0.0); % prior at origin
|
||||
priorNoise = gtsamnoiseModelDiagonal_Sigmas([0.3; 0.3; 0.1]);
|
||||
priorNoise = gtsamnoiseModelDiagonal.Sigmas([0.3; 0.3; 0.1]);
|
||||
graph.addPosePrior(i1, priorMean, priorNoise); % add directly to graph
|
||||
|
||||
%% Add odometry
|
||||
odometry = gtsamPose2(2.0, 0.0, 0.0);
|
||||
odometryNoise = gtsamnoiseModelDiagonal_Sigmas([0.2; 0.2; 0.1]);
|
||||
odometryNoise = gtsamnoiseModelDiagonal.Sigmas([0.2; 0.2; 0.1]);
|
||||
graph.addRelativePose(i1, i2, odometry, odometryNoise);
|
||||
graph.addRelativePose(i2, i3, odometry, odometryNoise);
|
||||
|
||||
%% Add bearing/range measurement factors
|
||||
degrees = pi/180;
|
||||
noiseModel = gtsamnoiseModelDiagonal_Sigmas([0.1; 0.2]);
|
||||
noiseModel = gtsamnoiseModelDiagonal.Sigmas([0.1; 0.2]);
|
||||
graph.addBearingRange(i1, j1, gtsamRot2(45*degrees), sqrt(4+4), noiseModel);
|
||||
graph.addBearingRange(i2, j1, gtsamRot2(90*degrees), 2, noiseModel);
|
||||
graph.addBearingRange(i3, j2, gtsamRot2(90*degrees), 2, noiseModel);
|
||||
|
|
|
|||
|
|
@ -15,22 +15,22 @@
|
|||
i1 = symbol('x',1); i2 = symbol('x',2); i3 = symbol('x',3);
|
||||
graph = planarSLAMGraph;
|
||||
priorMean = gtsamPose2(0.0, 0.0, 0.0); % prior at origin
|
||||
priorNoise = gtsamnoiseModelDiagonal_Sigmas([0.3; 0.3; 0.1]);
|
||||
priorNoise = gtsamnoiseModelDiagonal.Sigmas([0.3; 0.3; 0.1]);
|
||||
graph.addPosePrior(i1, priorMean, priorNoise); % add directly to graph
|
||||
odometry = gtsamPose2(2.0, 0.0, 0.0);
|
||||
odometryNoise = gtsamnoiseModelDiagonal_Sigmas([0.2; 0.2; 0.1]);
|
||||
odometryNoise = gtsamnoiseModelDiagonal.Sigmas([0.2; 0.2; 0.1]);
|
||||
graph.addRelativePose(i1, i2, odometry, odometryNoise);
|
||||
graph.addRelativePose(i2, i3, odometry, odometryNoise);
|
||||
|
||||
%% Except, for measurements we offer a choice
|
||||
j1 = symbol('l',1); j2 = symbol('l',2);
|
||||
degrees = pi/180;
|
||||
noiseModel = gtsamnoiseModelDiagonal_Sigmas([0.1; 0.2]);
|
||||
noiseModel = gtsamnoiseModelDiagonal.Sigmas([0.1; 0.2]);
|
||||
if 1
|
||||
graph.addBearingRange(i1, j1, gtsamRot2(45*degrees), sqrt(4+4), noiseModel);
|
||||
graph.addBearingRange(i2, j1, gtsamRot2(90*degrees), 2, noiseModel);
|
||||
else
|
||||
bearingModel = gtsamnoiseModelDiagonal_Sigmas(0.1);
|
||||
bearingModel = gtsamnoiseModelDiagonal.Sigmas(0.1);
|
||||
graph.addBearing(i1, j1, gtsamRot2(45*degrees), bearingModel);
|
||||
graph.addBearing(i2, j1, gtsamRot2(90*degrees), bearingModel);
|
||||
end
|
||||
|
|
|
|||
|
|
@ -24,19 +24,19 @@ graph = pose2SLAMGraph;
|
|||
%% Add prior
|
||||
% gaussian for prior
|
||||
priorMean = gtsamPose2(0.0, 0.0, 0.0); % prior at origin
|
||||
priorNoise = gtsamnoiseModelDiagonal_Sigmas([0.3; 0.3; 0.1]);
|
||||
priorNoise = gtsamnoiseModelDiagonal.Sigmas([0.3; 0.3; 0.1]);
|
||||
graph.addPosePrior(1, priorMean, priorNoise); % add directly to graph
|
||||
|
||||
%% Add odometry
|
||||
% general noisemodel for odometry
|
||||
odometryNoise = gtsamnoiseModelDiagonal_Sigmas([0.2; 0.2; 0.1]);
|
||||
odometryNoise = gtsamnoiseModelDiagonal.Sigmas([0.2; 0.2; 0.1]);
|
||||
graph.addRelativePose(1, 2, gtsamPose2(2.0, 0.0, 0.0 ), odometryNoise);
|
||||
graph.addRelativePose(2, 3, gtsamPose2(2.0, 0.0, pi/2), odometryNoise);
|
||||
graph.addRelativePose(3, 4, gtsamPose2(2.0, 0.0, pi/2), odometryNoise);
|
||||
graph.addRelativePose(4, 5, gtsamPose2(2.0, 0.0, pi/2), odometryNoise);
|
||||
|
||||
%% Add pose constraint
|
||||
model = gtsamnoiseModelDiagonal_Sigmas([0.2; 0.2; 0.1]);
|
||||
model = gtsamnoiseModelDiagonal.Sigmas([0.2; 0.2; 0.1]);
|
||||
graph.addRelativePose(5, 2, gtsamPose2(2.0, 0.0, pi/2), model);
|
||||
|
||||
% print
|
||||
|
|
|
|||
|
|
@ -25,20 +25,20 @@ graph = pose2SLAMGraph;
|
|||
|
||||
%% Add prior
|
||||
% gaussian for prior
|
||||
priorNoise = gtsamnoiseModelDiagonal_Sigmas([0.3; 0.3; 0.1]);
|
||||
priorNoise = gtsamnoiseModelDiagonal.Sigmas([0.3; 0.3; 0.1]);
|
||||
priorMean = gtsamPose2(0.0, 0.0, 0.0); % prior at origin
|
||||
graph.addPosePrior(1, priorMean, priorNoise); % add directly to graph
|
||||
|
||||
%% Add odometry
|
||||
% general noisemodel for odometry
|
||||
odometryNoise = gtsamnoiseModelDiagonal_Sigmas([0.2; 0.2; 0.1]);
|
||||
odometryNoise = gtsamnoiseModelDiagonal.Sigmas([0.2; 0.2; 0.1]);
|
||||
odometry = gtsamPose2(2.0, 0.0, 0.0); % create a measurement for both factors (the same in this case)
|
||||
graph.addRelativePose(1, 2, odometry, odometryNoise);
|
||||
graph.addRelativePose(2, 3, odometry, odometryNoise);
|
||||
|
||||
%% Add measurements
|
||||
% general noisemodel for measurements
|
||||
measurementNoise = gtsamnoiseModelDiagonal_Sigmas([0.1; 0.2]);
|
||||
measurementNoise = gtsamnoiseModelDiagonal.Sigmas([0.1; 0.2]);
|
||||
|
||||
% print
|
||||
graph.print('full graph');
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
%% Create a hexagon of poses
|
||||
hexagon = pose2SLAMValues_Circle(6,1.0);
|
||||
hexagon = pose2SLAMValues.Circle(6,1.0);
|
||||
p0 = hexagon.pose(0);
|
||||
p1 = hexagon.pose(1);
|
||||
|
||||
|
|
@ -19,7 +19,7 @@ p1 = hexagon.pose(1);
|
|||
fg = pose2SLAMGraph;
|
||||
fg.addPoseConstraint(0, p0);
|
||||
delta = p0.between(p1);
|
||||
covariance = gtsamnoiseModelDiagonal_Sigmas([0.05; 0.05; 5*pi/180]);
|
||||
covariance = gtsamnoiseModelDiagonal.Sigmas([0.05; 0.05; 5*pi/180]);
|
||||
fg.addRelativePose(0,1, delta, covariance);
|
||||
fg.addRelativePose(1,2, delta, covariance);
|
||||
fg.addRelativePose(2,3, delta, covariance);
|
||||
|
|
|
|||
|
|
@ -11,13 +11,13 @@
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
%% Initialize graph, initial estimate, and odometry noise
|
||||
model = gtsamnoiseModelDiagonal_Sigmas([0.05; 0.05; 5*pi/180]);
|
||||
model = gtsamnoiseModelDiagonal.Sigmas([0.05; 0.05; 5*pi/180]);
|
||||
[graph,initial]=load2D('../../examples/Data/w100-odom.graph',model);
|
||||
initial.print(sprintf('Initial estimate:\n'));
|
||||
|
||||
%% Add a Gaussian prior on pose x_1
|
||||
priorMean = gtsamPose2(0.0, 0.0, 0.0); % prior mean is at origin
|
||||
priorNoise = gtsamnoiseModelDiagonal_Sigmas([0.01; 0.01; 0.01]);
|
||||
priorNoise = gtsamnoiseModelDiagonal.Sigmas([0.01; 0.01; 0.01]);
|
||||
graph.addPosePrior(0, priorMean, priorNoise); % add directly to graph
|
||||
|
||||
%% Plot Initial Estimate
|
||||
|
|
|
|||
|
|
@ -22,19 +22,19 @@ graph = pose2SLAMGraph;
|
|||
%% Add prior
|
||||
% gaussian for prior
|
||||
priorMean = gtsamPose2(0.0, 0.0, 0.0); % prior at origin
|
||||
priorNoise = gtsamnoiseModelDiagonal_Sigmas([0.3; 0.3; 0.1]);
|
||||
priorNoise = gtsamnoiseModelDiagonal.Sigmas([0.3; 0.3; 0.1]);
|
||||
graph.addPrior(1, priorMean, priorNoise); % add directly to graph
|
||||
|
||||
%% Add odometry
|
||||
% general noisemodel for odometry
|
||||
odometryNoise = gtsamnoiseModelDiagonal_Sigmas([0.2; 0.2; 0.1]);
|
||||
odometryNoise = gtsamnoiseModelDiagonal.Sigmas([0.2; 0.2; 0.1]);
|
||||
graph.addOdometry(1, 2, gtsamPose2(2.0, 0.0, 0.0 ), odometryNoise);
|
||||
graph.addOdometry(2, 3, gtsamPose2(2.0, 0.0, pi/2), odometryNoise);
|
||||
graph.addOdometry(3, 4, gtsamPose2(2.0, 0.0, pi/2), odometryNoise);
|
||||
graph.addOdometry(4, 5, gtsamPose2(2.0, 0.0, pi/2), odometryNoise);
|
||||
|
||||
%% Add pose constraint
|
||||
model = gtsamnoiseModelDiagonal_Sigmas([0.2; 0.2; 0.1]);
|
||||
model = gtsamnoiseModelDiagonal.Sigmas([0.2; 0.2; 0.1]);
|
||||
graph.addRelativePose(5, 2, gtsamPose2(2.0, 0.0, pi/2), model);
|
||||
|
||||
% print
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
%% Create a hexagon of poses
|
||||
hexagon = pose3SLAMValues_Circle(6,1.0);
|
||||
hexagon = pose3SLAMValues.Circle(6,1.0);
|
||||
p0 = hexagon.pose(0);
|
||||
p1 = hexagon.pose(1);
|
||||
|
||||
|
|
@ -19,7 +19,7 @@ p1 = hexagon.pose(1);
|
|||
fg = pose3SLAMGraph;
|
||||
fg.addPoseConstraint(0, p0);
|
||||
delta = p0.between(p1);
|
||||
covariance = gtsamnoiseModelDiagonal_Sigmas([0.05; 0.05; 0.05; 5*pi/180; 5*pi/180; 5*pi/180]);
|
||||
covariance = gtsamnoiseModelDiagonal.Sigmas([0.05; 0.05; 0.05; 5*pi/180; 5*pi/180; 5*pi/180]);
|
||||
fg.addRelativePose(0,1, delta, covariance);
|
||||
fg.addRelativePose(1,2, delta, covariance);
|
||||
fg.addRelativePose(2,3, delta, covariance);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ N = 2500;
|
|||
filename = '../../examples/Data/sphere2500.txt';
|
||||
|
||||
%% Initialize graph, initial estimate, and odometry noise
|
||||
model = gtsamnoiseModelDiagonal_Sigmas([0.05; 0.05; 0.05; 5*pi/180; 5*pi/180; 5*pi/180]);
|
||||
model = gtsamnoiseModelDiagonal.Sigmas([0.05; 0.05; 0.05; 5*pi/180; 5*pi/180; 5*pi/180]);
|
||||
[graph,initial]=load3D(filename,model,true,N);
|
||||
|
||||
%% Plot Initial Estimate
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ graph = sparseBAGraph;
|
|||
|
||||
|
||||
%% Add factors for all measurements
|
||||
measurementNoise = gtsamnoiseModelIsotropic_Sigma(2,measurementNoiseSigma);
|
||||
measurementNoise = gtsamnoiseModelIsotropic.Sigma(2,measurementNoiseSigma);
|
||||
for i=1:length(data.Z)
|
||||
for k=1:length(data.Z{i})
|
||||
j = data.J{i}{k};
|
||||
|
|
@ -43,11 +43,11 @@ for i=1:length(data.Z)
|
|||
end
|
||||
|
||||
%% Add Gaussian priors for a pose and a landmark to constrain the system
|
||||
cameraPriorNoise = gtsamnoiseModelDiagonal_Sigmas(cameraNoiseSigmas);
|
||||
cameraPriorNoise = gtsamnoiseModelDiagonal.Sigmas(cameraNoiseSigmas);
|
||||
firstCamera = gtsamSimpleCamera(truth.cameras{1}.pose, truth.K);
|
||||
graph.addSimpleCameraPrior(symbol('c',1), firstCamera, cameraPriorNoise);
|
||||
|
||||
pointPriorNoise = gtsamnoiseModelIsotropic_Sigma(3,pointNoiseSigma);
|
||||
pointPriorNoise = gtsamnoiseModelIsotropic.Sigma(3,pointNoiseSigma);
|
||||
graph.addPointPrior(symbol('p',1), truth.points{1}, pointPriorNoise);
|
||||
|
||||
%% Print the graph
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ poseNoiseSigmas = [0.001 0.001 0.001 0.1 0.1 0.1]';
|
|||
graph = visualSLAMGraph;
|
||||
|
||||
%% Add factors for all measurements
|
||||
measurementNoise = gtsamnoiseModelIsotropic_Sigma(2,measurementNoiseSigma);
|
||||
measurementNoise = gtsamnoiseModelIsotropic.Sigma(2,measurementNoiseSigma);
|
||||
for i=1:length(data.Z)
|
||||
for k=1:length(data.Z{i})
|
||||
j = data.J{i}{k};
|
||||
|
|
@ -41,9 +41,9 @@ for i=1:length(data.Z)
|
|||
end
|
||||
|
||||
%% Add Gaussian priors for a pose and a landmark to constrain the system
|
||||
posePriorNoise = gtsamnoiseModelDiagonal_Sigmas(poseNoiseSigmas);
|
||||
posePriorNoise = gtsamnoiseModelDiagonal.Sigmas(poseNoiseSigmas);
|
||||
graph.addPosePrior(symbol('x',1), truth.cameras{1}.pose, posePriorNoise);
|
||||
pointPriorNoise = gtsamnoiseModelIsotropic_Sigma(3,pointNoiseSigma);
|
||||
pointPriorNoise = gtsamnoiseModelIsotropic.Sigma(3,pointNoiseSigma);
|
||||
graph.addPointPrior(symbol('p',1), truth.points{1}, pointPriorNoise);
|
||||
|
||||
%% Print the graph
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ graph.addPoseConstraint(x1, first_pose);
|
|||
%% Create realistic calibration and measurement noise model
|
||||
% format: fx fy skew cx cy baseline
|
||||
K = gtsamCal3_S2Stereo(1000, 1000, 0, 320, 240, 0.2);
|
||||
stereo_model = gtsamnoiseModelDiagonal_Sigmas([1.0; 1.0; 1.0]);
|
||||
stereo_model = gtsamnoiseModelDiagonal.Sigmas([1.0; 1.0; 1.0]);
|
||||
|
||||
%% Add measurements
|
||||
% pose 1
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
% format: fx fy skew cx cy baseline
|
||||
calib = dlmread('../../examples/Data/VO_calibration.txt');
|
||||
K = gtsamCal3_S2Stereo(calib(1), calib(2), calib(3), calib(4), calib(5), calib(6));
|
||||
stereo_model = gtsamnoiseModelDiagonal_Sigmas([1.0; 1.0; 1.0]);
|
||||
stereo_model = gtsamnoiseModelDiagonal.Sigmas([1.0; 1.0; 1.0]);
|
||||
|
||||
%% create empty graph and values
|
||||
graph = visualSLAMGraph;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ for i=1:n
|
|||
i=v{2};
|
||||
if (~successive & i<N | successive & i==0)
|
||||
t = gtsamPoint3(v{3}, v{4}, v{5});
|
||||
R = gtsamRot3_ypr(v{8}, -v{7}, v{6});
|
||||
R = gtsamRot3.Ypr(v{8}, -v{7}, v{6});
|
||||
initial.insertPose(i, gtsamPose3(R,t));
|
||||
end
|
||||
elseif strcmp('EDGE3',line_i(1:5))
|
||||
|
|
@ -39,7 +39,7 @@ for i=1:n
|
|||
if i1<N & i2<N
|
||||
if ~successive | abs(i2-i1)==1
|
||||
t = gtsamPoint3(e{4}, e{5}, e{6});
|
||||
R = gtsamRot3_ypr(e{9}, e{8}, e{7});
|
||||
R = gtsamRot3.Ypr(e{9}, e{8}, e{7});
|
||||
dpose = gtsamPose3(R,t);
|
||||
graph.addRelativePose(i1, i2, dpose, model);
|
||||
if successive
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ x1 = 3;
|
|||
% the RHS
|
||||
b2=[-1;1.5;2;-1];
|
||||
sigmas = [1;1;1;1];
|
||||
model4 = gtsamnoiseModelDiagonal_Sigmas(sigmas);
|
||||
model4 = gtsamnoiseModelDiagonal.Sigmas(sigmas);
|
||||
combined = gtsamJacobianFactor(x2, Ax2, l1, Al1, x1, Ax1, b2, model4);
|
||||
|
||||
% eliminate the first variable (x2) in the combined factor, destructive !
|
||||
|
|
@ -69,7 +69,7 @@ Bx1 = [
|
|||
% the RHS
|
||||
b1= [0.0;0.894427];
|
||||
|
||||
model2 = gtsamnoiseModelDiagonal_Sigmas([1;1]);
|
||||
model2 = gtsamnoiseModelDiagonal.Sigmas([1;1]);
|
||||
expectedLF = gtsamJacobianFactor(l1, Bl1, x1, Bx1, b1, model2);
|
||||
|
||||
% check if the result matches the combined (reduced) factor
|
||||
|
|
|
|||
|
|
@ -22,13 +22,13 @@
|
|||
F = eye(2,2);
|
||||
B = eye(2,2);
|
||||
u = [1.0; 0.0];
|
||||
modelQ = gtsamnoiseModelDiagonal_Sigmas([0.1;0.1]);
|
||||
modelQ = gtsamnoiseModelDiagonal.Sigmas([0.1;0.1]);
|
||||
Q = 0.01*eye(2,2);
|
||||
H = eye(2,2);
|
||||
z1 = [1.0, 0.0]';
|
||||
z2 = [2.0, 0.0]';
|
||||
z3 = [3.0, 0.0]';
|
||||
modelR = gtsamnoiseModelDiagonal_Sigmas([0.1;0.1]);
|
||||
modelR = gtsamnoiseModelDiagonal.Sigmas([0.1;0.1]);
|
||||
R = 0.01*eye(2,2);
|
||||
|
||||
%% Create the set of expected output TestValues
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ graph = pose2SLAMGraph;
|
|||
|
||||
%% Add two odometry factors
|
||||
odometry = gtsamPose2(2.0, 0.0, 0.0); % create a measurement for both factors (the same in this case)
|
||||
odometryNoise = gtsamnoiseModelDiagonal_Sigmas([0.2; 0.2; 0.1]); % 20cm std on x,y, 0.1 rad on theta
|
||||
odometryNoise = gtsamnoiseModelDiagonal.Sigmas([0.2; 0.2; 0.1]); % 20cm std on x,y, 0.1 rad on theta
|
||||
graph.addRelativePose(1, 2, odometry, odometryNoise);
|
||||
graph.addRelativePose(2, 3, odometry, odometryNoise);
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ groundTruth = pose2SLAMValues;
|
|||
groundTruth.insertPose(1, gtsamPose2(0.0, 0.0, 0.0));
|
||||
groundTruth.insertPose(2, gtsamPose2(2.0, 0.0, 0.0));
|
||||
groundTruth.insertPose(3, gtsamPose2(4.0, 0.0, 0.0));
|
||||
noiseModel = gtsamnoiseModelDiagonal_Sigmas([0.1; 0.1; 10]);
|
||||
noiseModel = gtsamnoiseModelDiagonal.Sigmas([0.1; 0.1; 10]);
|
||||
for i=1:3
|
||||
graph.addPosePrior(i, groundTruth.pose(i), noiseModel);
|
||||
end
|
||||
|
|
|
|||
|
|
@ -15,12 +15,12 @@ graph = pose2SLAMGraph;
|
|||
|
||||
%% Add a Gaussian prior on pose x_1
|
||||
priorMean = gtsamPose2(0.0, 0.0, 0.0); % prior mean is at origin
|
||||
priorNoise = gtsamnoiseModelDiagonal_Sigmas([0.3; 0.3; 0.1]); % 30cm std on x,y, 0.1 rad on theta
|
||||
priorNoise = gtsamnoiseModelDiagonal.Sigmas([0.3; 0.3; 0.1]); % 30cm std on x,y, 0.1 rad on theta
|
||||
graph.addPosePrior(1, priorMean, priorNoise); % add directly to graph
|
||||
|
||||
%% Add two odometry factors
|
||||
odometry = gtsamPose2(2.0, 0.0, 0.0); % create a measurement for both factors (the same in this case)
|
||||
odometryNoise = gtsamnoiseModelDiagonal_Sigmas([0.2; 0.2; 0.1]); % 20cm std on x,y, 0.1 rad on theta
|
||||
odometryNoise = gtsamnoiseModelDiagonal.Sigmas([0.2; 0.2; 0.1]); % 20cm std on x,y, 0.1 rad on theta
|
||||
graph.addRelativePose(1, 2, odometry, odometryNoise);
|
||||
graph.addRelativePose(2, 3, odometry, odometryNoise);
|
||||
|
||||
|
|
|
|||
|
|
@ -28,18 +28,18 @@ graph = planarSLAMGraph;
|
|||
|
||||
%% Add prior
|
||||
priorMean = gtsamPose2(0.0, 0.0, 0.0); % prior at origin
|
||||
priorNoise = gtsamnoiseModelDiagonal_Sigmas([0.3; 0.3; 0.1]);
|
||||
priorNoise = gtsamnoiseModelDiagonal.Sigmas([0.3; 0.3; 0.1]);
|
||||
graph.addPosePrior(i1, priorMean, priorNoise); % add directly to graph
|
||||
|
||||
%% Add odometry
|
||||
odometry = gtsamPose2(2.0, 0.0, 0.0);
|
||||
odometryNoise = gtsamnoiseModelDiagonal_Sigmas([0.2; 0.2; 0.1]);
|
||||
odometryNoise = gtsamnoiseModelDiagonal.Sigmas([0.2; 0.2; 0.1]);
|
||||
graph.addRelativePose(i1, i2, odometry, odometryNoise);
|
||||
graph.addRelativePose(i2, i3, odometry, odometryNoise);
|
||||
|
||||
%% Add bearing/range measurement factors
|
||||
degrees = pi/180;
|
||||
noiseModel = gtsamnoiseModelDiagonal_Sigmas([0.1; 0.2]);
|
||||
noiseModel = gtsamnoiseModelDiagonal.Sigmas([0.1; 0.2]);
|
||||
graph.addBearingRange(i1, j1, gtsamRot2(45*degrees), sqrt(4+4), noiseModel);
|
||||
graph.addBearingRange(i2, j1, gtsamRot2(90*degrees), 2, noiseModel);
|
||||
graph.addBearingRange(i3, j2, gtsamRot2(90*degrees), 2, noiseModel);
|
||||
|
|
|
|||
|
|
@ -24,19 +24,19 @@ graph = pose2SLAMGraph;
|
|||
%% Add prior
|
||||
% gaussian for prior
|
||||
priorMean = gtsamPose2(0.0, 0.0, 0.0); % prior at origin
|
||||
priorNoise = gtsamnoiseModelDiagonal_Sigmas([0.3; 0.3; 0.1]);
|
||||
priorNoise = gtsamnoiseModelDiagonal.Sigmas([0.3; 0.3; 0.1]);
|
||||
graph.addPosePrior(1, priorMean, priorNoise); % add directly to graph
|
||||
|
||||
%% Add odometry
|
||||
% general noisemodel for odometry
|
||||
odometryNoise = gtsamnoiseModelDiagonal_Sigmas([0.2; 0.2; 0.1]);
|
||||
odometryNoise = gtsamnoiseModelDiagonal.Sigmas([0.2; 0.2; 0.1]);
|
||||
graph.addRelativePose(1, 2, gtsamPose2(2.0, 0.0, 0.0 ), odometryNoise);
|
||||
graph.addRelativePose(2, 3, gtsamPose2(2.0, 0.0, pi/2), odometryNoise);
|
||||
graph.addRelativePose(3, 4, gtsamPose2(2.0, 0.0, pi/2), odometryNoise);
|
||||
graph.addRelativePose(4, 5, gtsamPose2(2.0, 0.0, pi/2), odometryNoise);
|
||||
|
||||
%% Add pose constraint
|
||||
model = gtsamnoiseModelDiagonal_Sigmas([0.2; 0.2; 0.1]);
|
||||
model = gtsamnoiseModelDiagonal.Sigmas([0.2; 0.2; 0.1]);
|
||||
graph.addRelativePose(5, 2, gtsamPose2(2.0, 0.0, pi/2), model);
|
||||
|
||||
%% Initialize to noisy points
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
%% Create a hexagon of poses
|
||||
hexagon = pose3SLAMValues_Circle(6,1.0);
|
||||
hexagon = pose3SLAMValues.Circle(6,1.0);
|
||||
p0 = hexagon.pose(0);
|
||||
p1 = hexagon.pose(1);
|
||||
|
||||
|
|
@ -19,7 +19,7 @@ p1 = hexagon.pose(1);
|
|||
fg = pose3SLAMGraph;
|
||||
fg.addPoseConstraint(0, p0);
|
||||
delta = p0.between(p1);
|
||||
covariance = gtsamnoiseModelDiagonal_Sigmas([0.05; 0.05; 0.05; 5*pi/180; 5*pi/180; 5*pi/180]);
|
||||
covariance = gtsamnoiseModelDiagonal.Sigmas([0.05; 0.05; 0.05; 5*pi/180; 5*pi/180; 5*pi/180]);
|
||||
fg.addRelativePose(0,1, delta, covariance);
|
||||
fg.addRelativePose(1,2, delta, covariance);
|
||||
fg.addRelativePose(2,3, delta, covariance);
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ poseNoiseSigmas = [0.001 0.001 0.001 0.1 0.1 0.1]';
|
|||
graph = visualSLAMGraph;
|
||||
|
||||
%% Add factors for all measurements
|
||||
measurementNoise = gtsamnoiseModelIsotropic_Sigma(2,measurementNoiseSigma);
|
||||
measurementNoise = gtsamnoiseModelIsotropic.Sigma(2,measurementNoiseSigma);
|
||||
for i=1:length(data.Z)
|
||||
for k=1:length(data.Z{i})
|
||||
j = data.J{i}{k};
|
||||
|
|
@ -31,9 +31,9 @@ for i=1:length(data.Z)
|
|||
end
|
||||
end
|
||||
|
||||
posePriorNoise = gtsamnoiseModelDiagonal_Sigmas(poseNoiseSigmas);
|
||||
posePriorNoise = gtsamnoiseModelDiagonal.Sigmas(poseNoiseSigmas);
|
||||
graph.addPosePrior(symbol('x',1), truth.cameras{1}.pose, posePriorNoise);
|
||||
pointPriorNoise = gtsamnoiseModelIsotropic_Sigma(3,pointNoiseSigma);
|
||||
pointPriorNoise = gtsamnoiseModelIsotropic.Sigma(3,pointNoiseSigma);
|
||||
graph.addPointPrior(symbol('p',1), truth.points{1}, pointPriorNoise);
|
||||
|
||||
%% Initial estimate
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ graph.addPoseConstraint(x1, first_pose);
|
|||
%% Create realistic calibration and measurement noise model
|
||||
% format: fx fy skew cx cy baseline
|
||||
K = gtsamCal3_S2Stereo(1000, 1000, 0, 320, 240, 0.2);
|
||||
stereo_model = gtsamnoiseModelDiagonal_Sigmas([1.0; 1.0; 1.0]);
|
||||
stereo_model = gtsamnoiseModelDiagonal.Sigmas([1.0; 1.0; 1.0]);
|
||||
|
||||
%% Add measurements
|
||||
% pose 1
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* @file Argument.ccp
|
||||
* @author Frank Dellaert
|
||||
* @author Andrew Melim
|
||||
* @author Richard Roberts
|
||||
**/
|
||||
|
||||
#include <iostream>
|
||||
|
|
@ -64,7 +65,7 @@ void Argument::matlab_unwrap(FileWriter& file, const string& matlabName) const {
|
|||
file.oss << cppType << " " << name << " = unwrap< ";
|
||||
|
||||
file.oss << cppType << " >(" << matlabName;
|
||||
if (is_ptr || is_ref) file.oss << ", \"" << matlabType << "\"";
|
||||
if (is_ptr || is_ref) file.oss << ", \"ptr_" << matlabType << "\"";
|
||||
file.oss << ");" << endl;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
* @brief arguments to constructors and methods
|
||||
* @author Frank Dellaert
|
||||
* @author Andrew Melim
|
||||
* @author Richard Roberts
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Build/install Wrap
|
||||
|
||||
find_package(Boost 1.42 COMPONENTS system filesystem thread REQUIRED)
|
||||
set(WRAP_BOOST_LIBRARIES ${Boost_SYSTEM_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_THREAD_LIBRARY})
|
||||
|
||||
# Build the executable itself
|
||||
file(GLOB wrap_srcs "*.cpp")
|
||||
|
|
@ -9,19 +9,21 @@ list(REMOVE_ITEM wrap_srcs ${CMAKE_CURRENT_SOURCE_DIR}/wrap.cpp)
|
|||
add_library(wrap_lib STATIC ${wrap_srcs} ${wrap_headers})
|
||||
gtsam_assign_source_folders(${wrap_srcs} ${wrap_headers})
|
||||
add_executable(wrap wrap.cpp)
|
||||
target_link_libraries(wrap wrap_lib ${Boost_SYSTEM_LIBRARY} ${Boost_FILESYSTEM_LIBRARY})
|
||||
target_link_libraries(wrap wrap_lib ${WRAP_BOOST_LIBRARIES})
|
||||
|
||||
# Install wrap binary
|
||||
# Install wrap binary and export target
|
||||
if (GTSAM_INSTALL_WRAP)
|
||||
install(TARGETS wrap DESTINATION bin)
|
||||
install(TARGETS wrap EXPORT GTSAM-exports DESTINATION bin)
|
||||
list(APPEND GTSAM_EXPORTED_TARGETS wrap)
|
||||
set(GTSAM_EXPORTED_TARGETS "${GTSAM_EXPORTED_TARGETS}" PARENT_SCOPE)
|
||||
endif(GTSAM_INSTALL_WRAP)
|
||||
|
||||
# Install matlab header
|
||||
install(FILES matlab.h DESTINATION include/wrap)
|
||||
|
||||
# Build tests
|
||||
if (GTSAM_BUILD_TESTS)
|
||||
set(wrap_local_libs wrap_lib ${Boost_SYSTEM_LIBRARY} ${Boost_FILESYSTEM_LIBRARY})
|
||||
if (GTSAM_BUILD_TESTS)
|
||||
set(wrap_local_libs wrap_lib ${WRAP_BOOST_LIBRARIES})
|
||||
gtsam_add_subdir_tests("wrap" "${wrap_local_libs}" "${wrap_local_libs}" "")
|
||||
endif(GTSAM_BUILD_TESTS)
|
||||
|
||||
|
|
|
|||
493
wrap/Class.cpp
493
wrap/Class.cpp
|
|
@ -1,176 +1,317 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
|
||||
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||
* Atlanta, Georgia 30332-0415
|
||||
* All Rights Reserved
|
||||
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
|
||||
|
||||
* See LICENSE for the license information
|
||||
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @file Class.cpp
|
||||
* @author Frank Dellaert
|
||||
* @author Andrew Melim
|
||||
**/
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "Class.h"
|
||||
#include "utilities.h"
|
||||
#include "Argument.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace wrap;
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Class::matlab_proxy(const string& classFile) const {
|
||||
// open destination classFile
|
||||
FileWriter file(classFile, verbose_, "%");
|
||||
|
||||
// get the name of actual matlab object
|
||||
string matlabName = qualifiedName();
|
||||
|
||||
// emit class proxy code
|
||||
// we want our class to inherit the handle class for memory purposes
|
||||
file.oss << "classdef " << matlabName << " < handle" << endl;
|
||||
file.oss << " properties" << endl;
|
||||
file.oss << " self = 0" << endl;
|
||||
file.oss << " end" << endl;
|
||||
file.oss << " methods" << endl;
|
||||
// constructor
|
||||
file.oss << " function obj = " << matlabName << "(varargin)" << endl;
|
||||
//i is constructor id
|
||||
int id = 0;
|
||||
BOOST_FOREACH(ArgumentList a, constructor.args_list)
|
||||
{
|
||||
constructor.matlab_proxy_fragment(file,matlabName, id, a);
|
||||
id++;
|
||||
}
|
||||
//Static constructor collect call
|
||||
file.oss << " if nargin ==14, new_" << matlabName << "(varargin{1},0); end" << endl;
|
||||
file.oss << " if nargin ~= 13 && nargin ~= 14 && obj.self == 0, error('" << matlabName << " constructor failed'); end" << endl;
|
||||
file.oss << " end" << endl;
|
||||
// deconstructor
|
||||
file.oss << " function delete(obj)" << endl;
|
||||
file.oss << " if obj.self ~= 0" << endl;
|
||||
//TODO: Add verbosity flag
|
||||
//file.oss << " fprintf(1,'MATLAB class deleting %x',obj.self);" << endl;
|
||||
file.oss << " new_" << matlabName << "(obj.self);" << endl;
|
||||
file.oss << " obj.self = 0;" << endl;
|
||||
file.oss << " end" << endl;
|
||||
file.oss << " end" << endl;
|
||||
file.oss << " function display(obj), obj.print(''); end" << endl;
|
||||
file.oss << " function disp(obj), obj.display; end" << endl;
|
||||
file.oss << " end" << endl;
|
||||
file.oss << "end" << endl;
|
||||
|
||||
// close file
|
||||
file.emit(true);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
//TODO: Consolidate into single file
|
||||
void Class::matlab_constructors(const string& toolboxPath) const {
|
||||
/*BOOST_FOREACH(Constructor c, constructors) {
|
||||
args_list.push_back(c.args);
|
||||
}*/
|
||||
|
||||
BOOST_FOREACH(ArgumentList a, constructor.args_list) {
|
||||
constructor.matlab_mfile(toolboxPath, qualifiedName(), a);
|
||||
}
|
||||
constructor.matlab_wrapper(toolboxPath, qualifiedName("::"), qualifiedName(),
|
||||
using_namespaces, includes);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Class::matlab_methods(const string& classPath) const {
|
||||
string matlabName = qualifiedName(), cppName = qualifiedName("::");
|
||||
BOOST_FOREACH(Method m, methods) {
|
||||
m.matlab_mfile (classPath);
|
||||
m.matlab_wrapper(classPath, name, cppName, matlabName, using_namespaces, includes);
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Class::matlab_static_methods(const string& toolboxPath) const {
|
||||
string matlabName = qualifiedName(), cppName = qualifiedName("::");
|
||||
BOOST_FOREACH(const StaticMethod& m, static_methods) {
|
||||
m.matlab_mfile (toolboxPath, qualifiedName());
|
||||
m.matlab_wrapper(toolboxPath, name, matlabName, cppName, using_namespaces, includes);
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Class::matlab_make_fragment(FileWriter& file,
|
||||
const string& toolboxPath,
|
||||
const string& mexFlags) const {
|
||||
string mex = "mex " + mexFlags + " ";
|
||||
string matlabClassName = qualifiedName();
|
||||
file.oss << mex << constructor.matlab_wrapper_name(matlabClassName) << ".cpp" << endl;
|
||||
BOOST_FOREACH(StaticMethod sm, static_methods)
|
||||
file.oss << mex << matlabClassName + "_" + sm.name << ".cpp" << endl;
|
||||
file.oss << endl << "cd @" << matlabClassName << endl;
|
||||
BOOST_FOREACH(Method m, methods)
|
||||
file.oss << mex << m.name << ".cpp" << endl;
|
||||
file.oss << endl;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Class::makefile_fragment(FileWriter& file) const {
|
||||
// new_Point2_.$(MEXENDING): new_Point2_.cpp
|
||||
// $(MEX) $(mex_flags) new_Point2_.cpp
|
||||
// new_Point2_dd.$(MEXENDING): new_Point2_dd.cpp
|
||||
// $(MEX) $(mex_flags) new_Point2_dd.cpp
|
||||
// @Point2/x.$(MEXENDING): @Point2/x.cpp
|
||||
// $(MEX) $(mex_flags) @Point2/x.cpp -output @Point2/x
|
||||
// @Point2/y.$(MEXENDING): @Point2/y.cpp
|
||||
// $(MEX) $(mex_flags) @Point2/y.cpp -output @Point2/y
|
||||
// @Point2/dim.$(MEXENDING): @Point2/dim.cpp
|
||||
// $(MEX) $(mex_flags) @Point2/dim.cpp -output @Point2/dim
|
||||
//
|
||||
// Point2: new_Point2_.$(MEXENDING) new_Point2_dd.$(MEXENDING) @Point2/x.$(MEXENDING) @Point2/y.$(MEXENDING) @Point2/dim.$(MEXENDING)
|
||||
|
||||
string matlabName = qualifiedName();
|
||||
|
||||
// collect names
|
||||
vector<string> file_names;
|
||||
string file_base = constructor.matlab_wrapper_name(matlabName);
|
||||
file_names.push_back(file_base);
|
||||
BOOST_FOREACH(StaticMethod c, static_methods) {
|
||||
string file_base = matlabName + "_" + c.name;
|
||||
file_names.push_back(file_base);
|
||||
}
|
||||
BOOST_FOREACH(Method c, methods) {
|
||||
string file_base = "@" + matlabName + "/" + c.name;
|
||||
file_names.push_back(file_base);
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const string& file_base, file_names) {
|
||||
file.oss << file_base << ".$(MEXENDING): " << file_base << ".cpp";
|
||||
file.oss << " $(PATH_TO_WRAP)/matlab.h" << endl;
|
||||
file.oss << "\t$(MEX) $(mex_flags) " << file_base << ".cpp -output " << file_base << endl;
|
||||
}
|
||||
|
||||
// class target
|
||||
file.oss << "\n" << matlabName << ": ";
|
||||
BOOST_FOREACH(const string& file_base, file_names) {
|
||||
file.oss << file_base << ".$(MEXENDING) ";
|
||||
}
|
||||
file.oss << "\n" << endl;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
string Class::qualifiedName(const string& delim) const {
|
||||
string result;
|
||||
BOOST_FOREACH(const string& ns, namespaces)
|
||||
result += ns + delim;
|
||||
return result + name;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
/* ----------------------------------------------------------------------------
|
||||
|
||||
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||
* Atlanta, Georgia 30332-0415
|
||||
* All Rights Reserved
|
||||
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
|
||||
|
||||
* See LICENSE for the license information
|
||||
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @file Class.cpp
|
||||
* @author Frank Dellaert
|
||||
* @author Andrew Melim
|
||||
* @author Richard Roberts
|
||||
**/
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
//#include <cstdint> // on Linux GCC: fails with error regarding needing C++0x std flags
|
||||
//#include <cinttypes> // same failure as above
|
||||
#include <stdint.h> // works on Linux GCC
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "Class.h"
|
||||
#include "utilities.h"
|
||||
#include "Argument.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace wrap;
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Class::matlab_proxy(const string& classFile, const string& wrapperName,
|
||||
const TypeAttributesTable& typeAttributes,
|
||||
FileWriter& wrapperFile, vector<string>& functionNames) const {
|
||||
// open destination classFile
|
||||
FileWriter proxyFile(classFile, verbose_, "%");
|
||||
|
||||
// get the name of actual matlab object
|
||||
const string matlabName = qualifiedName(), cppName = qualifiedName("::");
|
||||
const string matlabBaseName = wrap::qualifiedName("", qualifiedParent);
|
||||
const string cppBaseName = wrap::qualifiedName("::", qualifiedParent);
|
||||
|
||||
// emit class proxy code
|
||||
// we want our class to inherit the handle class for memory purposes
|
||||
const string parent = qualifiedParent.empty() ?
|
||||
"handle" : ::wrap::qualifiedName("", qualifiedParent);
|
||||
proxyFile.oss << "classdef " << matlabName << " < " << parent << endl;
|
||||
proxyFile.oss << " properties" << endl;
|
||||
proxyFile.oss << " ptr_" << matlabName << " = 0" << endl;
|
||||
proxyFile.oss << " end" << endl;
|
||||
proxyFile.oss << " methods" << endl;
|
||||
|
||||
// Constructor
|
||||
proxyFile.oss << " function obj = " << matlabName << "(varargin)" << endl;
|
||||
// Special pointer constructors - one in MATLAB to create an object and
|
||||
// assign a pointer returned from a C++ function. In turn this MATLAB
|
||||
// constructor calls a special C++ function that just adds the object to
|
||||
// its collector. This allows wrapped functions to return objects in
|
||||
// other wrap modules - to add these to their collectors the pointer is
|
||||
// passed from one C++ module into matlab then back into the other C++
|
||||
// module.
|
||||
pointer_constructor_fragments(proxyFile, wrapperFile, wrapperName, functionNames);
|
||||
wrapperFile.oss << "\n";
|
||||
// Regular constructors
|
||||
BOOST_FOREACH(ArgumentList a, constructor.args_list)
|
||||
{
|
||||
const int id = (int)functionNames.size();
|
||||
constructor.proxy_fragment(proxyFile, wrapperName, matlabName, matlabBaseName, id, a);
|
||||
const string wrapFunctionName = constructor.wrapper_fragment(wrapperFile,
|
||||
cppName, matlabName, cppBaseName, id, using_namespaces, a);
|
||||
wrapperFile.oss << "\n";
|
||||
functionNames.push_back(wrapFunctionName);
|
||||
}
|
||||
proxyFile.oss << " else\n";
|
||||
proxyFile.oss << " error('Arguments do not match any overload of " << matlabName << " constructor');" << endl;
|
||||
proxyFile.oss << " end\n";
|
||||
if(!qualifiedParent.empty())
|
||||
proxyFile.oss << " obj = obj@" << matlabBaseName << "(uint64(" << ptr_constructor_key << "), base_ptr);\n";
|
||||
proxyFile.oss << " obj.ptr_" << matlabName << " = my_ptr;\n";
|
||||
proxyFile.oss << " end\n\n";
|
||||
|
||||
// Deconstructor
|
||||
{
|
||||
const int id = (int)functionNames.size();
|
||||
deconstructor.proxy_fragment(proxyFile, wrapperName, matlabName, id);
|
||||
proxyFile.oss << "\n";
|
||||
const string functionName = deconstructor.wrapper_fragment(wrapperFile, cppName, matlabName, id, using_namespaces);
|
||||
wrapperFile.oss << "\n";
|
||||
functionNames.push_back(functionName);
|
||||
}
|
||||
proxyFile.oss << " function display(obj), obj.print(''); end\n\n";
|
||||
proxyFile.oss << " function disp(obj), obj.display; end\n\n";
|
||||
|
||||
// Methods
|
||||
BOOST_FOREACH(const Methods::value_type& name_m, methods) {
|
||||
const Method& m = name_m.second;
|
||||
m.proxy_wrapper_fragments(proxyFile, wrapperFile, cppName, matlabName, wrapperName, using_namespaces, typeAttributes, functionNames);
|
||||
proxyFile.oss << "\n";
|
||||
wrapperFile.oss << "\n";
|
||||
}
|
||||
|
||||
proxyFile.oss << " end\n";
|
||||
proxyFile.oss << "\n";
|
||||
proxyFile.oss << " methods(Static = true)\n";
|
||||
|
||||
// Static methods
|
||||
BOOST_FOREACH(const StaticMethods::value_type& name_m, static_methods) {
|
||||
const StaticMethod& m = name_m.second;
|
||||
m.proxy_wrapper_fragments(proxyFile, wrapperFile, cppName, matlabName, wrapperName, using_namespaces, typeAttributes, functionNames);
|
||||
proxyFile.oss << "\n";
|
||||
wrapperFile.oss << "\n";
|
||||
}
|
||||
|
||||
proxyFile.oss << " end" << endl;
|
||||
proxyFile.oss << "end" << endl;
|
||||
|
||||
// Close file
|
||||
proxyFile.emit(true);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
string Class::qualifiedName(const string& delim) const {
|
||||
return ::wrap::qualifiedName(delim, namespaces, name);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Class::pointer_constructor_fragments(FileWriter& proxyFile, FileWriter& wrapperFile, const string& wrapperName, vector<string>& functionNames) const {
|
||||
|
||||
const string matlabName = qualifiedName(), cppName = qualifiedName("::");
|
||||
const string baseMatlabName = wrap::qualifiedName("", qualifiedParent);
|
||||
const string baseCppName = wrap::qualifiedName("::", qualifiedParent);
|
||||
|
||||
const int collectorInsertId = (int)functionNames.size();
|
||||
const string collectorInsertFunctionName = matlabName + "_collectorInsertAndMakeBase_" + boost::lexical_cast<string>(collectorInsertId);
|
||||
functionNames.push_back(collectorInsertFunctionName);
|
||||
|
||||
int upcastFromVoidId;
|
||||
string upcastFromVoidFunctionName;
|
||||
if(isVirtual) {
|
||||
upcastFromVoidId = (int)functionNames.size();
|
||||
upcastFromVoidFunctionName = matlabName + "_upcastFromVoid_" + boost::lexical_cast<string>(upcastFromVoidId);
|
||||
functionNames.push_back(upcastFromVoidFunctionName);
|
||||
}
|
||||
|
||||
// MATLAB constructor that assigns pointer to matlab object then calls c++
|
||||
// function to add the object to the collector.
|
||||
if(isVirtual) {
|
||||
proxyFile.oss << " if (nargin == 2 || (nargin == 3 && strcmp(varargin{3}, 'void')))";
|
||||
} else {
|
||||
proxyFile.oss << " if nargin == 2";
|
||||
}
|
||||
proxyFile.oss << " && isa(varargin{1}, 'uint64') && varargin{1} == uint64(" << ptr_constructor_key << ")\n";
|
||||
if(isVirtual) {
|
||||
proxyFile.oss << " if nargin == 2\n";
|
||||
proxyFile.oss << " my_ptr = varargin{2};\n";
|
||||
proxyFile.oss << " else\n";
|
||||
proxyFile.oss << " my_ptr = " << wrapperName << "(" << upcastFromVoidId << ", varargin{2});\n";
|
||||
proxyFile.oss << " end\n";
|
||||
} else {
|
||||
proxyFile.oss << " my_ptr = varargin{2};\n";
|
||||
}
|
||||
if(qualifiedParent.empty()) // If this class has a base class, we'll get a base class pointer back
|
||||
proxyFile.oss << " ";
|
||||
else
|
||||
proxyFile.oss << " base_ptr = ";
|
||||
proxyFile.oss << wrapperName << "(" << collectorInsertId << ", my_ptr);\n"; // Call collector insert and get base class ptr
|
||||
|
||||
// C++ function to add pointer from MATLAB to collector. The pointer always
|
||||
// comes from a C++ return value; this mechanism allows the object to be added
|
||||
// to a collector in a different wrap module. If this class has a base class,
|
||||
// a new pointer to the base class is allocated and returned.
|
||||
wrapperFile.oss << "void " << collectorInsertFunctionName << "(int nargout, mxArray *out[], int nargin, const mxArray *in[])" << endl;
|
||||
wrapperFile.oss << "{\n";
|
||||
wrapperFile.oss << " mexAtExit(&_deleteAllObjects);\n";
|
||||
generateUsingNamespace(wrapperFile, using_namespaces);
|
||||
// Typedef boost::shared_ptr
|
||||
wrapperFile.oss << " typedef boost::shared_ptr<" << cppName << "> Shared;\n";
|
||||
wrapperFile.oss << "\n";
|
||||
// Get self pointer passed in
|
||||
wrapperFile.oss << " Shared *self = *reinterpret_cast<Shared**> (mxGetData(in[0]));\n";
|
||||
// Add to collector
|
||||
wrapperFile.oss << " collector_" << matlabName << ".insert(self);\n";
|
||||
// If we have a base class, return the base class pointer (MATLAB will call the base class collectorInsertAndMakeBase to add this to the collector and recurse the heirarchy)
|
||||
if(!qualifiedParent.empty()) {
|
||||
wrapperFile.oss << "\n";
|
||||
wrapperFile.oss << " typedef boost::shared_ptr<" << baseCppName << "> SharedBase;\n";
|
||||
wrapperFile.oss << " out[0] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL);\n";
|
||||
wrapperFile.oss << " *reinterpret_cast<SharedBase**>(mxGetData(out[0])) = new SharedBase(*self);\n";
|
||||
}
|
||||
wrapperFile.oss << "}\n";
|
||||
|
||||
// If this is a virtual function, C++ function to dynamic upcast it from a
|
||||
// shared_ptr<void>. This mechanism allows automatic dynamic creation of the
|
||||
// real underlying derived-most class when a C++ method returns a virtual
|
||||
// base class.
|
||||
if(isVirtual)
|
||||
wrapperFile.oss <<
|
||||
"\n"
|
||||
"void " << upcastFromVoidFunctionName << "(int nargout, mxArray *out[], int nargin, const mxArray *in[]) {\n"
|
||||
" mexAtExit(&_deleteAllObjects);\n"
|
||||
" typedef boost::shared_ptr<" << cppName << "> Shared;\n"
|
||||
" boost::shared_ptr<void> *asVoid = *reinterpret_cast<boost::shared_ptr<void>**> (mxGetData(in[0]));\n"
|
||||
" out[0] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL);\n"
|
||||
" Shared *self = new Shared(boost::static_pointer_cast<" << cppName << ">(*asVoid));\n"
|
||||
" *reinterpret_cast<Shared**>(mxGetData(out[0])) = self;\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
vector<ArgumentList> expandArgumentListsTemplate(const vector<ArgumentList>& argLists, const string& templateArg, const vector<string>& instName) {
|
||||
vector<ArgumentList> result;
|
||||
BOOST_FOREACH(const ArgumentList& argList, argLists) {
|
||||
ArgumentList instArgList;
|
||||
BOOST_FOREACH(const Argument& arg, argList) {
|
||||
Argument instArg = arg;
|
||||
if(arg.type == templateArg) {
|
||||
instArg.namespaces.assign(instName.begin(), instName.end()-1);
|
||||
instArg.type = instName.back();
|
||||
}
|
||||
instArgList.push_back(instArg);
|
||||
}
|
||||
result.push_back(instArgList);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
template<class METHOD>
|
||||
map<string, METHOD> expandMethodTemplate(const map<string, METHOD>& methods, const string& templateArg, const vector<string>& instName) {
|
||||
map<string, METHOD> result;
|
||||
typedef pair<const string, METHOD> Name_Method;
|
||||
BOOST_FOREACH(const Name_Method& name_method, methods) {
|
||||
const METHOD& method = name_method.second;
|
||||
METHOD instMethod = method;
|
||||
instMethod.argLists = expandArgumentListsTemplate(method.argLists, templateArg, instName);
|
||||
instMethod.returnVals.clear();
|
||||
BOOST_FOREACH(const ReturnValue& retVal, method.returnVals) {
|
||||
ReturnValue instRetVal = retVal;
|
||||
if(retVal.type1 == templateArg) {
|
||||
instRetVal.namespaces1.assign(instName.begin(), instName.end()-1);
|
||||
instRetVal.type1 = instName.back();
|
||||
}
|
||||
if(retVal.type2 == templateArg) {
|
||||
instRetVal.namespaces2.assign(instName.begin(), instName.end()-1);
|
||||
instRetVal.type2 = instName.back();
|
||||
}
|
||||
instMethod.returnVals.push_back(instRetVal);
|
||||
}
|
||||
result.insert(make_pair(name_method.first, instMethod));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Class expandClassTemplate(const Class& cls, const string& templateArg, const vector<string>& instName) {
|
||||
Class inst;
|
||||
inst.name = cls.name;
|
||||
inst.templateArgs = cls.templateArgs;
|
||||
inst.typedefName = cls.typedefName;
|
||||
inst.isVirtual = cls.isVirtual;
|
||||
inst.qualifiedParent = cls.qualifiedParent;
|
||||
inst.methods = expandMethodTemplate(cls.methods, templateArg, instName);
|
||||
inst.static_methods = expandMethodTemplate(cls.static_methods, templateArg, instName);
|
||||
inst.namespaces = cls.namespaces;
|
||||
inst.using_namespaces = cls.using_namespaces;
|
||||
bool allIncludesEmpty = true;
|
||||
BOOST_FOREACH(const string& inc, cls.includes) { if(!inc.empty()) { allIncludesEmpty = false; break; } }
|
||||
if(allIncludesEmpty)
|
||||
inst.includes.push_back(cls.name + ".h");
|
||||
else
|
||||
inst.includes = cls.includes;
|
||||
inst.constructor = cls.constructor;
|
||||
inst.constructor.args_list = expandArgumentListsTemplate(cls.constructor.args_list, templateArg, instName);
|
||||
inst.constructor.name = inst.name;
|
||||
inst.deconstructor = cls.deconstructor;
|
||||
inst.deconstructor.name = inst.name;
|
||||
inst.verbose_ = cls.verbose_;
|
||||
return inst;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
vector<Class> Class::expandTemplate(const string& templateArg, const vector<vector<string> >& instantiations) const {
|
||||
vector<Class> result;
|
||||
BOOST_FOREACH(const vector<string>& instName, instantiations) {
|
||||
Class inst = expandClassTemplate(*this, templateArg, instName);
|
||||
inst.name = name + instName.back();
|
||||
inst.templateArgs.clear();
|
||||
inst.typedefName = qualifiedName("::") + "<" + wrap::qualifiedName("::", instName) + ">";
|
||||
result.push_back(inst);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Class Class::expandTemplate(const string& templateArg, const vector<string>& instantiation) const {
|
||||
return expandClassTemplate(*this, templateArg, instantiation);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
std::string Class::getTypedef() const {
|
||||
string result;
|
||||
BOOST_FOREACH(const string& namesp, namespaces) {
|
||||
result += ("namespace " + namesp + " { ");
|
||||
}
|
||||
result += ("typedef " + typedefName + " " + name + ";");
|
||||
BOOST_FOREACH(const string& namesp, namespaces) {
|
||||
result += " }";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
|
|
|||
40
wrap/Class.h
40
wrap/Class.h
|
|
@ -14,44 +14,58 @@
|
|||
* @brief describe the C++ class that is being wrapped
|
||||
* @author Frank Dellaert
|
||||
* @author Andrew Melim
|
||||
* @author Richard Roberts
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "Constructor.h"
|
||||
#include "Deconstructor.h"
|
||||
#include "Method.h"
|
||||
#include "StaticMethod.h"
|
||||
#include "TypeAttributesTable.h"
|
||||
|
||||
namespace wrap {
|
||||
|
||||
/// Class has name, constructors, methods
|
||||
struct Class {
|
||||
typedef std::map<std::string, Method> Methods;
|
||||
typedef std::map<std::string, StaticMethod> StaticMethods;
|
||||
|
||||
/// Constructor creates an empty class
|
||||
Class(bool verbose=true) : verbose_(verbose) {}
|
||||
Class(bool verbose=true) : isVirtual(false), verbose_(verbose) {}
|
||||
|
||||
// Then the instance variables are set directly by the Module constructor
|
||||
std::string name; ///< Class name
|
||||
std::vector<Method> methods; ///< Class methods
|
||||
std::vector<StaticMethod> static_methods; ///< Static methods
|
||||
std::vector<std::string> templateArgs; ///< Template arguments
|
||||
std::string typedefName; ///< The name to typedef *from*, if this class is actually a typedef, i.e. typedef [typedefName] [name]
|
||||
bool isVirtual; ///< Whether the class is part of a virtual inheritance chain
|
||||
std::vector<std::string> qualifiedParent; ///< The *single* parent - the last string is the parent class name, preceededing elements are a namespace stack
|
||||
Methods methods; ///< Class methods
|
||||
StaticMethods static_methods; ///< Static methods
|
||||
std::vector<std::string> namespaces; ///< Stack of namespaces
|
||||
std::vector<std::string> using_namespaces; ///< default namespaces
|
||||
std::vector<std::string> using_namespaces;///< default namespaces
|
||||
std::vector<std::string> includes; ///< header include overrides
|
||||
Constructor constructor; ///< Class constructors
|
||||
Constructor constructor; ///< Class constructors
|
||||
Deconstructor deconstructor; ///< Deconstructor to deallocate C++ object
|
||||
bool verbose_; ///< verbose flag
|
||||
|
||||
// And finally MATLAB code is emitted, methods below called by Module::matlab_code
|
||||
void matlab_proxy(const std::string& classFile) const; ///< emit proxy class
|
||||
void matlab_constructors(const std::string& toolboxPath) const; ///< emit constructor wrappers
|
||||
void matlab_methods(const std::string& classPath) const; ///< emit method wrappers
|
||||
void matlab_static_methods(const std::string& classPath) const; ///< emit static method wrappers
|
||||
void matlab_make_fragment(FileWriter& file,
|
||||
const std::string& toolboxPath,
|
||||
const std::string& mexFlags) const; ///< emit make fragment for global make script
|
||||
void makefile_fragment(FileWriter& file) const; ///< emit makefile fragment
|
||||
void matlab_proxy(const std::string& classFile, const std::string& wrapperName, const TypeAttributesTable& typeAttributes,
|
||||
FileWriter& wrapperFile, std::vector<std::string>& functionNames) const; ///< emit proxy class
|
||||
std::string qualifiedName(const std::string& delim = "") const; ///< creates a namespace-qualified name, optional delimiter
|
||||
|
||||
std::vector<Class> expandTemplate(const std::string& templateArg, const std::vector<std::vector<std::string> >& instantiations) const;
|
||||
Class expandTemplate(const std::string& templateArg, const std::vector<std::string>& instantiation) const;
|
||||
|
||||
// The typedef line for this class, if this class is a typedef, otherwise returns an empty string.
|
||||
std::string getTypedef() const;
|
||||
|
||||
private:
|
||||
void pointer_constructor_fragments(FileWriter& proxyFile, FileWriter& wrapperFile, const std::string& wrapperName, std::vector<std::string>& functionNames) const;
|
||||
};
|
||||
|
||||
} // \namespace wrap
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* @file Constructor.ccp
|
||||
* @author Frank Dellaert
|
||||
* @author Andrew Melim
|
||||
* @author Richard Roberts
|
||||
**/
|
||||
|
||||
#include <iostream>
|
||||
|
|
@ -20,6 +21,7 @@
|
|||
#include <algorithm>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "utilities.h"
|
||||
#include "Constructor.h"
|
||||
|
|
@ -35,11 +37,11 @@ string Constructor::matlab_wrapper_name(const string& className) const {
|
|||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Constructor::matlab_proxy_fragment(FileWriter& file,
|
||||
const string& className, const int id, const ArgumentList args) const {
|
||||
void Constructor::proxy_fragment(FileWriter& file, const std::string& wrapperName,
|
||||
const string& matlabName, const string& matlabBaseName, const int id, const ArgumentList args) const {
|
||||
size_t nrArgs = args.size();
|
||||
// check for number of arguments...
|
||||
file.oss << " if (nargin == " << nrArgs;
|
||||
file.oss << " elseif nargin == " << nrArgs;
|
||||
if (nrArgs>0) file.oss << " && ";
|
||||
// ...and their types
|
||||
bool first = true;
|
||||
|
|
@ -49,117 +51,60 @@ void Constructor::matlab_proxy_fragment(FileWriter& file,
|
|||
first=false;
|
||||
}
|
||||
// emit code for calling constructor
|
||||
file.oss << "), obj.self = " << matlab_wrapper_name(className) << "(" << "0," << id;
|
||||
if(matlabBaseName.empty())
|
||||
file.oss << "\n my_ptr = ";
|
||||
else
|
||||
file.oss << "\n [ my_ptr, base_ptr ] = ";
|
||||
file.oss << wrapperName << "(" << id;
|
||||
// emit constructor arguments
|
||||
for(size_t i=0;i<nrArgs;i++) {
|
||||
file.oss << ",";
|
||||
file.oss << ", ";
|
||||
file.oss << "varargin{" << i+1 << "}";
|
||||
}
|
||||
file.oss << "); end" << endl;
|
||||
file.oss << ");\n";
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Constructor::matlab_mfile(const string& toolboxPath, const string& qualifiedMatlabName, const ArgumentList args) const {
|
||||
|
||||
string matlabName = matlab_wrapper_name(qualifiedMatlabName);
|
||||
|
||||
// open destination m-file
|
||||
string wrapperFile = toolboxPath + "/" + matlabName + ".m";
|
||||
FileWriter file(wrapperFile, verbose_, "%");
|
||||
|
||||
// generate code
|
||||
file.oss << "function result = " << matlabName << "(obj";
|
||||
if (args.size()) file.oss << "," << args.names();
|
||||
file.oss << ")" << endl;
|
||||
file.oss << " error('need to compile " << matlabName << ".cpp');" << endl;
|
||||
file.oss << "end" << endl;
|
||||
|
||||
// close file
|
||||
file.emit(true);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Constructor::matlab_wrapper(const string& toolboxPath,
|
||||
string Constructor::wrapper_fragment(FileWriter& file,
|
||||
const string& cppClassName,
|
||||
const string& matlabClassName,
|
||||
const string& cppBaseClassName,
|
||||
int id,
|
||||
const vector<string>& using_namespaces,
|
||||
const vector<string>& includes) const {
|
||||
string matlabName = matlab_wrapper_name(matlabClassName);
|
||||
const ArgumentList& al) const {
|
||||
|
||||
// open destination wrapperFile
|
||||
string wrapperFile = toolboxPath + "/" + matlabName + ".cpp";
|
||||
FileWriter file(wrapperFile, verbose_, "//");
|
||||
|
||||
// generate code
|
||||
generateIncludes(file, name, includes);
|
||||
generateUsingNamespace(file, using_namespaces);
|
||||
const string wrapFunctionName = matlabClassName + "_constructor_" + boost::lexical_cast<string>(id);
|
||||
|
||||
file.oss << "void " << wrapFunctionName << "(int nargout, mxArray *out[], int nargin, const mxArray *in[])" << endl;
|
||||
file.oss << "{\n";
|
||||
file.oss << " mexAtExit(&_deleteAllObjects);\n";
|
||||
generateUsingNamespace(file, using_namespaces);
|
||||
//Typedef boost::shared_ptr
|
||||
file.oss << "typedef boost::shared_ptr<" << cppClassName << "> Shared;" << endl;
|
||||
file.oss << endl;
|
||||
file.oss << " typedef boost::shared_ptr<" << cppClassName << "> Shared;\n";
|
||||
file.oss << "\n";
|
||||
|
||||
//Generate collector
|
||||
file.oss << "static std::set<Shared*> collector;" << endl;
|
||||
file.oss << endl;
|
||||
//Check to see if there will be any arguments and remove {} for consiseness
|
||||
if(al.size() > 0)
|
||||
al.matlab_unwrap(file); // unwrap arguments
|
||||
file.oss << " Shared *self = new Shared(new " << cppClassName << "(" << al.names() << "));" << endl;
|
||||
file.oss << " collector_" << matlabClassName << ".insert(self);\n";
|
||||
|
||||
//Generate cleanup function
|
||||
file.oss << "void cleanup(void) {" << endl;
|
||||
file.oss << " for(std::set<Shared*>::iterator iter = collector.begin(); iter != collector.end(); ) {\n";
|
||||
file.oss << " delete *iter;\n";
|
||||
file.oss << " collector.erase(iter++);\n";
|
||||
file.oss << " }\n";
|
||||
file.oss << "}" << endl;
|
||||
if(verbose_)
|
||||
file.oss << " std::cout << \"constructed \" << self << \" << std::endl;" << endl;
|
||||
file.oss << " out[0] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL);" << endl;
|
||||
file.oss << " *reinterpret_cast<Shared**> (mxGetData(out[0])) = self;" << endl;
|
||||
|
||||
file.oss << "void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])" << endl;
|
||||
file.oss << "{" << endl;
|
||||
//Cleanup function callback
|
||||
file.oss << " mexAtExit(cleanup);" << endl;
|
||||
file.oss << endl;
|
||||
file.oss << " const mxArray* input = in[0];" << endl;
|
||||
file.oss << " Shared* self = *(Shared**) mxGetData(input);" << endl;
|
||||
file.oss << endl;
|
||||
file.oss << " if(self) {" << endl;
|
||||
file.oss << " if(nargin > 1) {" << endl;
|
||||
file.oss << " collector.insert(self);" << endl;
|
||||
if(verbose_)
|
||||
file.oss << " std::cout << \"Collected\" << collector.size() << std::endl;" << endl;
|
||||
file.oss << " }" << endl;
|
||||
file.oss << " else if(collector.erase(self))" << endl;
|
||||
file.oss << " delete self;" << endl;
|
||||
file.oss << " } else {" << endl;
|
||||
file.oss << " int nc = unwrap<int>(in[1]);" << endl << endl;
|
||||
|
||||
int i = 0;
|
||||
BOOST_FOREACH(ArgumentList al, args_list)
|
||||
{
|
||||
//Check to see if there will be any arguments and remove {} for consiseness
|
||||
if(al.size())
|
||||
{
|
||||
file.oss << " if(nc == " << i <<") {" << endl;
|
||||
al.matlab_unwrap(file, 2); // unwrap arguments, start at 1
|
||||
file.oss << " self = new Shared(new " << cppClassName << "(" << al.names() << "));" << endl;
|
||||
file.oss << " }" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
file.oss << " if(nc == " << i <<")" << endl;
|
||||
file.oss << " self = new Shared(new " << cppClassName << "(" << al.names() << "));" << endl;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
//file.oss << " self = construct(nc, in);" << endl;
|
||||
file.oss << " collector.insert(self);" << endl;
|
||||
if(verbose_)
|
||||
file.oss << " std::cout << \"constructed \" << self << \", size=\" << collector.size() << std::endl;" << endl;
|
||||
file.oss << " out[0] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL);" << endl;
|
||||
file.oss << " *reinterpret_cast<Shared**> (mxGetPr(out[0])) = self;" << endl;
|
||||
file.oss << " }" << endl;
|
||||
// If we have a base class, return the base class pointer (MATLAB will call the base class collectorInsertAndMakeBase to add this to the collector and recurse the heirarchy)
|
||||
if(!cppBaseClassName.empty()) {
|
||||
file.oss << "\n";
|
||||
file.oss << " typedef boost::shared_ptr<" << cppBaseClassName << "> SharedBase;\n";
|
||||
file.oss << " out[1] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL);\n";
|
||||
file.oss << " *reinterpret_cast<SharedBase**>(mxGetData(out[1])) = new SharedBase(*self);\n";
|
||||
}
|
||||
|
||||
file.oss << "}" << endl;
|
||||
|
||||
// close file
|
||||
file.emit(true);
|
||||
return wrapFunctionName;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* @file Constructor.h
|
||||
* @brief class describing a constructor + code generation
|
||||
* @author Frank Dellaert
|
||||
* @author Richard Roberts
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
|
@ -48,21 +49,18 @@ struct Constructor {
|
|||
* Create fragment to select constructor in proxy class, e.g.,
|
||||
* if nargin == 2, obj.self = new_Pose3_RP(varargin{1},varargin{2}); end
|
||||
*/
|
||||
void matlab_proxy_fragment(FileWriter& file,
|
||||
const std::string& className, const int i,
|
||||
void proxy_fragment(FileWriter& file, const std::string& wrapperName,
|
||||
const std::string& className, const std::string& matlabBaseName, const int id,
|
||||
const ArgumentList args) const;
|
||||
|
||||
/// m-file
|
||||
void matlab_mfile(const std::string& toolboxPath,
|
||||
const std::string& qualifiedMatlabName,
|
||||
const ArgumentList args) const;
|
||||
|
||||
/// cpp wrapper
|
||||
void matlab_wrapper(const std::string& toolboxPath,
|
||||
std::string wrapper_fragment(FileWriter& file,
|
||||
const std::string& cppClassName,
|
||||
const std::string& matlabClassName,
|
||||
const std::string& cppBaseClassName,
|
||||
int id,
|
||||
const std::vector<std::string>& using_namespaces,
|
||||
const std::vector<std::string>& includes) const;
|
||||
const ArgumentList& al) const;
|
||||
|
||||
/// constructor function
|
||||
void generate_construct(FileWriter& file, const std::string& cppClassName,
|
||||
|
|
|
|||
|
|
@ -13,12 +13,14 @@
|
|||
* @file Deconstructor.ccp
|
||||
* @author Frank Dellaert
|
||||
* @author Andrew Melim
|
||||
* @author Richard Roberts
|
||||
**/
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "utilities.h"
|
||||
#include "Deconstructor.h"
|
||||
|
|
@ -33,51 +35,42 @@ string Deconstructor::matlab_wrapper_name(const string& className) const {
|
|||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Deconstructor::matlab_mfile(const string& toolboxPath, const string& qualifiedMatlabName) const {
|
||||
void Deconstructor::proxy_fragment(FileWriter& file,
|
||||
const std::string& wrapperName,
|
||||
const std::string& qualifiedMatlabName, int id) const {
|
||||
|
||||
string matlabName = matlab_wrapper_name(qualifiedMatlabName);
|
||||
|
||||
// open destination m-file
|
||||
string wrapperFile = toolboxPath + "/" + matlabName + ".m";
|
||||
FileWriter file(wrapperFile, verbose_, "%");
|
||||
|
||||
// generate code
|
||||
file.oss << "function result = " << matlabName << "(obj";
|
||||
if (args.size()) file.oss << "," << args.names();
|
||||
file.oss << ")" << endl;
|
||||
file.oss << " error('need to compile " << matlabName << ".cpp');" << endl;
|
||||
file.oss << "end" << endl;
|
||||
|
||||
// close file
|
||||
file.emit(true);
|
||||
file.oss << " function delete(obj)\n";
|
||||
file.oss << " " << wrapperName << "(" << id << ", obj.ptr_" << qualifiedMatlabName << ");\n";
|
||||
file.oss << " end\n";
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Deconstructor::matlab_wrapper(const string& toolboxPath,
|
||||
string Deconstructor::wrapper_fragment(FileWriter& file,
|
||||
const string& cppClassName,
|
||||
const string& matlabClassName,
|
||||
const vector<string>& using_namespaces, const vector<string>& includes) const {
|
||||
string matlabName = matlab_wrapper_name(matlabClassName);
|
||||
int id,
|
||||
const vector<string>& using_namespaces) const {
|
||||
|
||||
const string matlabName = matlab_wrapper_name(matlabClassName);
|
||||
|
||||
// open destination wrapperFile
|
||||
string wrapperFile = toolboxPath + "/" + matlabName + ".cpp";
|
||||
FileWriter file(wrapperFile, verbose_, "//");
|
||||
|
||||
// generate code
|
||||
//
|
||||
generateIncludes(file, name, includes);
|
||||
cout << "Generate includes " << name << endl;
|
||||
generateUsingNamespace(file, using_namespaces);
|
||||
const string wrapFunctionName = matlabClassName + "_deconstructor_" + boost::lexical_cast<string>(id);
|
||||
|
||||
file.oss << "void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])" << endl;
|
||||
file.oss << "void " << wrapFunctionName << "(int nargout, mxArray *out[], int nargin, const mxArray *in[])" << endl;
|
||||
file.oss << "{" << endl;
|
||||
generateUsingNamespace(file, using_namespaces);
|
||||
file.oss << " typedef boost::shared_ptr<" << cppClassName << "> Shared;" << endl;
|
||||
//Deconstructor takes 1 arg, the mxArray obj
|
||||
file.oss << " checkArguments(\"" << matlabName << "\",nargout,nargin," << "1" << ");" << endl;
|
||||
file.oss << " delete_shared_ptr< " << cppClassName << " >(in[0],\"" << matlabClassName << "\");" << endl;
|
||||
file.oss << " Shared *self = *reinterpret_cast<Shared**>(mxGetData(in[0]));\n";
|
||||
file.oss << " Collector_" << matlabClassName << "::iterator item;\n";
|
||||
file.oss << " item = collector_" << matlabClassName << ".find(self);\n";
|
||||
file.oss << " if(item != collector_" << matlabClassName << ".end()) {\n";
|
||||
file.oss << " delete self;\n";
|
||||
file.oss << " collector_" << matlabClassName << ".erase(item);\n";
|
||||
file.oss << " }\n";
|
||||
file.oss << "}" << endl;
|
||||
|
||||
// close file
|
||||
file.emit(true);
|
||||
return wrapFunctionName;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
* @brief class describing a constructor + code generation
|
||||
* @author Frank Dellaert
|
||||
* @author Andrew Melim
|
||||
* @author Richard Roberts
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
|
@ -34,7 +35,6 @@ struct Deconstructor {
|
|||
}
|
||||
|
||||
// Then the instance variables are set directly by the Module deconstructor
|
||||
ArgumentList args;
|
||||
std::string name;
|
||||
bool verbose_;
|
||||
|
||||
|
|
@ -46,15 +46,16 @@ struct Deconstructor {
|
|||
std::string matlab_wrapper_name(const std::string& className) const;
|
||||
|
||||
/// m-file
|
||||
void matlab_mfile(const std::string& toolboxPath,
|
||||
const std::string& qualifiedMatlabName) const;
|
||||
void proxy_fragment(FileWriter& file,
|
||||
const std::string& wrapperName,
|
||||
const std::string& qualifiedMatlabName, int id) const;
|
||||
|
||||
/// cpp wrapper
|
||||
void matlab_wrapper(const std::string& toolboxPath,
|
||||
std::string wrapper_fragment(FileWriter& file,
|
||||
const std::string& cppClassName,
|
||||
const std::string& matlabClassName,
|
||||
const std::vector<std::string>& using_namespaces,
|
||||
const std::vector<std::string>& includes) const;
|
||||
int id,
|
||||
const std::vector<std::string>& using_namespaces) const;
|
||||
};
|
||||
|
||||
} // \namespace wrap
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
|
||||
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||
* Atlanta, Georgia 30332-0415
|
||||
* All Rights Reserved
|
||||
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
|
||||
|
||||
* See LICENSE for the license information
|
||||
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @file Class.h
|
||||
* @brief describe the C++ class that is being wrapped
|
||||
* @author Frank Dellaert
|
||||
* @author Andrew Melim
|
||||
* @author Richard Roberts
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace wrap {
|
||||
|
||||
struct ForwardDeclaration {
|
||||
std::string name;
|
||||
bool isVirtual;
|
||||
ForwardDeclaration() : isVirtual(false) {}
|
||||
};
|
||||
|
||||
}
|
||||
134
wrap/Method.cpp
134
wrap/Method.cpp
|
|
@ -12,12 +12,14 @@
|
|||
/**
|
||||
* @file Method.ccp
|
||||
* @author Frank Dellaert
|
||||
* @author Richard Roberts
|
||||
**/
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "Method.h"
|
||||
#include "utilities.h"
|
||||
|
|
@ -26,57 +28,108 @@ using namespace std;
|
|||
using namespace wrap;
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Method::matlab_mfile(const string& classPath) const {
|
||||
void Method::addOverload(bool verbose, bool is_const, const std::string& name,
|
||||
const ArgumentList& args, const ReturnValue& retVal) {
|
||||
this->verbose_ = verbose;
|
||||
this->is_const_ = is_const;
|
||||
this->name = name;
|
||||
this->argLists.push_back(args);
|
||||
this->returnVals.push_back(retVal);
|
||||
}
|
||||
|
||||
// open destination m-file
|
||||
string wrapperFile = classPath + "/" + name + ".m";
|
||||
FileWriter file(wrapperFile, verbose_, "%");
|
||||
void Method::proxy_wrapper_fragments(FileWriter& proxyFile, FileWriter& wrapperFile,
|
||||
const string& cppClassName,
|
||||
const string& matlabClassName,
|
||||
const string& wrapperName,
|
||||
const vector<string>& using_namespaces,
|
||||
const TypeAttributesTable& typeAttributes,
|
||||
vector<string>& functionNames) const {
|
||||
|
||||
// generate code
|
||||
string returnType = returnVal.matlab_returnType();
|
||||
file.oss << "% " << returnType << " = obj." << name << "(" << args.names() << ")" << endl;
|
||||
file.oss << "function " << returnType << " = " << name << "(obj";
|
||||
if (args.size()) file.oss << "," << args.names();
|
||||
file.oss << ")" << endl;
|
||||
file.oss << " error('need to compile " << name << ".cpp');" << endl;
|
||||
file.oss << "end" << endl;
|
||||
proxyFile.oss << " function varargout = " << name << "(this, varargin)\n";
|
||||
|
||||
// close file
|
||||
file.emit(false);
|
||||
for(size_t overload = 0; overload < argLists.size(); ++overload) {
|
||||
const ArgumentList& args = argLists[overload];
|
||||
const ReturnValue& returnVal = returnVals[overload];
|
||||
size_t nrArgs = args.size();
|
||||
|
||||
const int id = functionNames.size();
|
||||
|
||||
// Output proxy matlab code
|
||||
|
||||
// check for number of arguments...
|
||||
proxyFile.oss << " " << (overload==0?"":"else") << "if length(varargin) == " << nrArgs;
|
||||
if (nrArgs>0) proxyFile.oss << " && ";
|
||||
// ...and their types
|
||||
bool first = true;
|
||||
for(size_t i=0;i<nrArgs;i++) {
|
||||
if (!first) proxyFile.oss << " && ";
|
||||
proxyFile.oss << "isa(varargin{" << i+1 << "},'" << args[i].matlabClass() << "')";
|
||||
first=false;
|
||||
}
|
||||
proxyFile.oss << "\n";
|
||||
|
||||
// output call to C++ wrapper
|
||||
string output;
|
||||
if(returnVal.isPair)
|
||||
output = "[ varargout{1} varargout{2} ] = ";
|
||||
else if(returnVal.category1 == ReturnValue::VOID)
|
||||
output = "";
|
||||
else
|
||||
output = "varargout{1} = ";
|
||||
proxyFile.oss << " " << output << wrapperName << "(" << id << ", this, varargin{:});\n";
|
||||
|
||||
// Output C++ wrapper code
|
||||
|
||||
const string wrapFunctionName = wrapper_fragment(
|
||||
wrapperFile, cppClassName, matlabClassName, overload, id, using_namespaces, typeAttributes);
|
||||
|
||||
// Add to function list
|
||||
functionNames.push_back(wrapFunctionName);
|
||||
|
||||
}
|
||||
|
||||
proxyFile.oss << " else\n";
|
||||
proxyFile.oss << " error('Arguments do not match any overload of function " <<
|
||||
matlabClassName << "." << name << "');" << endl;
|
||||
|
||||
proxyFile.oss << " end\n";
|
||||
proxyFile.oss << " end\n";
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Method::matlab_wrapper(const string& classPath,
|
||||
const string& className,
|
||||
string Method::wrapper_fragment(FileWriter& file,
|
||||
const string& cppClassName,
|
||||
const string& matlabClassName,
|
||||
const vector<string>& using_namespaces, const std::vector<std::string>& includes) const {
|
||||
// open destination wrapperFile
|
||||
string wrapperFile = classPath + "/" + name + ".cpp";
|
||||
FileWriter file(wrapperFile, verbose_, "//");
|
||||
int overload,
|
||||
int id,
|
||||
const vector<string>& using_namespaces,
|
||||
const TypeAttributesTable& typeAttributes) const {
|
||||
|
||||
// generate code
|
||||
|
||||
// header
|
||||
generateIncludes(file, className, includes);
|
||||
generateUsingNamespace(file, using_namespaces);
|
||||
const string wrapFunctionName = matlabClassName + "_" + name + "_" + boost::lexical_cast<string>(id);
|
||||
|
||||
const ArgumentList& args = argLists[overload];
|
||||
const ReturnValue& returnVal = returnVals[overload];
|
||||
|
||||
// call
|
||||
file.oss << "void " << wrapFunctionName << "(int nargout, mxArray *out[], int nargin, const mxArray *in[])\n";
|
||||
// start
|
||||
file.oss << "{\n";
|
||||
generateUsingNamespace(file, using_namespaces);
|
||||
|
||||
if(returnVal.isPair)
|
||||
{
|
||||
if(returnVal.category1 == ReturnValue::CLASS)
|
||||
file.oss << "typedef boost::shared_ptr<" << returnVal.qualifiedType1("::") << "> Shared" << returnVal.type1 << ";"<< endl;
|
||||
file.oss << " typedef boost::shared_ptr<" << returnVal.qualifiedType1("::") << "> Shared" << returnVal.type1 << ";"<< endl;
|
||||
if(returnVal.category2 == ReturnValue::CLASS)
|
||||
file.oss << "typedef boost::shared_ptr<" << returnVal.qualifiedType2("::") << "> Shared" << returnVal.type2 << ";"<< endl;
|
||||
file.oss << " typedef boost::shared_ptr<" << returnVal.qualifiedType2("::") << "> Shared" << returnVal.type2 << ";"<< endl;
|
||||
}
|
||||
else
|
||||
if(returnVal.category1 == ReturnValue::CLASS)
|
||||
file.oss << "typedef boost::shared_ptr<" << returnVal.qualifiedType1("::") << "> Shared" << returnVal.type1 << ";"<< endl;
|
||||
file.oss << " typedef boost::shared_ptr<" << returnVal.qualifiedType1("::") << "> Shared" << returnVal.type1 << ";"<< endl;
|
||||
|
||||
file.oss << "typedef boost::shared_ptr<" << cppClassName << "> Shared;" << endl;
|
||||
// call
|
||||
file.oss << "void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])\n";
|
||||
// start
|
||||
file.oss << "{\n";
|
||||
file.oss << " typedef boost::shared_ptr<" << cppClassName << "> Shared;" << endl;
|
||||
|
||||
// check arguments
|
||||
// extra argument obj -> nargin-1 is passed !
|
||||
|
|
@ -85,26 +138,21 @@ void Method::matlab_wrapper(const string& classPath,
|
|||
|
||||
// get class pointer
|
||||
// example: shared_ptr<Test> = unwrap_shared_ptr< Test >(in[0], "Test");
|
||||
file.oss << " Shared obj = unwrap_shared_ptr<" << cppClassName << ">(in[0], \"" << cppClassName << "\");" << endl;
|
||||
file.oss << " Shared obj = unwrap_shared_ptr<" << cppClassName << ">(in[0], \"ptr_" << matlabClassName << "\");" << endl;
|
||||
// unwrap arguments, see Argument.cpp
|
||||
args.matlab_unwrap(file,1);
|
||||
|
||||
// call method
|
||||
// example: bool result = self->return_field(t);
|
||||
file.oss << " ";
|
||||
// call method and wrap result
|
||||
// example: out[0]=wrap<bool>(self->return_field(t));
|
||||
if (returnVal.type1!="void")
|
||||
file.oss << returnVal.return_type(true,ReturnValue::pair) << " result = ";
|
||||
file.oss << "obj->" << name << "(" << args.names() << ");\n";
|
||||
|
||||
// wrap result
|
||||
// example: out[0]=wrap<bool>(result);
|
||||
returnVal.wrap_result(file);
|
||||
returnVal.wrap_result("obj->"+name+"("+args.names()+")", file, typeAttributes);
|
||||
else
|
||||
file.oss << " obj->"+name+"("+args.names()+");\n";
|
||||
|
||||
// finish
|
||||
file.oss << "}\n";
|
||||
|
||||
// close file
|
||||
file.emit(true);
|
||||
return wrapFunctionName;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* @file Method.h
|
||||
* @brief describes and generates code for methods
|
||||
* @author Frank Dellaert
|
||||
* @author Richard Roberts
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
|
@ -22,6 +23,7 @@
|
|||
|
||||
#include "Argument.h"
|
||||
#include "ReturnValue.h"
|
||||
#include "TypeAttributesTable.h"
|
||||
|
||||
namespace wrap {
|
||||
|
||||
|
|
@ -30,25 +32,37 @@ struct Method {
|
|||
|
||||
/// Constructor creates empty object
|
||||
Method(bool verbose = true) :
|
||||
verbose_(verbose) {}
|
||||
verbose_(verbose), is_const_(false) {}
|
||||
|
||||
// Then the instance variables are set directly by the Module constructor
|
||||
bool verbose_;
|
||||
bool is_const_;
|
||||
std::string name;
|
||||
ArgumentList args;
|
||||
ReturnValue returnVal;
|
||||
std::vector<ArgumentList> argLists;
|
||||
std::vector<ReturnValue> returnVals;
|
||||
|
||||
// The first time this function is called, it initializes the class members
|
||||
// with those in rhs, but in subsequent calls it adds additional argument
|
||||
// lists as function overloads.
|
||||
void addOverload(bool verbose, bool is_const, const std::string& name,
|
||||
const ArgumentList& args, const ReturnValue& retVal);
|
||||
|
||||
// MATLAB code generation
|
||||
// classPath is class directory, e.g., ../matlab/@Point2
|
||||
void proxy_wrapper_fragments(FileWriter& proxyFile, FileWriter& wrapperFile,
|
||||
const std::string& cppClassName, const std::string& matlabClassName,
|
||||
const std::string& wrapperName, const std::vector<std::string>& using_namespaces,
|
||||
const TypeAttributesTable& typeAttributes,
|
||||
std::vector<std::string>& functionNames) const;
|
||||
|
||||
void matlab_mfile(const std::string& classPath) const; ///< m-file
|
||||
void matlab_wrapper(const std::string& classPath,
|
||||
const std::string& className,
|
||||
private:
|
||||
std::string wrapper_fragment(FileWriter& file,
|
||||
const std::string& cppClassName,
|
||||
const std::string& matlabClassname,
|
||||
int overload,
|
||||
int id,
|
||||
const std::vector<std::string>& using_namespaces,
|
||||
const std::vector<std::string>& includes) const; ///< cpp wrapper
|
||||
const TypeAttributesTable& typeAttributes) const; ///< cpp wrapper
|
||||
};
|
||||
|
||||
} // \namespace wrap
|
||||
|
|
|
|||
993
wrap/Module.cpp
993
wrap/Module.cpp
|
|
@ -1,389 +1,604 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
|
||||
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||
* Atlanta, Georgia 30332-0415
|
||||
* All Rights Reserved
|
||||
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
|
||||
|
||||
* See LICENSE for the license information
|
||||
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @file Module.ccp
|
||||
* @author Frank Dellaert
|
||||
* @author Alex Cunningham
|
||||
* @author Andrew Melim
|
||||
**/
|
||||
|
||||
#include "Module.h"
|
||||
#include "FileWriter.h"
|
||||
#include "utilities.h"
|
||||
#include "spirit_actors.h"
|
||||
|
||||
//#define BOOST_SPIRIT_DEBUG
|
||||
#include <boost/spirit/include/classic_confix.hpp>
|
||||
#include <boost/spirit/include/classic_clear_actor.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
using namespace wrap;
|
||||
using namespace BOOST_SPIRIT_CLASSIC_NS;
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
typedef rule<BOOST_SPIRIT_CLASSIC_NS::phrase_scanner_t> Rule;
|
||||
|
||||
/* ************************************************************************* */
|
||||
// We parse an interface file into a Module object.
|
||||
// The grammar is defined using the boost/spirit combinatorial parser.
|
||||
// For example, str_p("const") parses the string "const", and the >>
|
||||
// operator creates a sequence parser. The grammar below, composed of rules
|
||||
// and with start rule [class_p], doubles as the specs for our interface files.
|
||||
/* ************************************************************************* */
|
||||
|
||||
Module::Module(const string& interfacePath,
|
||||
const string& moduleName, bool enable_verbose) : name(moduleName), verbose(enable_verbose)
|
||||
{
|
||||
// these variables will be imperatively updated to gradually build [cls]
|
||||
// The one with postfix 0 are used to reset the variables after parse.
|
||||
ReturnValue retVal0, retVal;
|
||||
Argument arg0, arg;
|
||||
ArgumentList args0, args;
|
||||
vector<string> arg_dup; ///keep track of duplicates
|
||||
Constructor constructor0(enable_verbose), constructor(enable_verbose);
|
||||
//Deconstructor deconstructor0(enable_verbose), deconstructor(enable_verbose);
|
||||
Method method0(enable_verbose), method(enable_verbose);
|
||||
StaticMethod static_method0(enable_verbose), static_method(enable_verbose);
|
||||
Class cls0(enable_verbose),cls(enable_verbose);
|
||||
vector<string> namespaces, /// current namespace tag
|
||||
namespace_includes, /// current set of includes
|
||||
namespaces_return, /// namespace for current return type
|
||||
using_namespace_current; /// All namespaces from "using" declarations
|
||||
string include_path = "";
|
||||
string class_name = "";
|
||||
const string null_str = "";
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Grammar with actions that build the Class object. Actions are
|
||||
// defined within the square brackets [] and are executed whenever a
|
||||
// rule is successfully parsed. Define BOOST_SPIRIT_DEBUG to debug.
|
||||
// The grammar is allows a very restricted C++ header
|
||||
// lexeme_d turns off white space skipping
|
||||
// http://www.boost.org/doc/libs/1_37_0/libs/spirit/classic/doc/directives.html
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
Rule comments_p = comment_p("/*", "*/") | comment_p("//", eol_p);
|
||||
|
||||
Rule basisType_p =
|
||||
(str_p("string") | "bool" | "size_t" | "int" | "double" | "char" | "unsigned char");
|
||||
|
||||
Rule keywords_p =
|
||||
(str_p("const") | "static" | "namespace" | basisType_p);
|
||||
|
||||
Rule eigenType_p =
|
||||
(str_p("Vector") | "Matrix");
|
||||
|
||||
Rule className_p = (lexeme_d[upper_p >> *(alnum_p | '_')] - eigenType_p - keywords_p)[assign_a(class_name)];
|
||||
|
||||
Rule namespace_name_p = lexeme_d[lower_p >> *(alnum_p | '_')] - keywords_p;
|
||||
|
||||
Rule namespace_arg_p = namespace_name_p[push_back_a(arg.namespaces)] >> str_p("::");
|
||||
|
||||
Rule argEigenType_p =
|
||||
eigenType_p[assign_a(arg.type)] >>
|
||||
!ch_p('*')[assign_a(arg.is_ptr,true)];
|
||||
|
||||
Rule eigenRef_p =
|
||||
!str_p("const") [assign_a(arg.is_const,true)] >>
|
||||
eigenType_p [assign_a(arg.type)] >>
|
||||
ch_p('&') [assign_a(arg.is_ref,true)];
|
||||
|
||||
Rule classArg_p =
|
||||
!str_p("const") [assign_a(arg.is_const,true)] >>
|
||||
*namespace_arg_p >>
|
||||
className_p[assign_a(arg.type)] >>
|
||||
(ch_p('*')[assign_a(arg.is_ptr,true)] | ch_p('&')[assign_a(arg.is_ref,true)]);
|
||||
|
||||
Rule name_p = lexeme_d[alpha_p >> *(alnum_p | '_')];
|
||||
|
||||
Rule argument_p =
|
||||
((basisType_p[assign_a(arg.type)] | argEigenType_p | eigenRef_p | classArg_p)
|
||||
>> name_p[assign_a(arg.name)])
|
||||
[push_back_a(args, arg)]
|
||||
[assign_a(arg,arg0)];
|
||||
|
||||
Rule argumentList_p = !argument_p >> * (',' >> argument_p);
|
||||
|
||||
Rule constructor_p =
|
||||
(className_p >> '(' >> argumentList_p >> ')' >> ';' >> !comments_p)
|
||||
[push_back_a(constructor.args_list, args)]
|
||||
[assign_a(args,args0)];
|
||||
//[assign_a(constructor.args,args)]
|
||||
//[assign_a(constructor.name,cls.name)]
|
||||
//[push_back_a(cls.constructors, constructor)]
|
||||
//[assign_a(constructor,constructor0)];
|
||||
|
||||
Rule namespace_ret_p = namespace_name_p[push_back_a(namespaces_return)] >> str_p("::");
|
||||
|
||||
Rule returnType1_p =
|
||||
(basisType_p[assign_a(retVal.type1)][assign_a(retVal.category1, ReturnValue::BASIS)]) |
|
||||
((*namespace_ret_p)[assign_a(retVal.namespaces1, namespaces_return)][clear_a(namespaces_return)]
|
||||
>> (className_p[assign_a(retVal.type1)][assign_a(retVal.category1, ReturnValue::CLASS)]) >>
|
||||
!ch_p('*')[assign_a(retVal.isPtr1,true)]) |
|
||||
(eigenType_p[assign_a(retVal.type1)][assign_a(retVal.category1, ReturnValue::EIGEN)]);
|
||||
|
||||
Rule returnType2_p =
|
||||
(basisType_p[assign_a(retVal.type2)][assign_a(retVal.category2, ReturnValue::BASIS)]) |
|
||||
((*namespace_ret_p)[assign_a(retVal.namespaces2, namespaces_return)][clear_a(namespaces_return)]
|
||||
>> (className_p[assign_a(retVal.type2)][assign_a(retVal.category2, ReturnValue::CLASS)]) >>
|
||||
!ch_p('*') [assign_a(retVal.isPtr2,true)]) |
|
||||
(eigenType_p[assign_a(retVal.type2)][assign_a(retVal.category2, ReturnValue::EIGEN)]);
|
||||
|
||||
Rule pair_p =
|
||||
(str_p("pair") >> '<' >> returnType1_p >> ',' >> returnType2_p >> '>')
|
||||
[assign_a(retVal.isPair,true)];
|
||||
|
||||
Rule void_p = str_p("void")[assign_a(retVal.type1)];
|
||||
|
||||
Rule returnType_p = void_p | returnType1_p | pair_p;
|
||||
|
||||
Rule methodName_p = lexeme_d[lower_p >> *(alnum_p | '_')];
|
||||
|
||||
Rule method_p =
|
||||
(returnType_p >> methodName_p[assign_a(method.name)] >>
|
||||
'(' >> argumentList_p >> ')' >>
|
||||
!str_p("const")[assign_a(method.is_const_,true)] >> ';' >> *comments_p)
|
||||
[assign_a(method.args,args)]
|
||||
[assign_a(args,args0)]
|
||||
[assign_a(method.returnVal,retVal)]
|
||||
[assign_a(retVal,retVal0)]
|
||||
[push_back_a(cls.methods, method)]
|
||||
[assign_a(method,method0)];
|
||||
|
||||
Rule staticMethodName_p = lexeme_d[(upper_p | lower_p) >> *(alnum_p | '_')];
|
||||
|
||||
Rule static_method_p =
|
||||
(str_p("static") >> returnType_p >> staticMethodName_p[assign_a(static_method.name)] >>
|
||||
'(' >> argumentList_p >> ')' >> ';' >> *comments_p)
|
||||
[assign_a(static_method.args,args)]
|
||||
[assign_a(args,args0)]
|
||||
[assign_a(static_method.returnVal,retVal)]
|
||||
[assign_a(retVal,retVal0)]
|
||||
[push_back_a(cls.static_methods, static_method)]
|
||||
[assign_a(static_method,static_method0)];
|
||||
|
||||
Rule functions_p = constructor_p | method_p | static_method_p;
|
||||
|
||||
Rule include_p = str_p("#include") >> ch_p('<') >> (*(anychar_p - '>'))[assign_a(include_path)] >> ch_p('>');
|
||||
|
||||
Rule class_p =
|
||||
(!*include_p
|
||||
>> str_p("class")[push_back_a(cls.includes, include_path)][assign_a(include_path, null_str)]
|
||||
>> className_p[assign_a(cls.name)]
|
||||
>> '{'
|
||||
>> *(functions_p | comments_p)
|
||||
>> str_p("};"))
|
||||
[assign_a(constructor.name, cls.name)]
|
||||
[assign_a(cls.constructor, constructor)]
|
||||
[assign_a(cls.namespaces, namespaces)]
|
||||
[assign_a(cls.using_namespaces, using_namespace_current)]
|
||||
[append_a(cls.includes, namespace_includes)]
|
||||
//[assign_a(deconstructor.name,cls.name)]
|
||||
//[assign_a(cls.d, deconstructor)]
|
||||
[push_back_a(classes,cls)]
|
||||
//[assign_a(deconstructor,deconstructor0)]
|
||||
[assign_a(constructor, constructor0)]
|
||||
[assign_a(cls,cls0)];
|
||||
|
||||
Rule namespace_def_p =
|
||||
(!*include_p
|
||||
>> str_p("namespace")[push_back_a(namespace_includes, include_path)][assign_a(include_path, null_str)]
|
||||
>> namespace_name_p[push_back_a(namespaces)]
|
||||
>> ch_p('{')
|
||||
>> *(class_p | namespace_def_p | comments_p)
|
||||
>> str_p("}///\\namespace") // end namespace, avoid confusion with classes
|
||||
>> !namespace_name_p)
|
||||
[pop_a(namespaces)]
|
||||
[pop_a(namespace_includes)];
|
||||
|
||||
Rule using_namespace_p =
|
||||
str_p("using") >> str_p("namespace")
|
||||
>> namespace_name_p[push_back_a(using_namespace_current)] >> ch_p(';');
|
||||
|
||||
Rule forward_declaration_p =
|
||||
str_p("class") >>
|
||||
(*(namespace_name_p >> str_p("::")) >> className_p)[push_back_a(forward_declarations)]
|
||||
>> ch_p(';');
|
||||
|
||||
Rule module_content_p = comments_p | using_namespace_p | class_p | forward_declaration_p | namespace_def_p ;
|
||||
|
||||
Rule module_p = *module_content_p >> !end_p;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// for debugging, define BOOST_SPIRIT_DEBUG
|
||||
# ifdef BOOST_SPIRIT_DEBUG
|
||||
BOOST_SPIRIT_DEBUG_NODE(className_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(classPtr_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(classRef_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(basisType_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(name_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(argument_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(argumentList_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(constructor_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(returnType1_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(returnType2_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(pair_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(void_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(returnType_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(methodName_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(method_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(class_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(namespace_def_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(module_p);
|
||||
# endif
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// read interface file
|
||||
string interfaceFile = interfacePath + "/" + moduleName + ".h";
|
||||
string contents = file_contents(interfaceFile);
|
||||
|
||||
// and parse contents
|
||||
parse_info<const char*> info = parse(contents.c_str(), module_p, space_p);
|
||||
if(!info.full) {
|
||||
printf("parsing stopped at \n%.20s\n",info.stop);
|
||||
throw ParseFailed(info.length);
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
template<class T>
|
||||
void verifyArguments(const vector<string>& validArgs, const vector<T>& vt) {
|
||||
BOOST_FOREACH(const T& t, vt) {
|
||||
BOOST_FOREACH(Argument arg, t.args) {
|
||||
string fullType = arg.qualifiedType("::");
|
||||
if(find(validArgs.begin(), validArgs.end(), fullType)
|
||||
== validArgs.end())
|
||||
throw DependencyMissing(fullType, t.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
template<class T>
|
||||
void verifyReturnTypes(const vector<string>& validtypes, const vector<T>& vt) {
|
||||
BOOST_FOREACH(const T& t, vt) {
|
||||
const ReturnValue& retval = t.returnVal;
|
||||
if (find(validtypes.begin(), validtypes.end(), retval.qualifiedType1("::")) == validtypes.end())
|
||||
throw DependencyMissing(retval.qualifiedType1("::"), t.name);
|
||||
if (retval.isPair && find(validtypes.begin(), validtypes.end(), retval.qualifiedType2("::")) == validtypes.end())
|
||||
throw DependencyMissing(retval.qualifiedType2("::"), t.name);
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Module::matlab_code(const string& mexCommand, const string& toolboxPath,
|
||||
const string& mexExt, const string& headerPath,const string& mexFlags) const {
|
||||
|
||||
fs::create_directories(toolboxPath);
|
||||
|
||||
// create make m-file
|
||||
string matlabMakeFileName = toolboxPath + "/make_" + name + ".m";
|
||||
FileWriter makeModuleMfile(matlabMakeFileName, verbose, "%");
|
||||
|
||||
// create the (actual) make file
|
||||
string makeFileName = toolboxPath + "/Makefile";
|
||||
FileWriter makeModuleMakefile(makeFileName, verbose, "#");
|
||||
|
||||
makeModuleMfile.oss << "echo on" << endl << endl;
|
||||
makeModuleMfile.oss << "toolboxpath = mfilename('fullpath');" << endl;
|
||||
makeModuleMfile.oss << "delims = find(toolboxpath == '/' | toolboxpath == '\\');" << endl;
|
||||
makeModuleMfile.oss << "toolboxpath = toolboxpath(1:(delims(end)-1));" << endl;
|
||||
makeModuleMfile.oss << "clear delims" << endl;
|
||||
makeModuleMfile.oss << "addpath(toolboxpath);" << endl << endl;
|
||||
|
||||
makeModuleMakefile.oss << "\nMEX = " << mexCommand << "\n";
|
||||
makeModuleMakefile.oss << "MEXENDING = " << mexExt << "\n";
|
||||
makeModuleMakefile.oss << "PATH_TO_WRAP = " << headerPath << "\n";
|
||||
makeModuleMakefile.oss << "mex_flags = " << mexFlags << "\n\n";
|
||||
|
||||
// Dependency check list
|
||||
vector<string> validTypes = forward_declarations;
|
||||
validTypes.push_back("void");
|
||||
validTypes.push_back("string");
|
||||
validTypes.push_back("int");
|
||||
validTypes.push_back("bool");
|
||||
validTypes.push_back("char");
|
||||
validTypes.push_back("unsigned char");
|
||||
validTypes.push_back("size_t");
|
||||
validTypes.push_back("double");
|
||||
validTypes.push_back("Vector");
|
||||
validTypes.push_back("Matrix");
|
||||
|
||||
// add 'all' to Makefile
|
||||
makeModuleMakefile.oss << "all: ";
|
||||
BOOST_FOREACH(Class cls, classes) {
|
||||
makeModuleMakefile.oss << cls.qualifiedName() << " ";
|
||||
//Create a list of parsed classes for dependency checking
|
||||
validTypes.push_back(cls.qualifiedName("::"));
|
||||
}
|
||||
makeModuleMakefile.oss << "\n\n";
|
||||
|
||||
// generate proxy classes and wrappers
|
||||
BOOST_FOREACH(Class cls, classes) {
|
||||
// create directory if needed
|
||||
string classPath = toolboxPath + "/@" + cls.qualifiedName();
|
||||
fs::create_directories(classPath);
|
||||
|
||||
// create proxy class
|
||||
string classFile = classPath + "/" + cls.qualifiedName() + ".m";
|
||||
cls.matlab_proxy(classFile);
|
||||
|
||||
// verify all of the function arguments
|
||||
//TODO:verifyArguments<ArgumentList>(validTypes, cls.constructor.args_list);
|
||||
verifyArguments<StaticMethod>(validTypes, cls.static_methods);
|
||||
verifyArguments<Method>(validTypes, cls.methods);
|
||||
|
||||
// verify function return types
|
||||
verifyReturnTypes<StaticMethod>(validTypes, cls.static_methods);
|
||||
verifyReturnTypes<Method>(validTypes, cls.methods);
|
||||
|
||||
// create constructor and method wrappers
|
||||
cls.matlab_constructors(toolboxPath);
|
||||
cls.matlab_static_methods(toolboxPath);
|
||||
cls.matlab_methods(classPath);
|
||||
|
||||
// create deconstructor
|
||||
//cls.matlab_deconstructor(toolboxPath);
|
||||
|
||||
// add lines to make m-file
|
||||
makeModuleMfile.oss << "%% " << cls.qualifiedName() << endl;
|
||||
makeModuleMfile.oss << "cd(toolboxpath)" << endl;
|
||||
cls.matlab_make_fragment(makeModuleMfile, toolboxPath, mexFlags);
|
||||
|
||||
// add section to the (actual) make file
|
||||
makeModuleMakefile.oss << "# " << cls.qualifiedName() << endl;
|
||||
cls.makefile_fragment(makeModuleMakefile);
|
||||
}
|
||||
|
||||
// finish make m-file
|
||||
makeModuleMfile.oss << "cd(toolboxpath)" << endl << endl;
|
||||
makeModuleMfile.oss << "echo off" << endl;
|
||||
makeModuleMfile.emit(true); // By default, compare existing file first
|
||||
|
||||
// make clean at end of Makefile
|
||||
makeModuleMakefile.oss << "\n\nclean: \n";
|
||||
makeModuleMakefile.oss << "\trm -rf *.$(MEXENDING)\n";
|
||||
BOOST_FOREACH(Class cls, classes)
|
||||
makeModuleMakefile.oss << "\trm -rf @" << cls.qualifiedName() << "/*.$(MEXENDING)\n";
|
||||
|
||||
// finish Makefile
|
||||
makeModuleMakefile.oss << "\n" << endl;
|
||||
makeModuleMakefile.emit(true);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
/* ----------------------------------------------------------------------------
|
||||
|
||||
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||
* Atlanta, Georgia 30332-0415
|
||||
* All Rights Reserved
|
||||
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
|
||||
|
||||
* See LICENSE for the license information
|
||||
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @file Module.ccp
|
||||
* @author Frank Dellaert
|
||||
* @author Alex Cunningham
|
||||
* @author Andrew Melim
|
||||
* @author Richard Roberts
|
||||
**/
|
||||
|
||||
#include "Module.h"
|
||||
#include "FileWriter.h"
|
||||
#include "TypeAttributesTable.h"
|
||||
#include "utilities.h"
|
||||
#include "spirit_actors.h"
|
||||
|
||||
//#define BOOST_SPIRIT_DEBUG
|
||||
#include <boost/spirit/include/classic_confix.hpp>
|
||||
#include <boost/spirit/include/classic_clear_actor.hpp>
|
||||
#include <boost/spirit/include/classic_insert_at_actor.hpp>
|
||||
#include <boost/lambda/bind.hpp>
|
||||
#include <boost/lambda/lambda.hpp>
|
||||
#include <boost/lambda/construct.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
using namespace wrap;
|
||||
using namespace BOOST_SPIRIT_CLASSIC_NS;
|
||||
namespace bl = boost::lambda;
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
typedef rule<BOOST_SPIRIT_CLASSIC_NS::phrase_scanner_t> Rule;
|
||||
|
||||
/* ************************************************************************* */
|
||||
// We parse an interface file into a Module object.
|
||||
// The grammar is defined using the boost/spirit combinatorial parser.
|
||||
// For example, str_p("const") parses the string "const", and the >>
|
||||
// operator creates a sequence parser. The grammar below, composed of rules
|
||||
// and with start rule [class_p], doubles as the specs for our interface files.
|
||||
/* ************************************************************************* */
|
||||
|
||||
/* ************************************************************************* */
|
||||
void handle_possible_template(vector<Class>& classes, const Class& cls, const string& templateArgument, const vector<vector<string> >& instantiations) {
|
||||
if(instantiations.empty()) {
|
||||
classes.push_back(cls);
|
||||
} else {
|
||||
vector<Class> classInstantiations = cls.expandTemplate(templateArgument, instantiations);
|
||||
BOOST_FOREACH(const Class& c, classInstantiations) {
|
||||
classes.push_back(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Module::Module(const string& interfacePath,
|
||||
const string& moduleName, bool enable_verbose) : name(moduleName), verbose(enable_verbose)
|
||||
{
|
||||
// these variables will be imperatively updated to gradually build [cls]
|
||||
// The one with postfix 0 are used to reset the variables after parse.
|
||||
string methodName, methodName0;
|
||||
bool isConst, isConst0 = false;
|
||||
ReturnValue retVal0, retVal;
|
||||
Argument arg0, arg;
|
||||
ArgumentList args0, args;
|
||||
vector<string> arg_dup; ///keep track of duplicates
|
||||
Constructor constructor0(enable_verbose), constructor(enable_verbose);
|
||||
Deconstructor deconstructor0(enable_verbose), deconstructor(enable_verbose);
|
||||
//Method method0(enable_verbose), method(enable_verbose);
|
||||
StaticMethod static_method0(enable_verbose), static_method(enable_verbose);
|
||||
Class cls0(enable_verbose),cls(enable_verbose);
|
||||
ForwardDeclaration fwDec0, fwDec;
|
||||
vector<string> namespaces, /// current namespace tag
|
||||
namespace_includes, /// current set of includes
|
||||
namespaces_return, /// namespace for current return type
|
||||
using_namespace_current; /// All namespaces from "using" declarations
|
||||
string templateArgument;
|
||||
vector<string> templateInstantiationNamespace;
|
||||
vector<vector<string> > templateInstantiations;
|
||||
TemplateInstantiationTypedef singleInstantiation, singleInstantiation0;
|
||||
string include_path = "";
|
||||
const string null_str = "";
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Grammar with actions that build the Class object. Actions are
|
||||
// defined within the square brackets [] and are executed whenever a
|
||||
// rule is successfully parsed. Define BOOST_SPIRIT_DEBUG to debug.
|
||||
// The grammar is allows a very restricted C++ header
|
||||
// lexeme_d turns off white space skipping
|
||||
// http://www.boost.org/doc/libs/1_37_0/libs/spirit/classic/doc/directives.html
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
Rule comments_p = comment_p("/*", "*/") | comment_p("//", eol_p);
|
||||
|
||||
Rule basisType_p =
|
||||
(str_p("string") | "bool" | "size_t" | "int" | "double" | "char" | "unsigned char");
|
||||
|
||||
Rule keywords_p =
|
||||
(str_p("const") | "static" | "namespace" | basisType_p);
|
||||
|
||||
Rule eigenType_p =
|
||||
(str_p("Vector") | "Matrix");
|
||||
|
||||
Rule className_p = (lexeme_d[upper_p >> *(alnum_p | '_')] - eigenType_p - keywords_p);
|
||||
|
||||
Rule namespace_name_p = lexeme_d[lower_p >> *(alnum_p | '_')] - keywords_p;
|
||||
|
||||
Rule namespace_arg_p = namespace_name_p[push_back_a(arg.namespaces)] >> str_p("::");
|
||||
|
||||
Rule argEigenType_p =
|
||||
eigenType_p[assign_a(arg.type)] >>
|
||||
!ch_p('*')[assign_a(arg.is_ptr,true)];
|
||||
|
||||
Rule eigenRef_p =
|
||||
!str_p("const") [assign_a(arg.is_const,true)] >>
|
||||
eigenType_p [assign_a(arg.type)] >>
|
||||
ch_p('&') [assign_a(arg.is_ref,true)];
|
||||
|
||||
Rule classArg_p =
|
||||
!str_p("const") [assign_a(arg.is_const,true)] >>
|
||||
*namespace_arg_p >>
|
||||
className_p[assign_a(arg.type)] >>
|
||||
(ch_p('*')[assign_a(arg.is_ptr,true)] | ch_p('&')[assign_a(arg.is_ref,true)]);
|
||||
|
||||
Rule name_p = lexeme_d[alpha_p >> *(alnum_p | '_')];
|
||||
|
||||
Rule classParent_p =
|
||||
*(namespace_name_p[push_back_a(cls.qualifiedParent)] >> str_p("::")) >>
|
||||
className_p[push_back_a(cls.qualifiedParent)];
|
||||
|
||||
Rule templateInstantiation_p =
|
||||
(*(namespace_name_p[push_back_a(templateInstantiationNamespace)] >> str_p("::")) >>
|
||||
className_p[push_back_a(templateInstantiationNamespace)])
|
||||
[push_back_a(templateInstantiations, templateInstantiationNamespace)]
|
||||
[clear_a(templateInstantiationNamespace)];
|
||||
|
||||
Rule templateInstantiations_p =
|
||||
(str_p("template") >>
|
||||
'<' >> name_p[assign_a(templateArgument)] >> '=' >> '{' >>
|
||||
!(templateInstantiation_p >> *(',' >> templateInstantiation_p)) >>
|
||||
'}' >> '>')
|
||||
[push_back_a(cls.templateArgs, templateArgument)];
|
||||
|
||||
Rule templateSingleInstantiationArg_p =
|
||||
(*(namespace_name_p[push_back_a(templateInstantiationNamespace)] >> str_p("::")) >>
|
||||
className_p[push_back_a(templateInstantiationNamespace)])
|
||||
[push_back_a(singleInstantiation.typeList, templateInstantiationNamespace)]
|
||||
[clear_a(templateInstantiationNamespace)];
|
||||
|
||||
Rule templateSingleInstantiation_p =
|
||||
(str_p("typedef") >>
|
||||
*(namespace_name_p[push_back_a(singleInstantiation.classNamespaces)] >> str_p("::")) >>
|
||||
className_p[assign_a(singleInstantiation.className)] >>
|
||||
'<' >> templateSingleInstantiationArg_p >> *(',' >> templateSingleInstantiationArg_p) >>
|
||||
'>' >>
|
||||
className_p[assign_a(singleInstantiation.name)] >>
|
||||
';')
|
||||
[assign_a(singleInstantiation.namespaces, namespaces)]
|
||||
[push_back_a(templateInstantiationTypedefs, singleInstantiation)]
|
||||
[assign_a(singleInstantiation, singleInstantiation0)];
|
||||
|
||||
Rule templateList_p =
|
||||
(str_p("template") >>
|
||||
'<' >> name_p[push_back_a(cls.templateArgs)] >> *(',' >> name_p[push_back_a(cls.templateArgs)]) >>
|
||||
'>');
|
||||
|
||||
Rule argument_p =
|
||||
((basisType_p[assign_a(arg.type)] | argEigenType_p | eigenRef_p | classArg_p)
|
||||
>> name_p[assign_a(arg.name)])
|
||||
[push_back_a(args, arg)]
|
||||
[assign_a(arg,arg0)];
|
||||
|
||||
Rule argumentList_p = !argument_p >> * (',' >> argument_p);
|
||||
|
||||
Rule constructor_p =
|
||||
(className_p >> '(' >> argumentList_p >> ')' >> ';' >> !comments_p)
|
||||
[push_back_a(constructor.args_list, args)]
|
||||
[assign_a(args,args0)];
|
||||
//[assign_a(constructor.args,args)]
|
||||
//[assign_a(constructor.name,cls.name)]
|
||||
//[push_back_a(cls.constructors, constructor)]
|
||||
//[assign_a(constructor,constructor0)];
|
||||
|
||||
Rule namespace_ret_p = namespace_name_p[push_back_a(namespaces_return)] >> str_p("::");
|
||||
|
||||
Rule returnType1_p =
|
||||
(basisType_p[assign_a(retVal.type1)][assign_a(retVal.category1, ReturnValue::BASIS)]) |
|
||||
((*namespace_ret_p)[assign_a(retVal.namespaces1, namespaces_return)][clear_a(namespaces_return)]
|
||||
>> (className_p[assign_a(retVal.type1)][assign_a(retVal.category1, ReturnValue::CLASS)]) >>
|
||||
!ch_p('*')[assign_a(retVal.isPtr1,true)]) |
|
||||
(eigenType_p[assign_a(retVal.type1)][assign_a(retVal.category1, ReturnValue::EIGEN)]);
|
||||
|
||||
Rule returnType2_p =
|
||||
(basisType_p[assign_a(retVal.type2)][assign_a(retVal.category2, ReturnValue::BASIS)]) |
|
||||
((*namespace_ret_p)[assign_a(retVal.namespaces2, namespaces_return)][clear_a(namespaces_return)]
|
||||
>> (className_p[assign_a(retVal.type2)][assign_a(retVal.category2, ReturnValue::CLASS)]) >>
|
||||
!ch_p('*') [assign_a(retVal.isPtr2,true)]) |
|
||||
(eigenType_p[assign_a(retVal.type2)][assign_a(retVal.category2, ReturnValue::EIGEN)]);
|
||||
|
||||
Rule pair_p =
|
||||
(str_p("pair") >> '<' >> returnType1_p >> ',' >> returnType2_p >> '>')
|
||||
[assign_a(retVal.isPair,true)];
|
||||
|
||||
Rule void_p = str_p("void")[assign_a(retVal.type1)];
|
||||
|
||||
Rule returnType_p = void_p | returnType1_p | pair_p;
|
||||
|
||||
Rule methodName_p = lexeme_d[lower_p >> *(alnum_p | '_')];
|
||||
|
||||
Rule method_p =
|
||||
(returnType_p >> methodName_p[assign_a(methodName)] >>
|
||||
'(' >> argumentList_p >> ')' >>
|
||||
!str_p("const")[assign_a(isConst,true)] >> ';' >> *comments_p)
|
||||
[bl::bind(&Method::addOverload,
|
||||
bl::var(cls.methods)[bl::var(methodName)],
|
||||
verbose,
|
||||
bl::var(isConst),
|
||||
bl::var(methodName),
|
||||
bl::var(args),
|
||||
bl::var(retVal))]
|
||||
[assign_a(isConst,isConst0)]
|
||||
[assign_a(methodName,methodName0)]
|
||||
[assign_a(args,args0)]
|
||||
[assign_a(retVal,retVal0)];
|
||||
|
||||
Rule staticMethodName_p = lexeme_d[(upper_p | lower_p) >> *(alnum_p | '_')];
|
||||
|
||||
Rule static_method_p =
|
||||
(str_p("static") >> returnType_p >> staticMethodName_p[assign_a(methodName)] >>
|
||||
'(' >> argumentList_p >> ')' >> ';' >> *comments_p)
|
||||
[bl::bind(&StaticMethod::addOverload,
|
||||
bl::var(cls.static_methods)[bl::var(methodName)],
|
||||
verbose,
|
||||
bl::var(methodName),
|
||||
bl::var(args),
|
||||
bl::var(retVal))]
|
||||
[assign_a(methodName,methodName0)]
|
||||
[assign_a(args,args0)]
|
||||
[assign_a(retVal,retVal0)];
|
||||
|
||||
Rule functions_p = constructor_p | method_p | static_method_p;
|
||||
|
||||
Rule include_p = str_p("#include") >> ch_p('<') >> (*(anychar_p - '>'))[assign_a(include_path)] >> ch_p('>');
|
||||
|
||||
Rule class_p =
|
||||
(!*include_p
|
||||
>> !(templateInstantiations_p | templateList_p)
|
||||
>> !(str_p("virtual")[assign_a(cls.isVirtual, true)])
|
||||
>> str_p("class")[push_back_a(cls.includes, include_path)][assign_a(include_path, null_str)]
|
||||
>> className_p[assign_a(cls.name)]
|
||||
>> ((':' >> classParent_p >> '{') | '{')
|
||||
>> *(functions_p | comments_p)
|
||||
>> str_p("};"))
|
||||
[assign_a(constructor.name, cls.name)]
|
||||
[assign_a(cls.constructor, constructor)]
|
||||
[assign_a(cls.namespaces, namespaces)]
|
||||
[assign_a(cls.using_namespaces, using_namespace_current)]
|
||||
[append_a(cls.includes, namespace_includes)]
|
||||
[assign_a(deconstructor.name,cls.name)]
|
||||
[assign_a(cls.deconstructor, deconstructor)]
|
||||
[bl::bind(&handle_possible_template, bl::var(classes), bl::var(cls), bl::var(templateArgument), bl::var(templateInstantiations))]
|
||||
[assign_a(deconstructor,deconstructor0)]
|
||||
[assign_a(constructor, constructor0)]
|
||||
[assign_a(cls,cls0)]
|
||||
[clear_a(templateArgument)]
|
||||
[clear_a(templateInstantiations)];
|
||||
|
||||
Rule namespace_def_p =
|
||||
(!*include_p
|
||||
>> str_p("namespace")[push_back_a(namespace_includes, include_path)][assign_a(include_path, null_str)]
|
||||
>> namespace_name_p[push_back_a(namespaces)]
|
||||
>> ch_p('{')
|
||||
>> *(class_p | templateSingleInstantiation_p | namespace_def_p | comments_p)
|
||||
>> str_p("}///\\namespace") // end namespace, avoid confusion with classes
|
||||
>> !namespace_name_p)
|
||||
[pop_a(namespaces)]
|
||||
[pop_a(namespace_includes)];
|
||||
|
||||
Rule using_namespace_p =
|
||||
str_p("using") >> str_p("namespace")
|
||||
>> namespace_name_p[push_back_a(using_namespace_current)] >> ch_p(';');
|
||||
|
||||
Rule forward_declaration_p =
|
||||
!(str_p("virtual")[assign_a(fwDec.isVirtual, true)])
|
||||
>> str_p("class")
|
||||
>> (*(namespace_name_p >> str_p("::")) >> className_p)[assign_a(fwDec.name)]
|
||||
>> ch_p(';')
|
||||
[push_back_a(forward_declarations, fwDec)]
|
||||
[assign_a(fwDec, fwDec0)];
|
||||
|
||||
Rule module_content_p = comments_p | using_namespace_p | class_p | templateSingleInstantiation_p | forward_declaration_p | namespace_def_p ;
|
||||
|
||||
Rule module_p = *module_content_p >> !end_p;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// for debugging, define BOOST_SPIRIT_DEBUG
|
||||
# ifdef BOOST_SPIRIT_DEBUG
|
||||
BOOST_SPIRIT_DEBUG_NODE(className_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(classPtr_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(classRef_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(basisType_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(name_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(argument_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(argumentList_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(constructor_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(returnType1_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(returnType2_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(pair_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(void_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(returnType_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(methodName_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(method_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(class_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(namespace_def_p);
|
||||
BOOST_SPIRIT_DEBUG_NODE(module_p);
|
||||
# endif
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// read interface file
|
||||
string interfaceFile = interfacePath + "/" + moduleName + ".h";
|
||||
string contents = file_contents(interfaceFile);
|
||||
|
||||
// and parse contents
|
||||
parse_info<const char*> info = parse(contents.c_str(), module_p, space_p);
|
||||
if(!info.full) {
|
||||
printf("parsing stopped at \n%.20s\n",info.stop);
|
||||
throw ParseFailed((int)info.length);
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
template<class T>
|
||||
void verifyArguments(const vector<string>& validArgs, const map<string,T>& vt) {
|
||||
typedef typename map<string,T>::value_type Name_Method;
|
||||
BOOST_FOREACH(const Name_Method& name_method, vt) {
|
||||
const T& t = name_method.second;
|
||||
BOOST_FOREACH(const ArgumentList& argList, t.argLists) {
|
||||
BOOST_FOREACH(Argument arg, argList) {
|
||||
string fullType = arg.qualifiedType("::");
|
||||
if(find(validArgs.begin(), validArgs.end(), fullType)
|
||||
== validArgs.end())
|
||||
throw DependencyMissing(fullType, t.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
template<class T>
|
||||
void verifyReturnTypes(const vector<string>& validtypes, const map<string,T>& vt) {
|
||||
typedef typename map<string,T>::value_type Name_Method;
|
||||
BOOST_FOREACH(const Name_Method& name_method, vt) {
|
||||
const T& t = name_method.second;
|
||||
BOOST_FOREACH(const ReturnValue& retval, t.returnVals) {
|
||||
if (find(validtypes.begin(), validtypes.end(), retval.qualifiedType1("::")) == validtypes.end())
|
||||
throw DependencyMissing(retval.qualifiedType1("::"), t.name);
|
||||
if (retval.isPair && find(validtypes.begin(), validtypes.end(), retval.qualifiedType2("::")) == validtypes.end())
|
||||
throw DependencyMissing(retval.qualifiedType2("::"), t.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Module::generateIncludes(FileWriter& file) const {
|
||||
|
||||
// collect includes
|
||||
vector<string> all_includes;
|
||||
BOOST_FOREACH(const Class& cls, classes) {
|
||||
bool added_include = false;
|
||||
BOOST_FOREACH(const string& s, cls.includes) {
|
||||
if (!s.empty()) {
|
||||
all_includes.push_back(s);
|
||||
added_include = true;
|
||||
}
|
||||
}
|
||||
if (!added_include) // add default include
|
||||
all_includes.push_back(cls.name + ".h");
|
||||
}
|
||||
|
||||
// sort and remove duplicates
|
||||
sort(all_includes.begin(), all_includes.end());
|
||||
vector<string>::const_iterator last_include = unique(all_includes.begin(), all_includes.end());
|
||||
vector<string>::const_iterator it = all_includes.begin();
|
||||
// add includes to file
|
||||
for (; it != last_include; ++it)
|
||||
file.oss << "#include <" << *it << ">" << endl;
|
||||
file.oss << "\n";
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Module::matlab_code(const string& toolboxPath, const string& headerPath) const {
|
||||
|
||||
fs::create_directories(toolboxPath);
|
||||
|
||||
// create the unified .cpp switch file
|
||||
const string wrapperName = name + "_wrapper";
|
||||
string wrapperFileName = toolboxPath + "/" + wrapperName + ".cpp";
|
||||
FileWriter wrapperFile(wrapperFileName, verbose, "//");
|
||||
vector<string> functionNames; // Function names stored by index for switch
|
||||
wrapperFile.oss << "#include <wrap/matlab.h>\n";
|
||||
wrapperFile.oss << "#include <map>\n";
|
||||
wrapperFile.oss << "#include <boost/foreach.hpp>\n";
|
||||
wrapperFile.oss << "\n";
|
||||
|
||||
// Expand templates - This is done first so that template instantiations are
|
||||
// counted in the list of valid types, have their attributes and dependencies
|
||||
// checked, etc.
|
||||
vector<Class> expandedClasses = ExpandTypedefInstantiations(classes, templateInstantiationTypedefs);
|
||||
|
||||
// Dependency check list
|
||||
vector<string> validTypes = GenerateValidTypes(expandedClasses, forward_declarations);
|
||||
|
||||
// Check that all classes have been defined somewhere
|
||||
BOOST_FOREACH(const Class& cls, expandedClasses) {
|
||||
// verify all of the function arguments
|
||||
//TODO:verifyArguments<ArgumentList>(validTypes, cls.constructor.args_list);
|
||||
verifyArguments<StaticMethod>(validTypes, cls.static_methods);
|
||||
verifyArguments<Method>(validTypes, cls.methods);
|
||||
|
||||
// verify function return types
|
||||
verifyReturnTypes<StaticMethod>(validTypes, cls.static_methods);
|
||||
verifyReturnTypes<Method>(validTypes, cls.methods);
|
||||
|
||||
// verify parents
|
||||
if(!cls.qualifiedParent.empty() && std::find(validTypes.begin(), validTypes.end(), wrap::qualifiedName("::", cls.qualifiedParent)) == validTypes.end())
|
||||
throw DependencyMissing(wrap::qualifiedName("::", cls.qualifiedParent), cls.qualifiedName("::"));
|
||||
}
|
||||
|
||||
// Create type attributes table and check validity
|
||||
TypeAttributesTable typeAttributes;
|
||||
typeAttributes.addClasses(expandedClasses);
|
||||
typeAttributes.addForwardDeclarations(forward_declarations);
|
||||
typeAttributes.checkValidity(expandedClasses);
|
||||
|
||||
// Generate includes while avoiding redundant includes
|
||||
generateIncludes(wrapperFile);
|
||||
|
||||
// create typedef classes - we put this at the top of the wrap file so that collectors and method arguments can use these typedefs
|
||||
BOOST_FOREACH(const Class& cls, expandedClasses) {
|
||||
if(!cls.typedefName.empty())
|
||||
wrapperFile.oss << cls.getTypedef() << "\n";
|
||||
}
|
||||
wrapperFile.oss << "\n";
|
||||
|
||||
// Generate collectors and cleanup function to be called from mexAtExit
|
||||
WriteCollectorsAndCleanupFcn(wrapperFile, name, expandedClasses);
|
||||
|
||||
// generate RTTI registry (for returning derived-most types)
|
||||
WriteRTTIRegistry(wrapperFile, name, expandedClasses);
|
||||
|
||||
// create proxy class and wrapper code
|
||||
BOOST_FOREACH(const Class& cls, expandedClasses) {
|
||||
string classFile = toolboxPath + "/" + cls.qualifiedName() + ".m";
|
||||
cls.matlab_proxy(classFile, wrapperName, typeAttributes, wrapperFile, functionNames);
|
||||
}
|
||||
|
||||
// finish wrapper file
|
||||
wrapperFile.oss << "\n";
|
||||
finish_wrapper(wrapperFile, functionNames);
|
||||
|
||||
wrapperFile.emit(true);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Module::finish_wrapper(FileWriter& file, const std::vector<std::string>& functionNames) const {
|
||||
file.oss << "void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])\n";
|
||||
file.oss << "{\n";
|
||||
file.oss << " mstream mout;\n"; // Send stdout to MATLAB console, see matlab.h
|
||||
file.oss << " std::streambuf *outbuf = std::cout.rdbuf(&mout);\n\n";
|
||||
file.oss << " if(!_RTTIRegister_" << name << "_done) {\n";
|
||||
file.oss << " _" << name << "_RTTIRegister();\n";
|
||||
file.oss << " _RTTIRegister_" << name << "_done = true;\n";
|
||||
file.oss << " }\n";
|
||||
file.oss << " int id = unwrap<int>(in[0]);\n\n";
|
||||
file.oss << " switch(id) {\n";
|
||||
for(size_t id = 0; id < functionNames.size(); ++id) {
|
||||
file.oss << " case " << id << ":\n";
|
||||
file.oss << " " << functionNames[id] << "(nargout, out, nargin-1, in+1);\n";
|
||||
file.oss << " break;\n";
|
||||
}
|
||||
file.oss << " }\n";
|
||||
file.oss << "\n";
|
||||
file.oss << " std::cout.rdbuf(outbuf);\n"; // Restore cout, see matlab.h
|
||||
file.oss << "}\n";
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
vector<Class> Module::ExpandTypedefInstantiations(const vector<Class>& classes, const vector<TemplateInstantiationTypedef> instantiations) {
|
||||
|
||||
vector<Class> expandedClasses = classes;
|
||||
|
||||
BOOST_FOREACH(const TemplateInstantiationTypedef& inst, instantiations) {
|
||||
// Add the new class to the list
|
||||
expandedClasses.push_back(inst.findAndExpand(classes));
|
||||
}
|
||||
|
||||
// Remove all template classes
|
||||
for(int i = 0; i < expandedClasses.size(); ++i)
|
||||
if(!expandedClasses[size_t(i)].templateArgs.empty()) {
|
||||
expandedClasses.erase(expandedClasses.begin() + size_t(i));
|
||||
-- i;
|
||||
}
|
||||
|
||||
return expandedClasses;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
vector<string> Module::GenerateValidTypes(const vector<Class>& classes, const vector<ForwardDeclaration> forwardDeclarations) {
|
||||
vector<string> validTypes;
|
||||
BOOST_FOREACH(const ForwardDeclaration& fwDec, forwardDeclarations) {
|
||||
validTypes.push_back(fwDec.name);
|
||||
}
|
||||
validTypes.push_back("void");
|
||||
validTypes.push_back("string");
|
||||
validTypes.push_back("int");
|
||||
validTypes.push_back("bool");
|
||||
validTypes.push_back("char");
|
||||
validTypes.push_back("unsigned char");
|
||||
validTypes.push_back("size_t");
|
||||
validTypes.push_back("double");
|
||||
validTypes.push_back("Vector");
|
||||
validTypes.push_back("Matrix");
|
||||
//Create a list of parsed classes for dependency checking
|
||||
BOOST_FOREACH(const Class& cls, classes) {
|
||||
validTypes.push_back(cls.qualifiedName("::"));
|
||||
}
|
||||
|
||||
return validTypes;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Module::WriteCollectorsAndCleanupFcn(FileWriter& wrapperFile, const std::string& moduleName, const std::vector<Class>& classes) {
|
||||
// Generate all collectors
|
||||
BOOST_FOREACH(const Class& cls, classes) {
|
||||
const string matlabName = cls.qualifiedName(), cppName = cls.qualifiedName("::");
|
||||
wrapperFile.oss << "typedef std::set<boost::shared_ptr<" << cppName << ">*> "
|
||||
<< "Collector_" << matlabName << ";\n";
|
||||
wrapperFile.oss << "static Collector_" << matlabName <<
|
||||
" collector_" << matlabName << ";\n";
|
||||
}
|
||||
|
||||
// generate mexAtExit cleanup function
|
||||
wrapperFile.oss << "\nvoid _deleteAllObjects()\n";
|
||||
wrapperFile.oss << "{\n";
|
||||
BOOST_FOREACH(const Class& cls, classes) {
|
||||
const string matlabName = cls.qualifiedName();
|
||||
const string cppName = cls.qualifiedName("::");
|
||||
const string collectorType = "Collector_" + matlabName;
|
||||
const string collectorName = "collector_" + matlabName;
|
||||
wrapperFile.oss << " for(" << collectorType << "::iterator iter = " << collectorName << ".begin();\n";
|
||||
wrapperFile.oss << " iter != " << collectorName << ".end(); ) {\n";
|
||||
wrapperFile.oss << " delete *iter;\n";
|
||||
wrapperFile.oss << " " << collectorName << ".erase(iter++);\n";
|
||||
wrapperFile.oss << " }\n";
|
||||
}
|
||||
wrapperFile.oss << "}\n\n";
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Module::WriteRTTIRegistry(FileWriter& wrapperFile, const std::string& moduleName, const std::vector<Class>& classes) {
|
||||
wrapperFile.oss <<
|
||||
"static bool _RTTIRegister_" << moduleName << "_done = false;\n"
|
||||
"void _" << moduleName << "_RTTIRegister() {\n"
|
||||
" std::map<std::string, std::string> types;\n";
|
||||
BOOST_FOREACH(const Class& cls, classes) {
|
||||
if(cls.isVirtual)
|
||||
wrapperFile.oss <<
|
||||
" types.insert(std::make_pair(typeid(" << cls.qualifiedName("::") << ").name(), \"" << cls.qualifiedName() << "\"));\n";
|
||||
}
|
||||
wrapperFile.oss << "\n";
|
||||
|
||||
wrapperFile.oss <<
|
||||
" mxArray *registry = mexGetVariable(\"global\", \"gtsamwrap_rttiRegistry\");\n"
|
||||
" if(!registry)\n"
|
||||
" registry = mxCreateStructMatrix(1, 1, 0, NULL);\n"
|
||||
" typedef std::pair<std::string, std::string> StringPair;\n"
|
||||
" BOOST_FOREACH(const StringPair& rtti_matlab, types) {\n"
|
||||
" int fieldId = mxAddField(registry, rtti_matlab.first.c_str());\n"
|
||||
" if(fieldId < 0)\n"
|
||||
" mexErrMsgTxt(\"gtsam wrap: Error indexing RTTI types, inheritance will not work correctly\");\n"
|
||||
" mxArray *matlabName = mxCreateString(rtti_matlab.second.c_str());\n"
|
||||
" mxSetFieldByNumber(registry, 0, fieldId, matlabName);\n"
|
||||
" }\n"
|
||||
" if(mexPutVariable(\"global\", \"gtsamwrap_rttiRegistry\", registry) != 0)\n"
|
||||
" mexErrMsgTxt(\"gtsam wrap: Error indexing RTTI types, inheritance will not work correctly\");\n"
|
||||
" mxDestroyArray(registry);\n"
|
||||
"}\n"
|
||||
"\n";
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
|
|
|||
|
|
@ -13,14 +13,18 @@
|
|||
* @file Module.h
|
||||
* @brief describes module to be wrapped
|
||||
* @author Frank Dellaert
|
||||
* @author Richard Roberts
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "Class.h"
|
||||
#include "TemplateInstantiationTypedef.h"
|
||||
#include "ForwardDeclaration.h"
|
||||
|
||||
namespace wrap {
|
||||
|
||||
|
|
@ -28,11 +32,13 @@ namespace wrap {
|
|||
* A module just has a name and a list of classes
|
||||
*/
|
||||
struct Module {
|
||||
|
||||
std::string name; ///< module name
|
||||
std::vector<Class> classes; ///< list of classes
|
||||
std::vector<TemplateInstantiationTypedef> templateInstantiationTypedefs; ///< list of template instantiations
|
||||
bool verbose; ///< verbose flag
|
||||
// std::vector<std::string> using_namespaces; ///< all default namespaces
|
||||
std::vector<std::string> forward_declarations;
|
||||
std::vector<ForwardDeclaration> forward_declarations;
|
||||
|
||||
/// constructor that parses interface file
|
||||
Module(const std::string& interfacePath,
|
||||
|
|
@ -41,11 +47,18 @@ struct Module {
|
|||
|
||||
/// MATLAB code generation:
|
||||
void matlab_code(
|
||||
const std::string& mexCommand,
|
||||
const std::string& path,
|
||||
const std::string& mexExt,
|
||||
const std::string& headerPath,
|
||||
const std::string& mexFlags) const;
|
||||
const std::string& headerPath) const;
|
||||
|
||||
void finish_wrapper(FileWriter& file, const std::vector<std::string>& functionNames) const;
|
||||
|
||||
void generateIncludes(FileWriter& file) const;
|
||||
|
||||
private:
|
||||
static std::vector<Class> ExpandTypedefInstantiations(const std::vector<Class>& classes, const std::vector<TemplateInstantiationTypedef> instantiations);
|
||||
static std::vector<std::string> GenerateValidTypes(const std::vector<Class>& classes, const std::vector<ForwardDeclaration> forwardDeclarations);
|
||||
static void WriteCollectorsAndCleanupFcn(FileWriter& wrapperFile, const std::string& moduleName, const std::vector<Class>& classes);
|
||||
static void WriteRTTIRegistry(FileWriter& wrapperFile, const std::string& moduleName, const std::vector<Class>& classes);
|
||||
};
|
||||
|
||||
} // \namespace wrap
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
* @date Dec 1, 2011
|
||||
* @author Alex Cunningham
|
||||
* @author Andrew Melim
|
||||
* @author Richard Roberts
|
||||
*/
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
|
@ -46,45 +47,78 @@ string ReturnValue::qualifiedType2(const string& delim) const {
|
|||
|
||||
/* ************************************************************************* */
|
||||
//TODO:Fix this
|
||||
void ReturnValue::wrap_result(FileWriter& file) const {
|
||||
void ReturnValue::wrap_result(const string& result, FileWriter& file, const TypeAttributesTable& typeAttributes) const {
|
||||
string cppType1 = qualifiedType1("::"), matlabType1 = qualifiedType1();
|
||||
string cppType2 = qualifiedType2("::"), matlabType2 = qualifiedType2();
|
||||
|
||||
if (isPair) {
|
||||
// first return value in pair
|
||||
if (isPtr1) {// if we already have a pointer
|
||||
file.oss << " Shared" << type1 <<"* ret = new Shared" << type1 << "(result.first);" << endl;
|
||||
file.oss << " out[0] = wrap_collect_shared_ptr(ret,\"" << matlabType1 << "\");\n";
|
||||
}
|
||||
else if (category1 == ReturnValue::CLASS) { // if we are going to make one
|
||||
file.oss << " Shared" << type1 << "* ret = new Shared" << type1 << "(new " << cppType1 << "(result.first));\n";
|
||||
file.oss << " out[0] = wrap_collect_shared_ptr(ret,\"" << matlabType1 << "\");\n";
|
||||
}
|
||||
else // if basis type
|
||||
file.oss << " out[0] = wrap< " << return_type(true,arg1) << " >(result.first);\n";
|
||||
if (category1 == ReturnValue::CLASS) { // if we are going to make one
|
||||
string objCopy, ptrType;
|
||||
ptrType = "Shared" + type1;
|
||||
const bool isVirtual = typeAttributes.at(cppType1).isVirtual;
|
||||
if(isVirtual) {
|
||||
if(isPtr1)
|
||||
objCopy = result + ".first";
|
||||
else
|
||||
objCopy = result + ".first.clone()";
|
||||
} else {
|
||||
if(isPtr1)
|
||||
objCopy = result + ".first";
|
||||
else
|
||||
objCopy = ptrType + "(new " + cppType1 + "(" + result + ".first))";
|
||||
}
|
||||
file.oss << " out[0] = wrap_shared_ptr(" << objCopy << ",\"" << matlabType1 << "\", " << (isVirtual ? "true" : "false") << ");\n";
|
||||
} else if(isPtr1) {
|
||||
file.oss << " Shared" << type1 <<"* ret = new Shared" << type1 << "(" << result << ".first);" << endl;
|
||||
file.oss << " out[0] = wrap_shared_ptr(ret,\"" << matlabType1 << "\", false);\n";
|
||||
} else // if basis type
|
||||
file.oss << " out[0] = wrap< " << return_type(true,arg1) << " >(" << result << ".first);\n";
|
||||
|
||||
// second return value in pair
|
||||
if (isPtr2) {// if we already have a pointer
|
||||
file.oss << " Shared" << type2 <<"* ret = new Shared" << type2 << "(result.second);" << endl;
|
||||
file.oss << " out[1] = wrap_collect_shared_ptr(ret,\"" << matlabType2 << "\");\n";
|
||||
}
|
||||
else if (category2 == ReturnValue::CLASS) { // if we are going to make one
|
||||
file.oss << " Shared" << type2 << "* ret = new Shared" << type2 << "(new " << cppType2 << "(result.first));\n";
|
||||
file.oss << " out[0] = wrap_collect_shared_ptr(ret,\"" << matlabType2 << "\");\n";
|
||||
}
|
||||
else
|
||||
file.oss << " out[1] = wrap< " << return_type(true,arg2) << " >(result.second);\n";
|
||||
}
|
||||
else if (isPtr1){
|
||||
file.oss << " Shared" << type1 <<"* ret = new Shared" << type1 << "(result);" << endl;
|
||||
file.oss << " out[0] = wrap_collect_shared_ptr(ret,\"" << matlabType1 << "\");\n";
|
||||
if (category2 == ReturnValue::CLASS) { // if we are going to make one
|
||||
string objCopy, ptrType;
|
||||
ptrType = "Shared" + type2;
|
||||
const bool isVirtual = typeAttributes.at(cppType2).isVirtual;
|
||||
if(isVirtual) {
|
||||
if(isPtr2)
|
||||
objCopy = result + ".second";
|
||||
else
|
||||
objCopy = result + ".second.clone()";
|
||||
} else {
|
||||
if(isPtr2)
|
||||
objCopy = result + ".second";
|
||||
else
|
||||
objCopy = ptrType + "(new " + cppType2 + "(" + result + ".second))";
|
||||
}
|
||||
file.oss << " out[0] = wrap_shared_ptr(" << objCopy << ",\"" << matlabType2 << "\", " << (isVirtual ? "true" : "false") << ");\n";
|
||||
} else if(isPtr2) {
|
||||
file.oss << " Shared" << type2 <<"* ret = new Shared" << type2 << "(" << result << ".second);" << endl;
|
||||
file.oss << " out[1] = wrap_shared_ptr(ret,\"" << matlabType2 << "\");\n";
|
||||
} else
|
||||
file.oss << " out[1] = wrap< " << return_type(true,arg2) << " >(" << result << ".second);\n";
|
||||
}
|
||||
else if (category1 == ReturnValue::CLASS){
|
||||
file.oss << " Shared" << type1 << "* ret = new Shared" << type1 << "(new " << cppType1 << "(result));\n";
|
||||
file.oss << " out[0] = wrap_collect_shared_ptr(ret,\"" << matlabType1 << "\");\n";
|
||||
}
|
||||
else if (matlabType1!="void")
|
||||
file.oss << " out[0] = wrap< " << return_type(true,arg1) << " >(result);\n";
|
||||
string objCopy, ptrType;
|
||||
ptrType = "Shared" + type1;
|
||||
const bool isVirtual = typeAttributes.at(cppType1).isVirtual;
|
||||
if(isVirtual) {
|
||||
if(isPtr1)
|
||||
objCopy = result;
|
||||
else
|
||||
objCopy = result + ".clone()";
|
||||
} else {
|
||||
if(isPtr1)
|
||||
objCopy = result;
|
||||
else
|
||||
objCopy = ptrType + "(new " + cppType1 + "(" + result + "))";
|
||||
}
|
||||
file.oss << " out[0] = wrap_shared_ptr(" << objCopy << ",\"" << matlabType1 << "\", " << (isVirtual ? "true" : "false") << ");\n";
|
||||
} else if(isPtr1) {
|
||||
file.oss << " Shared" << type1 <<"* ret = new Shared" << type1 << "(" << result << ");" << endl;
|
||||
file.oss << " out[0] = wrap_shared_ptr(ret,\"" << matlabType1 << "\");\n";
|
||||
} else if (matlabType1!="void")
|
||||
file.oss << " out[0] = wrap< " << return_type(true,arg1) << " >(" << result << ");\n";
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
|
|
|||
|
|
@ -5,11 +5,14 @@
|
|||
*
|
||||
* @date Dec 1, 2011
|
||||
* @author Alex Cunningham
|
||||
* @author Richard Roberts
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "FileWriter.h"
|
||||
#include "TypeAttributesTable.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
|
|
@ -47,7 +50,7 @@ struct ReturnValue {
|
|||
|
||||
std::string matlab_returnType() const;
|
||||
|
||||
void wrap_result(FileWriter& file) const;
|
||||
void wrap_result(const std::string& result, FileWriter& file, const TypeAttributesTable& typeAttributes) const;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -13,12 +13,14 @@
|
|||
* @file StaticMethod.ccp
|
||||
* @author Frank Dellaert
|
||||
* @author Andrew Melim
|
||||
* @author Richard Roberts
|
||||
**/
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "StaticMethod.h"
|
||||
#include "utilities.h"
|
||||
|
|
@ -26,80 +28,131 @@
|
|||
using namespace std;
|
||||
using namespace wrap;
|
||||
|
||||
|
||||
/* ************************************************************************* */
|
||||
void StaticMethod::matlab_mfile(const string& toolboxPath, const string& className) const {
|
||||
void StaticMethod::addOverload(bool verbose, const std::string& name,
|
||||
const ArgumentList& args, const ReturnValue& retVal) {
|
||||
this->verbose = verbose;
|
||||
this->name = name;
|
||||
this->argLists.push_back(args);
|
||||
this->returnVals.push_back(retVal);
|
||||
}
|
||||
|
||||
// open destination m-file
|
||||
string full_name = className + "_" + name;
|
||||
string wrapperFile = toolboxPath + "/" + full_name + ".m";
|
||||
FileWriter file(wrapperFile, verbose, "%");
|
||||
void StaticMethod::proxy_wrapper_fragments(FileWriter& proxyFile, FileWriter& wrapperFile,
|
||||
const string& cppClassName,
|
||||
const string& matlabClassName,
|
||||
const string& wrapperName,
|
||||
const vector<string>& using_namespaces,
|
||||
const TypeAttributesTable& typeAttributes,
|
||||
vector<string>& functionNames) const {
|
||||
|
||||
// generate code
|
||||
string returnType = returnVal.matlab_returnType();
|
||||
file.oss << "function " << returnType << " = " << full_name << "(";
|
||||
if (args.size()) file.oss << args.names();
|
||||
file.oss << ")" << endl;
|
||||
file.oss << "% usage: x = " << full_name << "(" << args.names() << ")" << endl;
|
||||
file.oss << " error('need to compile " << full_name << ".cpp');" << endl;
|
||||
file.oss << "end" << endl;
|
||||
string upperName = name; upperName[0] = std::toupper(upperName[0], std::locale());
|
||||
|
||||
// close file
|
||||
file.emit(true);
|
||||
proxyFile.oss << " function varargout = " << upperName << "(varargin)\n";
|
||||
|
||||
for(size_t overload = 0; overload < argLists.size(); ++overload) {
|
||||
const ArgumentList& args = argLists[overload];
|
||||
const ReturnValue& returnVal = returnVals[overload];
|
||||
size_t nrArgs = args.size();
|
||||
|
||||
const int id = functionNames.size();
|
||||
|
||||
// Output proxy matlab code
|
||||
|
||||
// check for number of arguments...
|
||||
proxyFile.oss << " " << (overload==0?"":"else") << "if length(varargin) == " << nrArgs;
|
||||
if (nrArgs>0) proxyFile.oss << " && ";
|
||||
// ...and their types
|
||||
bool first = true;
|
||||
for(size_t i=0;i<nrArgs;i++) {
|
||||
if (!first) proxyFile.oss << " && ";
|
||||
proxyFile.oss << "isa(varargin{" << i+1 << "},'" << args[i].matlabClass() << "')";
|
||||
first=false;
|
||||
}
|
||||
proxyFile.oss << "\n";
|
||||
|
||||
// output call to C++ wrapper
|
||||
string output;
|
||||
if(returnVal.isPair)
|
||||
output = "[ varargout{1} varargout{2} ] = ";
|
||||
else if(returnVal.category1 == ReturnValue::VOID)
|
||||
output = "";
|
||||
else
|
||||
output = "varargout{1} = ";
|
||||
proxyFile.oss << " " << output << wrapperName << "(" << id << ", varargin{:});\n";
|
||||
|
||||
// Output C++ wrapper code
|
||||
|
||||
const string wrapFunctionName = wrapper_fragment(
|
||||
wrapperFile, cppClassName, matlabClassName, overload, id, using_namespaces, typeAttributes);
|
||||
|
||||
// Add to function list
|
||||
functionNames.push_back(wrapFunctionName);
|
||||
|
||||
}
|
||||
|
||||
proxyFile.oss << " else\n";
|
||||
proxyFile.oss << " error('Arguments do not match any overload of function " <<
|
||||
matlabClassName << "." << upperName << "');" << endl;
|
||||
|
||||
proxyFile.oss << " end\n";
|
||||
proxyFile.oss << " end\n";
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void StaticMethod::matlab_wrapper(const string& toolboxPath, const string& className,
|
||||
const string& matlabClassName, const string& cppClassName,
|
||||
const vector<string>& using_namespaces,
|
||||
const vector<string>& includes) const {
|
||||
// open destination wrapperFile
|
||||
string full_name = matlabClassName + "_" + name;
|
||||
string wrapperFile = toolboxPath + "/" + full_name + ".cpp";
|
||||
FileWriter file(wrapperFile, verbose, "//");
|
||||
string StaticMethod::wrapper_fragment(FileWriter& file,
|
||||
const string& cppClassName,
|
||||
const string& matlabClassName,
|
||||
int overload,
|
||||
int id,
|
||||
const vector<string>& using_namespaces,
|
||||
const TypeAttributesTable& typeAttributes) const {
|
||||
|
||||
// generate code
|
||||
|
||||
// header
|
||||
generateIncludes(file, className, includes);
|
||||
generateUsingNamespace(file, using_namespaces);
|
||||
const string wrapFunctionName = matlabClassName + "_" + name + "_" + boost::lexical_cast<string>(id);
|
||||
|
||||
const ArgumentList& args = argLists[overload];
|
||||
const ReturnValue& returnVal = returnVals[overload];
|
||||
|
||||
// call
|
||||
file.oss << "void " << wrapFunctionName << "(int nargout, mxArray *out[], int nargin, const mxArray *in[])\n";
|
||||
// start
|
||||
file.oss << "{\n";
|
||||
generateUsingNamespace(file, using_namespaces);
|
||||
|
||||
if(returnVal.isPair)
|
||||
{
|
||||
file.oss << "typedef boost::shared_ptr<" << returnVal.qualifiedType1("::") << "> Shared" << returnVal.type1 << ";"<< endl;
|
||||
file.oss << "typedef boost::shared_ptr<" << returnVal.qualifiedType2("::") << "> Shared" << returnVal.type2 << ";"<< endl;
|
||||
if(returnVal.category1 == ReturnValue::CLASS)
|
||||
file.oss << " typedef boost::shared_ptr<" << returnVal.qualifiedType1("::") << "> Shared" << returnVal.type1 << ";"<< endl;
|
||||
if(returnVal.category2 == ReturnValue::CLASS)
|
||||
file.oss << " typedef boost::shared_ptr<" << returnVal.qualifiedType2("::") << "> Shared" << returnVal.type2 << ";"<< endl;
|
||||
}
|
||||
else
|
||||
file.oss << "typedef boost::shared_ptr<" << returnVal.qualifiedType1("::") << "> Shared" << returnVal.type1 << ";"<< endl;
|
||||
if(returnVal.category1 == ReturnValue::CLASS)
|
||||
file.oss << " typedef boost::shared_ptr<" << returnVal.qualifiedType1("::") << "> Shared" << returnVal.type1 << ";"<< endl;
|
||||
|
||||
file.oss << "typedef boost::shared_ptr<" << cppClassName << "> Shared;" << endl;
|
||||
// call
|
||||
file.oss << "void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])\n";
|
||||
// start
|
||||
file.oss << "{\n";
|
||||
file.oss << " typedef boost::shared_ptr<" << cppClassName << "> Shared;" << endl;
|
||||
|
||||
// check arguments
|
||||
// NOTE: for static functions, there is no object passed
|
||||
file.oss << " checkArguments(\"" << full_name << "\",nargout,nargin," << args.size() << ");\n";
|
||||
file.oss << " checkArguments(\"" << matlabClassName << "." << name << "\",nargout,nargin," << args.size() << ");\n";
|
||||
|
||||
// unwrap arguments, see Argument.cpp
|
||||
args.matlab_unwrap(file,0); // We start at 0 because there is no self object
|
||||
|
||||
file.oss << " ";
|
||||
|
||||
// call method with default type
|
||||
// call method with default type and wrap result
|
||||
if (returnVal.type1!="void")
|
||||
file.oss << returnVal.return_type(true,ReturnValue::pair) << " result = ";
|
||||
file.oss << cppClassName << "::" << name << "(" << args.names() << ");\n";
|
||||
|
||||
// wrap result
|
||||
// example: out[0]=wrap<bool>(result);
|
||||
returnVal.wrap_result(file);
|
||||
returnVal.wrap_result(cppClassName+"::"+name+"("+args.names()+")", file, typeAttributes);
|
||||
else
|
||||
file.oss << cppClassName+"::"+name+"("+args.names()+");\n";
|
||||
|
||||
// finish
|
||||
file.oss << "}\n";
|
||||
|
||||
// close file
|
||||
file.emit(true);
|
||||
return wrapFunctionName;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
* @brief describes and generates code for static methods
|
||||
* @author Frank Dellaert
|
||||
* @author Alex Cunningham
|
||||
* @author Richard Roberts
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
|
@ -23,6 +24,7 @@
|
|||
|
||||
#include "Argument.h"
|
||||
#include "ReturnValue.h"
|
||||
#include "TypeAttributesTable.h"
|
||||
|
||||
namespace wrap {
|
||||
|
||||
|
|
@ -36,20 +38,31 @@ struct StaticMethod {
|
|||
// Then the instance variables are set directly by the Module constructor
|
||||
bool verbose;
|
||||
std::string name;
|
||||
ArgumentList args;
|
||||
ReturnValue returnVal;
|
||||
std::vector<ArgumentList> argLists;
|
||||
std::vector<ReturnValue> returnVals;
|
||||
|
||||
// The first time this function is called, it initializes the class members
|
||||
// with those in rhs, but in subsequent calls it adds additional argument
|
||||
// lists as function overloads.
|
||||
void addOverload(bool verbose, const std::string& name,
|
||||
const ArgumentList& args, const ReturnValue& retVal);
|
||||
|
||||
// MATLAB code generation
|
||||
// toolboxPath is the core toolbox directory, e.g., ../matlab
|
||||
// NOTE: static functions are not inside the class, and
|
||||
// are created with [ClassName]_[FunctionName]() format
|
||||
// classPath is class directory, e.g., ../matlab/@Point2
|
||||
void proxy_wrapper_fragments(FileWriter& proxyFile, FileWriter& wrapperFile,
|
||||
const std::string& cppClassName, const std::string& matlabClassName,
|
||||
const std::string& wrapperName, const std::vector<std::string>& using_namespaces,
|
||||
const TypeAttributesTable& typeAttributes,
|
||||
std::vector<std::string>& functionNames) const;
|
||||
|
||||
void matlab_mfile(const std::string& toolboxPath, const std::string& className) const; ///< m-file
|
||||
void matlab_wrapper(const std::string& toolboxPath,
|
||||
const std::string& className, const std::string& matlabClassName,
|
||||
const std::string& cppClassName,
|
||||
const std::vector<std::string>& using_namespaces,
|
||||
const std::vector<std::string>& includes) const; ///< cpp wrapper
|
||||
private:
|
||||
std::string wrapper_fragment(FileWriter& file,
|
||||
const std::string& cppClassName,
|
||||
const std::string& matlabClassname,
|
||||
int overload,
|
||||
int id,
|
||||
const std::vector<std::string>& using_namespaces,
|
||||
const TypeAttributesTable& typeAttributes) const; ///< cpp wrapper
|
||||
};
|
||||
|
||||
} // \namespace wrap
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
|
||||
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||
* Atlanta, Georgia 30332-0415
|
||||
* All Rights Reserved
|
||||
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
|
||||
|
||||
* See LICENSE for the license information
|
||||
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @file Class.cpp
|
||||
* @author Frank Dellaert
|
||||
* @author Andrew Melim
|
||||
* @author Richard Roberts
|
||||
**/
|
||||
|
||||
#include "TemplateInstantiationTypedef.h"
|
||||
|
||||
#include "utilities.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace wrap {
|
||||
|
||||
Class TemplateInstantiationTypedef::findAndExpand(const vector<Class>& classes) const {
|
||||
// Find matching class
|
||||
std::vector<Class>::const_iterator clsIt = classes.end();
|
||||
for(std::vector<Class>::const_iterator it = classes.begin(); it != classes.end(); ++it) {
|
||||
if(it->name == className && it->namespaces == classNamespaces && it->templateArgs.size() == typeList.size()) {
|
||||
clsIt = it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(clsIt == classes.end())
|
||||
throw DependencyMissing(wrap::qualifiedName("::", classNamespaces, className),
|
||||
"instantiation into typedef name " + wrap::qualifiedName("::", namespaces, name) +
|
||||
". Ensure that the typedef provides the correct number of template arguments.");
|
||||
|
||||
// Instantiate it
|
||||
Class classInst = *clsIt;
|
||||
for(size_t i = 0; i < typeList.size(); ++i)
|
||||
classInst = classInst.expandTemplate(classInst.templateArgs[i], typeList[i]);
|
||||
|
||||
// Fix class properties
|
||||
classInst.name = name;
|
||||
classInst.templateArgs.clear();
|
||||
classInst.typedefName = clsIt->qualifiedName("::") + "<";
|
||||
if(typeList.size() > 0)
|
||||
classInst.typedefName += wrap::qualifiedName("::", typeList[0]);
|
||||
for(size_t i = 1; i < typeList.size(); ++i)
|
||||
classInst.typedefName += (", " + wrap::qualifiedName("::", typeList[i]));
|
||||
classInst.typedefName += ">";
|
||||
classInst.namespaces = namespaces;
|
||||
|
||||
return classInst;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
|
||||
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||
* Atlanta, Georgia 30332-0415
|
||||
* All Rights Reserved
|
||||
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
|
||||
|
||||
* See LICENSE for the license information
|
||||
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @file Class.h
|
||||
* @brief describe the C++ class that is being wrapped
|
||||
* @author Frank Dellaert
|
||||
* @author Andrew Melim
|
||||
* @author Richard Roberts
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "Class.h"
|
||||
|
||||
namespace wrap {
|
||||
|
||||
struct TemplateInstantiationTypedef {
|
||||
std::vector<std::string> classNamespaces;
|
||||
std::string className;
|
||||
std::vector<std::string> namespaces;
|
||||
std::string name;
|
||||
std::vector<std::vector<std::string> > typeList;
|
||||
|
||||
Class findAndExpand(const std::vector<Class>& classes) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
|
||||
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||
* Atlanta, Georgia 30332-0415
|
||||
* All Rights Reserved
|
||||
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
|
||||
|
||||
* See LICENSE for the license information
|
||||
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @file Class.cpp
|
||||
* @author Frank Dellaert
|
||||
* @author Andrew Melim
|
||||
* @author Richard Roberts
|
||||
**/
|
||||
|
||||
#include "TypeAttributesTable.h"
|
||||
#include "Class.h"
|
||||
#include "utilities.h"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace wrap {
|
||||
|
||||
/* ************************************************************************* */
|
||||
void TypeAttributesTable::addClasses(const vector<Class>& classes) {
|
||||
BOOST_FOREACH(const Class& cls, classes) {
|
||||
if(!insert(make_pair(cls.qualifiedName("::"), TypeAttributes(cls.isVirtual))).second)
|
||||
throw DuplicateDefinition("class " + cls.qualifiedName("::"));
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void TypeAttributesTable::addForwardDeclarations(const vector<ForwardDeclaration>& forwardDecls) {
|
||||
BOOST_FOREACH(const ForwardDeclaration& fwDec, forwardDecls) {
|
||||
if(!insert(make_pair(fwDec.name, TypeAttributes(fwDec.isVirtual))).second)
|
||||
throw DuplicateDefinition("class " + fwDec.name);
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void TypeAttributesTable::checkValidity(const vector<Class>& classes) const {
|
||||
BOOST_FOREACH(const Class& cls, classes) {
|
||||
// Check that class is virtual if it has a parent
|
||||
if(!cls.qualifiedParent.empty() && !cls.isVirtual)
|
||||
throw AttributeError(cls.qualifiedName("::"), "Has a base class so needs to be declared virtual, change to 'virtual class "+cls.name+" ...'");
|
||||
// Check that parent is virtual as well
|
||||
if(!cls.qualifiedParent.empty() && !at(wrap::qualifiedName("::", cls.qualifiedParent)).isVirtual)
|
||||
throw AttributeError(wrap::qualifiedName("::", cls.qualifiedParent),
|
||||
"Is the base class of " + cls.qualifiedName("::") + ", so needs to be declared virtual");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
|
||||
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||
* Atlanta, Georgia 30332-0415
|
||||
* All Rights Reserved
|
||||
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
|
||||
|
||||
* See LICENSE for the license information
|
||||
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @file Class.h
|
||||
* @brief describe the C++ class that is being wrapped
|
||||
* @author Frank Dellaert
|
||||
* @author Andrew Melim
|
||||
* @author Richard Roberts
|
||||
**/
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "ForwardDeclaration.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace wrap {
|
||||
|
||||
// Forward declarations
|
||||
struct Class;
|
||||
|
||||
/** Attributes about valid classes, both for classes defined in this module and
|
||||
* also those forward-declared from others. At the moment this only contains
|
||||
* whether the class is virtual, which is used to know how to copy the class,
|
||||
* and whether to try to convert it to a more derived type upon returning it.
|
||||
*/
|
||||
struct TypeAttributes {
|
||||
bool isVirtual;
|
||||
TypeAttributes() : isVirtual(false) {}
|
||||
TypeAttributes(bool isVirtual) : isVirtual(isVirtual) {}
|
||||
};
|
||||
|
||||
/** Map of type names to attributes. */
|
||||
class TypeAttributesTable : public std::map<std::string, TypeAttributes> {
|
||||
public:
|
||||
TypeAttributesTable() {}
|
||||
|
||||
void addClasses(const std::vector<Class>& classes);
|
||||
void addForwardDeclarations(const std::vector<ForwardDeclaration>& forwardDecls);
|
||||
|
||||
void checkValidity(const std::vector<Class>& classes) const;
|
||||
};
|
||||
|
||||
}
|
||||
798
wrap/matlab.h
798
wrap/matlab.h
|
|
@ -1,372 +1,426 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
|
||||
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||
* Atlanta, Georgia 30332-0415
|
||||
* All Rights Reserved
|
||||
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
|
||||
|
||||
* See LICENSE for the license information
|
||||
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @file matlab.h
|
||||
* @brief header file to be included in MATLAB wrappers
|
||||
* @date 2008
|
||||
* @author Frank Dellaert
|
||||
*
|
||||
* wrapping and unwrapping is done using specialized templates, see
|
||||
* http://www.cplusplus.com/doc/tutorial/templates.html
|
||||
*/
|
||||
|
||||
#include <gtsam/base/Vector.h>
|
||||
#include <gtsam/base/Matrix.h>
|
||||
|
||||
using gtsam::Vector;
|
||||
using gtsam::Matrix;
|
||||
|
||||
extern "C" {
|
||||
#include <mex.h>
|
||||
}
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <typeinfo>
|
||||
#include <set>
|
||||
|
||||
using namespace std;
|
||||
using namespace boost; // not usual, but for conciseness of generated code
|
||||
|
||||
// start GTSAM Specifics /////////////////////////////////////////////////
|
||||
// to enable Matrix and Vector constructor for SharedGaussian:
|
||||
#define GTSAM_MAGIC_GAUSSIAN
|
||||
// end GTSAM Specifics /////////////////////////////////////////////////
|
||||
|
||||
#if defined(__LP64__) || defined(_WIN64)
|
||||
// 64-bit
|
||||
#define mxUINT32OR64_CLASS mxUINT64_CLASS
|
||||
#else
|
||||
#define mxUINT32OR64_CLASS mxUINT32_CLASS
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
// Utilities
|
||||
//*****************************************************************************
|
||||
|
||||
void error(const char* str) {
|
||||
mexErrMsgIdAndTxt("wrap:error", str);
|
||||
}
|
||||
|
||||
mxArray *scalar(mxClassID classid) {
|
||||
mwSize dims[1]; dims[0]=1;
|
||||
return mxCreateNumericArray(1, dims, classid, mxREAL);
|
||||
}
|
||||
|
||||
void checkScalar(const mxArray* array, const char* str) {
|
||||
int m = mxGetM(array), n = mxGetN(array);
|
||||
if (m!=1 || n!=1)
|
||||
mexErrMsgIdAndTxt("wrap: not a scalar in ", str);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// Check arguments
|
||||
//*****************************************************************************
|
||||
|
||||
void checkArguments(const string& name, int nargout, int nargin, int expected) {
|
||||
stringstream err;
|
||||
err << name << " expects " << expected << " arguments, not " << nargin;
|
||||
if (nargin!=expected)
|
||||
error(err.str().c_str());
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// wrapping C++ basis types in MATLAB arrays
|
||||
//*****************************************************************************
|
||||
|
||||
// default wrapping throws an error: only basis types are allowed in wrap
|
||||
template <typename Class>
|
||||
mxArray* wrap(Class& value) {
|
||||
error("wrap internal error: attempted wrap of invalid type");
|
||||
}
|
||||
|
||||
// specialization to string
|
||||
// wraps into a character array
|
||||
template<>
|
||||
mxArray* wrap<string>(string& value) {
|
||||
return mxCreateString(value.c_str());
|
||||
}
|
||||
|
||||
// specialization to char
|
||||
template<>
|
||||
mxArray* wrap<char>(char& value) {
|
||||
mxArray *result = scalar(mxUINT32OR64_CLASS);
|
||||
*(char*)mxGetData(result) = value;
|
||||
return result;
|
||||
}
|
||||
|
||||
// specialization to unsigned char
|
||||
template<>
|
||||
mxArray* wrap<unsigned char>(unsigned char& value) {
|
||||
mxArray *result = scalar(mxUINT32OR64_CLASS);
|
||||
*(unsigned char*)mxGetData(result) = value;
|
||||
return result;
|
||||
}
|
||||
|
||||
// specialization to bool
|
||||
template<>
|
||||
mxArray* wrap<bool>(bool& value) {
|
||||
mxArray *result = scalar(mxUINT32OR64_CLASS);
|
||||
*(bool*)mxGetData(result) = value;
|
||||
return result;
|
||||
}
|
||||
|
||||
// specialization to size_t
|
||||
template<>
|
||||
mxArray* wrap<size_t>(size_t& value) {
|
||||
mxArray *result = scalar(mxUINT32OR64_CLASS);
|
||||
*(size_t*)mxGetData(result) = value;
|
||||
return result;
|
||||
}
|
||||
|
||||
// specialization to int
|
||||
template<>
|
||||
mxArray* wrap<int>(int& value) {
|
||||
mxArray *result = scalar(mxUINT32OR64_CLASS);
|
||||
*(int*)mxGetData(result) = value;
|
||||
return result;
|
||||
}
|
||||
|
||||
// specialization to double -> just double
|
||||
template<>
|
||||
mxArray* wrap<double>(double& value) {
|
||||
return mxCreateDoubleScalar(value);
|
||||
}
|
||||
|
||||
// wrap a const Eigen vector into a double vector
|
||||
mxArray* wrap_Vector(const gtsam::Vector& v) {
|
||||
int m = v.size();
|
||||
mxArray *result = mxCreateDoubleMatrix(m, 1, mxREAL);
|
||||
double *data = mxGetPr(result);
|
||||
for (int i=0;i<m;i++) data[i]=v(i);
|
||||
return result;
|
||||
}
|
||||
|
||||
// specialization to Eigen vector -> double vector
|
||||
template<>
|
||||
mxArray* wrap<gtsam::Vector >(gtsam::Vector& v) {
|
||||
return wrap_Vector(v);
|
||||
}
|
||||
|
||||
// const version
|
||||
template<>
|
||||
mxArray* wrap<const gtsam::Vector >(const gtsam::Vector& v) {
|
||||
return wrap_Vector(v);
|
||||
}
|
||||
|
||||
// wrap a const Eigen MATRIX into a double matrix
|
||||
mxArray* wrap_Matrix(const gtsam::Matrix& A) {
|
||||
int m = A.rows(), n = A.cols();
|
||||
#ifdef DEBUG_WRAP
|
||||
mexPrintf("wrap_Matrix called with A = \n", m,n);
|
||||
gtsam::print(A);
|
||||
#endif
|
||||
mxArray *result = mxCreateDoubleMatrix(m, n, mxREAL);
|
||||
double *data = mxGetPr(result);
|
||||
// converts from column-major to row-major
|
||||
for (int j=0;j<n;j++) for (int i=0;i<m;i++,data++) *data = A(i,j);
|
||||
return result;
|
||||
}
|
||||
|
||||
// specialization to Eigen MATRIX -> double matrix
|
||||
template<>
|
||||
mxArray* wrap<gtsam::Matrix >(gtsam::Matrix& A) {
|
||||
return wrap_Matrix(A);
|
||||
}
|
||||
|
||||
// const version
|
||||
template<>
|
||||
mxArray* wrap<const gtsam::Matrix >(const gtsam::Matrix& A) {
|
||||
return wrap_Matrix(A);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// unwrapping MATLAB arrays into C++ basis types
|
||||
//*****************************************************************************
|
||||
|
||||
// default unwrapping throws an error
|
||||
// as wrap only supports passing a reference or one of the basic types
|
||||
template <typename T>
|
||||
T unwrap(const mxArray* array) {
|
||||
error("wrap internal error: attempted unwrap of invalid type");
|
||||
}
|
||||
|
||||
// specialization to string
|
||||
// expects a character array
|
||||
// Warning: relies on mxChar==char
|
||||
template<>
|
||||
string unwrap<string>(const mxArray* array) {
|
||||
char *data = mxArrayToString(array);
|
||||
if (data==NULL) error("unwrap<string>: not a character array");
|
||||
string str(data);
|
||||
mxFree(data);
|
||||
return str;
|
||||
}
|
||||
|
||||
// Check for 64-bit, as Mathworks says mxGetScalar only good for 32 bit
|
||||
template <typename T>
|
||||
T myGetScalar(const mxArray* array) {
|
||||
switch (mxGetClassID(array)) {
|
||||
case mxINT64_CLASS:
|
||||
return (T) *(int64_t*) mxGetData(array);
|
||||
case mxUINT64_CLASS:
|
||||
return (T) *(uint64_t*) mxGetData(array);
|
||||
default:
|
||||
// hope for the best!
|
||||
return (T) mxGetScalar(array);
|
||||
}
|
||||
}
|
||||
|
||||
// specialization to bool
|
||||
template<>
|
||||
bool unwrap<bool>(const mxArray* array) {
|
||||
checkScalar(array,"unwrap<bool>");
|
||||
return myGetScalar<bool>(array);
|
||||
}
|
||||
|
||||
// specialization to char
|
||||
template<>
|
||||
char unwrap<char>(const mxArray* array) {
|
||||
checkScalar(array,"unwrap<char>");
|
||||
return myGetScalar<char>(array);
|
||||
}
|
||||
|
||||
// specialization to unsigned char
|
||||
template<>
|
||||
unsigned char unwrap<unsigned char>(const mxArray* array) {
|
||||
checkScalar(array,"unwrap<unsigned char>");
|
||||
return myGetScalar<unsigned char>(array);
|
||||
}
|
||||
|
||||
// specialization to int
|
||||
template<>
|
||||
int unwrap<int>(const mxArray* array) {
|
||||
checkScalar(array,"unwrap<int>");
|
||||
return myGetScalar<int>(array);
|
||||
}
|
||||
|
||||
// specialization to size_t
|
||||
template<>
|
||||
size_t unwrap<size_t>(const mxArray* array) {
|
||||
checkScalar(array, "unwrap<size_t>");
|
||||
return myGetScalar<size_t>(array);
|
||||
}
|
||||
|
||||
// specialization to double
|
||||
template<>
|
||||
double unwrap<double>(const mxArray* array) {
|
||||
checkScalar(array,"unwrap<double>");
|
||||
return myGetScalar<double>(array);
|
||||
}
|
||||
|
||||
// specialization to Eigen vector
|
||||
template<>
|
||||
gtsam::Vector unwrap< gtsam::Vector >(const mxArray* array) {
|
||||
int m = mxGetM(array), n = mxGetN(array);
|
||||
if (mxIsDouble(array)==false || n!=1) error("unwrap<vector>: not a vector");
|
||||
#ifdef DEBUG_WRAP
|
||||
mexPrintf("unwrap< gtsam::Vector > called with %dx%d argument\n", m,n);
|
||||
#endif
|
||||
double* data = (double*)mxGetData(array);
|
||||
gtsam::Vector v(m);
|
||||
for (int i=0;i<m;i++,data++) v(i) = *data;
|
||||
#ifdef DEBUG_WRAP
|
||||
gtsam::print(v);
|
||||
#endif
|
||||
return v;
|
||||
}
|
||||
|
||||
// specialization to Eigen matrix
|
||||
template<>
|
||||
gtsam::Matrix unwrap< gtsam::Matrix >(const mxArray* array) {
|
||||
if (mxIsDouble(array)==false) error("unwrap<matrix>: not a matrix");
|
||||
int m = mxGetM(array), n = mxGetN(array);
|
||||
#ifdef DEBUG_WRAP
|
||||
mexPrintf("unwrap< gtsam::Matrix > called with %dx%d argument\n", m,n);
|
||||
#endif
|
||||
double* data = (double*)mxGetData(array);
|
||||
gtsam::Matrix A(m,n);
|
||||
// converts from row-major to column-major
|
||||
for (int j=0;j<n;j++) for (int i=0;i<m;i++,data++) A(i,j) = *data;
|
||||
#ifdef DEBUG_WRAP
|
||||
gtsam::print(A);
|
||||
#endif
|
||||
return A;
|
||||
}
|
||||
|
||||
/*
|
||||
[create_object] creates a MATLAB proxy class object with a mexhandle
|
||||
in the self property. Matlab does not allow the creation of matlab
|
||||
objects from within mex files, hence we resort to an ugly trick: we
|
||||
invoke the proxy class constructor by calling MATLAB, and pass 13
|
||||
dummy arguments to let the constructor know we want an object without
|
||||
the self property initialized. We then assign the mexhandle to self.
|
||||
*/
|
||||
mxArray* create_object(const char *classname, mxArray* h) {
|
||||
mxArray *result;
|
||||
mxArray* dummy[13] = {h,h,h,h,h, h,h,h,h,h, h,h,h};
|
||||
mexCallMATLAB(1,&result,13,dummy,classname);
|
||||
mxSetProperty(result, 0, "self", h);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Similar to create object, this also collects the shared_ptr in addition
|
||||
* to creating the dummy object. Mainly used for static constructor methods
|
||||
* which don't have direct access to the function.
|
||||
*/
|
||||
mxArray* create_collect_object(const char *classname, mxArray* h){
|
||||
mxArray *result;
|
||||
//First arg is a flag to collect
|
||||
mxArray* dummy[14] = {h,h,h,h,h, h,h,h,h,h, h,h,h,h};
|
||||
mexCallMATLAB(1,&result,14,dummy,classname);
|
||||
mxSetProperty(result, 0, "self", h);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
When the user calls a method that returns a shared pointer, we create
|
||||
an ObjectHandle from the shared_pointer and return it as a proxy
|
||||
class to matlab.
|
||||
*/
|
||||
template <typename Class>
|
||||
mxArray* wrap_shared_ptr(boost::shared_ptr< Class >* shared_ptr, const char *classname) {
|
||||
mxArray* mxh = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL);
|
||||
*reinterpret_cast<boost::shared_ptr<Class>**> (mxGetData(mxh)) = shared_ptr;
|
||||
//return mxh;
|
||||
return create_object(classname, mxh);
|
||||
}
|
||||
|
||||
template <typename Class>
|
||||
mxArray* wrap_collect_shared_ptr(boost::shared_ptr< Class >* shared_ptr, const char *classname) {
|
||||
mxArray* mxh = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL);
|
||||
*reinterpret_cast<boost::shared_ptr<Class>**> (mxGetData(mxh)) = shared_ptr;
|
||||
//return mxh;
|
||||
return create_collect_object(classname, mxh);
|
||||
}
|
||||
|
||||
template <typename Class>
|
||||
boost::shared_ptr<Class> unwrap_shared_ptr(const mxArray* obj, const string& className) {
|
||||
|
||||
mxArray* mxh = mxGetProperty(obj,0,"self");
|
||||
if (mxGetClassID(mxh) != mxUINT32OR64_CLASS || mxIsComplex(mxh)
|
||||
|| mxGetM(mxh) != 1 || mxGetN(mxh) != 1) error(
|
||||
"Parameter is not an Shared type.");
|
||||
|
||||
boost::shared_ptr<Class>* spp = *reinterpret_cast<boost::shared_ptr<Class>**> (mxGetData(mxh));
|
||||
return *spp;
|
||||
}
|
||||
/* ----------------------------------------------------------------------------
|
||||
|
||||
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||
* Atlanta, Georgia 30332-0415
|
||||
* All Rights Reserved
|
||||
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
|
||||
|
||||
* See LICENSE for the license information
|
||||
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @file matlab.h
|
||||
* @brief header file to be included in MATLAB wrappers
|
||||
* @date 2008
|
||||
* @author Frank Dellaert
|
||||
* @author Alex Cunningham
|
||||
* @author Andrew Melim
|
||||
* @author Richard Roberts
|
||||
*
|
||||
* wrapping and unwrapping is done using specialized templates, see
|
||||
* http://www.cplusplus.com/doc/tutorial/templates.html
|
||||
*/
|
||||
|
||||
#include <gtsam/base/Vector.h>
|
||||
#include <gtsam/base/Matrix.h>
|
||||
|
||||
using gtsam::Vector;
|
||||
using gtsam::Matrix;
|
||||
|
||||
extern "C" {
|
||||
#include <mex.h>
|
||||
}
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <typeinfo>
|
||||
#include <set>
|
||||
#include <streambuf>
|
||||
|
||||
using namespace std;
|
||||
using namespace boost; // not usual, but for conciseness of generated code
|
||||
|
||||
// start GTSAM Specifics /////////////////////////////////////////////////
|
||||
// to enable Matrix and Vector constructor for SharedGaussian:
|
||||
#define GTSAM_MAGIC_GAUSSIAN
|
||||
// end GTSAM Specifics /////////////////////////////////////////////////
|
||||
|
||||
#if defined(__LP64__) || defined(_WIN64)
|
||||
// 64-bit
|
||||
#define mxUINT32OR64_CLASS mxUINT64_CLASS
|
||||
#else
|
||||
#define mxUINT32OR64_CLASS mxUINT32_CLASS
|
||||
#endif
|
||||
|
||||
// "Unique" key to signal calling the matlab object constructor with a raw pointer
|
||||
// to a shared pointer of the same C++ object type as the MATLAB type.
|
||||
// Also present in utilities.h
|
||||
static const uint64_t ptr_constructor_key =
|
||||
(uint64_t('G') << 56) |
|
||||
(uint64_t('T') << 48) |
|
||||
(uint64_t('S') << 40) |
|
||||
(uint64_t('A') << 32) |
|
||||
(uint64_t('M') << 24) |
|
||||
(uint64_t('p') << 16) |
|
||||
(uint64_t('t') << 8) |
|
||||
(uint64_t('r'));
|
||||
|
||||
//*****************************************************************************
|
||||
// Utilities
|
||||
//*****************************************************************************
|
||||
|
||||
void error(const char* str) {
|
||||
mexErrMsgIdAndTxt("wrap:error", str);
|
||||
}
|
||||
|
||||
mxArray *scalar(mxClassID classid) {
|
||||
mwSize dims[1]; dims[0]=1;
|
||||
return mxCreateNumericArray(1, dims, classid, mxREAL);
|
||||
}
|
||||
|
||||
void checkScalar(const mxArray* array, const char* str) {
|
||||
int m = mxGetM(array), n = mxGetN(array);
|
||||
if (m!=1 || n!=1)
|
||||
mexErrMsgIdAndTxt("wrap: not a scalar in ", str);
|
||||
}
|
||||
|
||||
// Replacement streambuf for cout that writes to the MATLAB console
|
||||
// Thanks to http://stackoverflow.com/a/249008
|
||||
class mstream : public std::streambuf {
|
||||
protected:
|
||||
virtual std::streamsize xsputn(const char *s, std::streamsize n) {
|
||||
mexPrintf("%.*s",n,s);
|
||||
return n;
|
||||
}
|
||||
virtual int overflow(int c = EOF) {
|
||||
if (c != EOF) {
|
||||
mexPrintf("%.1s",&c);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
// Check arguments
|
||||
//*****************************************************************************
|
||||
|
||||
void checkArguments(const string& name, int nargout, int nargin, int expected) {
|
||||
stringstream err;
|
||||
err << name << " expects " << expected << " arguments, not " << nargin;
|
||||
if (nargin!=expected)
|
||||
error(err.str().c_str());
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// wrapping C++ basis types in MATLAB arrays
|
||||
//*****************************************************************************
|
||||
|
||||
// default wrapping throws an error: only basis types are allowed in wrap
|
||||
template <typename Class>
|
||||
mxArray* wrap(const Class& value) {
|
||||
error("wrap internal error: attempted wrap of invalid type");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// specialization to string
|
||||
// wraps into a character array
|
||||
template<>
|
||||
mxArray* wrap<string>(const string& value) {
|
||||
return mxCreateString(value.c_str());
|
||||
}
|
||||
|
||||
// specialization to char
|
||||
template<>
|
||||
mxArray* wrap<char>(const char& value) {
|
||||
mxArray *result = scalar(mxUINT32OR64_CLASS);
|
||||
*(char*)mxGetData(result) = value;
|
||||
return result;
|
||||
}
|
||||
|
||||
// specialization to unsigned char
|
||||
template<>
|
||||
mxArray* wrap<unsigned char>(const unsigned char& value) {
|
||||
mxArray *result = scalar(mxUINT32OR64_CLASS);
|
||||
*(unsigned char*)mxGetData(result) = value;
|
||||
return result;
|
||||
}
|
||||
|
||||
// specialization to bool
|
||||
template<>
|
||||
mxArray* wrap<bool>(const bool& value) {
|
||||
mxArray *result = scalar(mxUINT32OR64_CLASS);
|
||||
*(bool*)mxGetData(result) = value;
|
||||
return result;
|
||||
}
|
||||
|
||||
// specialization to size_t
|
||||
template<>
|
||||
mxArray* wrap<size_t>(const size_t& value) {
|
||||
mxArray *result = scalar(mxUINT32OR64_CLASS);
|
||||
*(size_t*)mxGetData(result) = value;
|
||||
return result;
|
||||
}
|
||||
|
||||
// specialization to int
|
||||
template<>
|
||||
mxArray* wrap<int>(const int& value) {
|
||||
mxArray *result = scalar(mxUINT32OR64_CLASS);
|
||||
*(int*)mxGetData(result) = value;
|
||||
return result;
|
||||
}
|
||||
|
||||
// specialization to double -> just double
|
||||
template<>
|
||||
mxArray* wrap<double>(const double& value) {
|
||||
return mxCreateDoubleScalar(value);
|
||||
}
|
||||
|
||||
// wrap a const Eigen vector into a double vector
|
||||
mxArray* wrap_Vector(const gtsam::Vector& v) {
|
||||
int m = v.size();
|
||||
mxArray *result = mxCreateDoubleMatrix(m, 1, mxREAL);
|
||||
double *data = mxGetPr(result);
|
||||
for (int i=0;i<m;i++) data[i]=v(i);
|
||||
return result;
|
||||
}
|
||||
|
||||
// specialization to Eigen vector -> double vector
|
||||
template<>
|
||||
mxArray* wrap<gtsam::Vector >(const gtsam::Vector& v) {
|
||||
return wrap_Vector(v);
|
||||
}
|
||||
|
||||
// wrap a const Eigen MATRIX into a double matrix
|
||||
mxArray* wrap_Matrix(const gtsam::Matrix& A) {
|
||||
int m = A.rows(), n = A.cols();
|
||||
#ifdef DEBUG_WRAP
|
||||
mexPrintf("wrap_Matrix called with A = \n", m,n);
|
||||
gtsam::print(A);
|
||||
#endif
|
||||
mxArray *result = mxCreateDoubleMatrix(m, n, mxREAL);
|
||||
double *data = mxGetPr(result);
|
||||
// converts from column-major to row-major
|
||||
for (int j=0;j<n;j++) for (int i=0;i<m;i++,data++) *data = A(i,j);
|
||||
return result;
|
||||
}
|
||||
|
||||
// specialization to Eigen MATRIX -> double matrix
|
||||
template<>
|
||||
mxArray* wrap<gtsam::Matrix >(const gtsam::Matrix& A) {
|
||||
return wrap_Matrix(A);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// unwrapping MATLAB arrays into C++ basis types
|
||||
//*****************************************************************************
|
||||
|
||||
// default unwrapping throws an error
|
||||
// as wrap only supports passing a reference or one of the basic types
|
||||
template <typename T>
|
||||
T unwrap(const mxArray* array) {
|
||||
error("wrap internal error: attempted unwrap of invalid type");
|
||||
}
|
||||
|
||||
// specialization to string
|
||||
// expects a character array
|
||||
// Warning: relies on mxChar==char
|
||||
template<>
|
||||
string unwrap<string>(const mxArray* array) {
|
||||
char *data = mxArrayToString(array);
|
||||
if (data==NULL) error("unwrap<string>: not a character array");
|
||||
string str(data);
|
||||
mxFree(data);
|
||||
return str;
|
||||
}
|
||||
|
||||
// Check for 64-bit, as Mathworks says mxGetScalar only good for 32 bit
|
||||
template <typename T>
|
||||
T myGetScalar(const mxArray* array) {
|
||||
switch (mxGetClassID(array)) {
|
||||
case mxINT64_CLASS:
|
||||
return (T) *(int64_t*) mxGetData(array);
|
||||
case mxUINT64_CLASS:
|
||||
return (T) *(uint64_t*) mxGetData(array);
|
||||
default:
|
||||
// hope for the best!
|
||||
return (T) mxGetScalar(array);
|
||||
}
|
||||
}
|
||||
|
||||
// specialization to bool
|
||||
template<>
|
||||
bool unwrap<bool>(const mxArray* array) {
|
||||
checkScalar(array,"unwrap<bool>");
|
||||
return myGetScalar<bool>(array);
|
||||
}
|
||||
|
||||
// specialization to char
|
||||
template<>
|
||||
char unwrap<char>(const mxArray* array) {
|
||||
checkScalar(array,"unwrap<char>");
|
||||
return myGetScalar<char>(array);
|
||||
}
|
||||
|
||||
// specialization to unsigned char
|
||||
template<>
|
||||
unsigned char unwrap<unsigned char>(const mxArray* array) {
|
||||
checkScalar(array,"unwrap<unsigned char>");
|
||||
return myGetScalar<unsigned char>(array);
|
||||
}
|
||||
|
||||
// specialization to int
|
||||
template<>
|
||||
int unwrap<int>(const mxArray* array) {
|
||||
checkScalar(array,"unwrap<int>");
|
||||
return myGetScalar<int>(array);
|
||||
}
|
||||
|
||||
// specialization to size_t
|
||||
template<>
|
||||
size_t unwrap<size_t>(const mxArray* array) {
|
||||
checkScalar(array, "unwrap<size_t>");
|
||||
return myGetScalar<size_t>(array);
|
||||
}
|
||||
|
||||
// specialization to double
|
||||
template<>
|
||||
double unwrap<double>(const mxArray* array) {
|
||||
checkScalar(array,"unwrap<double>");
|
||||
return myGetScalar<double>(array);
|
||||
}
|
||||
|
||||
// specialization to Eigen vector
|
||||
template<>
|
||||
gtsam::Vector unwrap< gtsam::Vector >(const mxArray* array) {
|
||||
int m = mxGetM(array), n = mxGetN(array);
|
||||
if (mxIsDouble(array)==false || n!=1) error("unwrap<vector>: not a vector");
|
||||
#ifdef DEBUG_WRAP
|
||||
mexPrintf("unwrap< gtsam::Vector > called with %dx%d argument\n", m,n);
|
||||
#endif
|
||||
double* data = (double*)mxGetData(array);
|
||||
gtsam::Vector v(m);
|
||||
for (int i=0;i<m;i++,data++) v(i) = *data;
|
||||
#ifdef DEBUG_WRAP
|
||||
gtsam::print(v);
|
||||
#endif
|
||||
return v;
|
||||
}
|
||||
|
||||
// specialization to Eigen matrix
|
||||
template<>
|
||||
gtsam::Matrix unwrap< gtsam::Matrix >(const mxArray* array) {
|
||||
if (mxIsDouble(array)==false) error("unwrap<matrix>: not a matrix");
|
||||
int m = mxGetM(array), n = mxGetN(array);
|
||||
#ifdef DEBUG_WRAP
|
||||
mexPrintf("unwrap< gtsam::Matrix > called with %dx%d argument\n", m,n);
|
||||
#endif
|
||||
double* data = (double*)mxGetData(array);
|
||||
gtsam::Matrix A(m,n);
|
||||
// converts from row-major to column-major
|
||||
for (int j=0;j<n;j++) for (int i=0;i<m;i++,data++) A(i,j) = *data;
|
||||
#ifdef DEBUG_WRAP
|
||||
gtsam::print(A);
|
||||
#endif
|
||||
return A;
|
||||
}
|
||||
|
||||
/*
|
||||
[create_object] creates a MATLAB proxy class object with a mexhandle
|
||||
in the self property. Matlab does not allow the creation of matlab
|
||||
objects from within mex files, hence we resort to an ugly trick: we
|
||||
invoke the proxy class constructor by calling MATLAB with a special
|
||||
uint64 value ptr_constructor_key and the pointer itself. MATLAB
|
||||
allocates the object. Then, the special constructor in our wrap code
|
||||
that is activated when the ptr_constructor_key is passed in passes
|
||||
the pointer back into a C++ function to add the pointer to its
|
||||
collector. We go through this extra "C++ to MATLAB to C++ step" in
|
||||
order to be able to add to the collector could be in a different wrap
|
||||
module.
|
||||
*/
|
||||
mxArray* create_object(const std::string& classname, void *pointer, bool isVirtual, const char *rttiName) {
|
||||
mxArray *result;
|
||||
mxArray *input[3];
|
||||
int nargin = 2;
|
||||
// First input argument is pointer constructor key
|
||||
input[0] = mxCreateNumericMatrix(1, 1, mxUINT64_CLASS, mxREAL);
|
||||
*reinterpret_cast<uint64_t*>(mxGetData(input[0])) = ptr_constructor_key;
|
||||
// Second input argument is the pointer
|
||||
input[1] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL);
|
||||
*reinterpret_cast<void**>(mxGetData(input[1])) = pointer;
|
||||
// If the class is virtual, use the RTTI name to look up the derived matlab type
|
||||
const char *derivedClassName;
|
||||
if(isVirtual) {
|
||||
const mxArray *rttiRegistry = mexGetVariablePtr("global", "gtsamwrap_rttiRegistry");
|
||||
if(!rttiRegistry)
|
||||
mexErrMsgTxt(
|
||||
"gtsam wrap: RTTI registry is missing - it could have been cleared from the workspace."
|
||||
" You can issue 'clear all' to completely clear the workspace, and next time a wrapped object is"
|
||||
" created the RTTI registry will be recreated.");
|
||||
const mxArray *derivedNameMx = mxGetField(rttiRegistry, 0, rttiName);
|
||||
if(!derivedNameMx)
|
||||
mexErrMsgTxt((
|
||||
"gtsam wrap: The derived class type " + string(rttiName) + " was not found in the RTTI registry. "
|
||||
"Try calling 'clear all' twice consecutively - we have seen things not get unloaded properly the "
|
||||
"first time. If this does not work, this may indicate an inconsistency in your wrap interface file. "
|
||||
"The most likely cause for this is that a base class was marked virtual in the wrap interface "
|
||||
"definition header file for gtsam or for your module, but a derived type was returned by a C++ "
|
||||
"function and that derived type was not marked virtual (or was not specified in the wrap interface "
|
||||
"definition header at all).").c_str());
|
||||
size_t strLen = mxGetN(derivedNameMx);
|
||||
char *buf = new char[strLen+1];
|
||||
if(mxGetString(derivedNameMx, buf, strLen+1))
|
||||
mexErrMsgTxt("gtsam wrap: Internal error reading RTTI table, try 'clear all' to clear your workspace and reinitialize the toolbox.");
|
||||
derivedClassName = buf;
|
||||
input[2] = mxCreateString("void");
|
||||
nargin = 3;
|
||||
} else {
|
||||
derivedClassName = classname.c_str();
|
||||
}
|
||||
// Call special pointer constructor, which sets 'self'
|
||||
mexCallMATLAB(1,&result, nargin, input, derivedClassName);
|
||||
// Deallocate our memory
|
||||
mxDestroyArray(input[0]);
|
||||
mxDestroyArray(input[1]);
|
||||
if(isVirtual) {
|
||||
mxDestroyArray(input[2]);
|
||||
delete[] derivedClassName;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
When the user calls a method that returns a shared pointer, we create
|
||||
an ObjectHandle from the shared_pointer and return it as a proxy
|
||||
class to matlab.
|
||||
*/
|
||||
template <typename Class>
|
||||
mxArray* wrap_shared_ptr(boost::shared_ptr< Class > shared_ptr, const std::string& matlabName, bool isVirtual) {
|
||||
// Create actual class object from out pointer
|
||||
mxArray* result;
|
||||
if(isVirtual) {
|
||||
boost::shared_ptr<void> void_ptr(shared_ptr);
|
||||
result = create_object(matlabName, &void_ptr, isVirtual, typeid(*shared_ptr).name());
|
||||
} else {
|
||||
boost::shared_ptr<Class> *heapPtr = new boost::shared_ptr<Class>(shared_ptr);
|
||||
result = create_object(matlabName, heapPtr, isVirtual, "");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename Class>
|
||||
boost::shared_ptr<Class> unwrap_shared_ptr(const mxArray* obj, const string& propertyName) {
|
||||
|
||||
mxArray* mxh = mxGetProperty(obj,0, propertyName.c_str());
|
||||
if (mxGetClassID(mxh) != mxUINT32OR64_CLASS || mxIsComplex(mxh)
|
||||
|| mxGetM(mxh) != 1 || mxGetN(mxh) != 1) error(
|
||||
"Parameter is not an Shared type.");
|
||||
|
||||
boost::shared_ptr<Class>* spp = *reinterpret_cast<boost::shared_ptr<Class>**> (mxGetData(mxh));
|
||||
return *spp;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +0,0 @@
|
|||
% automatically generated by wrap
|
||||
classdef Point2 < handle
|
||||
properties
|
||||
self = 0
|
||||
end
|
||||
methods
|
||||
function obj = Point2(varargin)
|
||||
if (nargin == 0), obj.self = new_Point2(0,0); end
|
||||
if (nargin == 2 && isa(varargin{1},'double') && isa(varargin{2},'double')), obj.self = new_Point2(0,1,varargin{1},varargin{2}); end
|
||||
if nargin ==14, new_Point2(varargin{1},0); end
|
||||
if nargin ~= 13 && nargin ~= 14 && obj.self == 0, error('Point2 constructor failed'); end
|
||||
end
|
||||
function delete(obj)
|
||||
if obj.self ~= 0
|
||||
new_Point2(obj.self);
|
||||
obj.self = 0;
|
||||
end
|
||||
end
|
||||
function display(obj), obj.print(''); end
|
||||
function disp(obj), obj.display; end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
// automatically generated by wrap
|
||||
#include <wrap/matlab.h>
|
||||
#include <Point2.h>
|
||||
typedef boost::shared_ptr<Point2> Shared;
|
||||
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||
{
|
||||
checkArguments("argChar",nargout,nargin-1,1);
|
||||
Shared obj = unwrap_shared_ptr<Point2>(in[0], "Point2");
|
||||
char a = unwrap< char >(in[1]);
|
||||
obj->argChar(a);
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
% result = obj.argChar(a)
|
||||
function result = argChar(obj,a)
|
||||
error('need to compile argChar.cpp');
|
||||
end
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
// automatically generated by wrap
|
||||
#include <wrap/matlab.h>
|
||||
#include <Point2.h>
|
||||
typedef boost::shared_ptr<Point2> Shared;
|
||||
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||
{
|
||||
checkArguments("argUChar",nargout,nargin-1,1);
|
||||
Shared obj = unwrap_shared_ptr<Point2>(in[0], "Point2");
|
||||
unsigned char a = unwrap< unsigned char >(in[1]);
|
||||
obj->argUChar(a);
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
% result = obj.argUChar(a)
|
||||
function result = argUChar(obj,a)
|
||||
error('need to compile argUChar.cpp');
|
||||
end
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
// automatically generated by wrap
|
||||
#include <wrap/matlab.h>
|
||||
#include <Point2.h>
|
||||
typedef boost::shared_ptr<Point2> Shared;
|
||||
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||
{
|
||||
checkArguments("dim",nargout,nargin-1,0);
|
||||
Shared obj = unwrap_shared_ptr<Point2>(in[0], "Point2");
|
||||
int result = obj->dim();
|
||||
out[0] = wrap< int >(result);
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
% result = obj.dim()
|
||||
function result = dim(obj)
|
||||
error('need to compile dim.cpp');
|
||||
end
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
// automatically generated by wrap
|
||||
#include <wrap/matlab.h>
|
||||
#include <Point2.h>
|
||||
typedef boost::shared_ptr<Point2> Shared;
|
||||
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||
{
|
||||
checkArguments("returnChar",nargout,nargin-1,0);
|
||||
Shared obj = unwrap_shared_ptr<Point2>(in[0], "Point2");
|
||||
char result = obj->returnChar();
|
||||
out[0] = wrap< char >(result);
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
% result = obj.returnChar()
|
||||
function result = returnChar(obj)
|
||||
error('need to compile returnChar.cpp');
|
||||
end
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
// automatically generated by wrap
|
||||
#include <wrap/matlab.h>
|
||||
#include <Point2.h>
|
||||
typedef boost::shared_ptr<VectorNotEigen> SharedVectorNotEigen;
|
||||
typedef boost::shared_ptr<Point2> Shared;
|
||||
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||
{
|
||||
checkArguments("vectorConfusion",nargout,nargin-1,0);
|
||||
Shared obj = unwrap_shared_ptr<Point2>(in[0], "Point2");
|
||||
VectorNotEigen result = obj->vectorConfusion();
|
||||
SharedVectorNotEigen* ret = new SharedVectorNotEigen(new VectorNotEigen(result));
|
||||
out[0] = wrap_collect_shared_ptr(ret,"VectorNotEigen");
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
% result = obj.vectorConfusion()
|
||||
function result = vectorConfusion(obj)
|
||||
error('need to compile vectorConfusion.cpp');
|
||||
end
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
// automatically generated by wrap
|
||||
#include <wrap/matlab.h>
|
||||
#include <Point2.h>
|
||||
typedef boost::shared_ptr<Point2> Shared;
|
||||
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||
{
|
||||
checkArguments("x",nargout,nargin-1,0);
|
||||
Shared obj = unwrap_shared_ptr<Point2>(in[0], "Point2");
|
||||
double result = obj->x();
|
||||
out[0] = wrap< double >(result);
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
% result = obj.x()
|
||||
function result = x(obj)
|
||||
error('need to compile x.cpp');
|
||||
end
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
// automatically generated by wrap
|
||||
#include <wrap/matlab.h>
|
||||
#include <Point2.h>
|
||||
typedef boost::shared_ptr<Point2> Shared;
|
||||
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||
{
|
||||
checkArguments("y",nargout,nargin-1,0);
|
||||
Shared obj = unwrap_shared_ptr<Point2>(in[0], "Point2");
|
||||
double result = obj->y();
|
||||
out[0] = wrap< double >(result);
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
% result = obj.y()
|
||||
function result = y(obj)
|
||||
error('need to compile y.cpp');
|
||||
end
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
% automatically generated by wrap
|
||||
classdef Point3 < handle
|
||||
properties
|
||||
self = 0
|
||||
end
|
||||
methods
|
||||
function obj = Point3(varargin)
|
||||
if (nargin == 3 && isa(varargin{1},'double') && isa(varargin{2},'double') && isa(varargin{3},'double')), obj.self = new_Point3(0,0,varargin{1},varargin{2},varargin{3}); end
|
||||
if nargin ==14, new_Point3(varargin{1},0); end
|
||||
if nargin ~= 13 && nargin ~= 14 && obj.self == 0, error('Point3 constructor failed'); end
|
||||
end
|
||||
function delete(obj)
|
||||
if obj.self ~= 0
|
||||
new_Point3(obj.self);
|
||||
obj.self = 0;
|
||||
end
|
||||
end
|
||||
function display(obj), obj.print(''); end
|
||||
function disp(obj), obj.display; end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
// automatically generated by wrap
|
||||
#include <wrap/matlab.h>
|
||||
#include <Point3.h>
|
||||
using namespace geometry;
|
||||
typedef boost::shared_ptr<Point3> Shared;
|
||||
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||
{
|
||||
checkArguments("norm",nargout,nargin-1,0);
|
||||
Shared obj = unwrap_shared_ptr<Point3>(in[0], "Point3");
|
||||
double result = obj->norm();
|
||||
out[0] = wrap< double >(result);
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
% result = obj.norm()
|
||||
function result = norm(obj)
|
||||
error('need to compile norm.cpp');
|
||||
end
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
% automatically generated by wrap
|
||||
classdef Test < handle
|
||||
properties
|
||||
self = 0
|
||||
end
|
||||
methods
|
||||
function obj = Test(varargin)
|
||||
if (nargin == 0), obj.self = new_Test(0,0); end
|
||||
if (nargin == 2 && isa(varargin{1},'double') && isa(varargin{2},'double')), obj.self = new_Test(0,1,varargin{1},varargin{2}); end
|
||||
if nargin ==14, new_Test(varargin{1},0); end
|
||||
if nargin ~= 13 && nargin ~= 14 && obj.self == 0, error('Test constructor failed'); end
|
||||
end
|
||||
function delete(obj)
|
||||
if obj.self ~= 0
|
||||
new_Test(obj.self);
|
||||
obj.self = 0;
|
||||
end
|
||||
end
|
||||
function display(obj), obj.print(''); end
|
||||
function disp(obj), obj.display; end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
// automatically generated by wrap
|
||||
#include <wrap/matlab.h>
|
||||
#include <folder/path/to/Test.h>
|
||||
using namespace geometry;
|
||||
typedef boost::shared_ptr<Test> Shared;
|
||||
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||
{
|
||||
checkArguments("arg_EigenConstRef",nargout,nargin-1,1);
|
||||
Shared obj = unwrap_shared_ptr<Test>(in[0], "Test");
|
||||
Matrix& value = *unwrap_shared_ptr< Matrix >(in[1], "Matrix");
|
||||
obj->arg_EigenConstRef(value);
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
% result = obj.arg_EigenConstRef(value)
|
||||
function result = arg_EigenConstRef(obj,value)
|
||||
error('need to compile arg_EigenConstRef.cpp');
|
||||
end
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
// automatically generated by wrap
|
||||
#include <wrap/matlab.h>
|
||||
#include <folder/path/to/Test.h>
|
||||
using namespace geometry;
|
||||
typedef boost::shared_ptr<Test> SharedTest;
|
||||
typedef boost::shared_ptr<Test> SharedTest;
|
||||
typedef boost::shared_ptr<Test> Shared;
|
||||
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||
{
|
||||
checkArguments("create_MixedPtrs",nargout,nargin-1,0);
|
||||
Shared obj = unwrap_shared_ptr<Test>(in[0], "Test");
|
||||
pair< Test, SharedTest > result = obj->create_MixedPtrs();
|
||||
SharedTest* ret = new SharedTest(new Test(result.first));
|
||||
out[0] = wrap_collect_shared_ptr(ret,"Test");
|
||||
SharedTest* ret = new SharedTest(result.second);
|
||||
out[1] = wrap_collect_shared_ptr(ret,"Test");
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
% [first,second] = obj.create_MixedPtrs()
|
||||
function [first,second] = create_MixedPtrs(obj)
|
||||
error('need to compile create_MixedPtrs.cpp');
|
||||
end
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
// automatically generated by wrap
|
||||
#include <wrap/matlab.h>
|
||||
#include <folder/path/to/Test.h>
|
||||
using namespace geometry;
|
||||
typedef boost::shared_ptr<Test> SharedTest;
|
||||
typedef boost::shared_ptr<Test> SharedTest;
|
||||
typedef boost::shared_ptr<Test> Shared;
|
||||
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||
{
|
||||
checkArguments("create_ptrs",nargout,nargin-1,0);
|
||||
Shared obj = unwrap_shared_ptr<Test>(in[0], "Test");
|
||||
pair< SharedTest, SharedTest > result = obj->create_ptrs();
|
||||
SharedTest* ret = new SharedTest(result.first);
|
||||
out[0] = wrap_collect_shared_ptr(ret,"Test");
|
||||
SharedTest* ret = new SharedTest(result.second);
|
||||
out[1] = wrap_collect_shared_ptr(ret,"Test");
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
% [first,second] = obj.create_ptrs()
|
||||
function [first,second] = create_ptrs(obj)
|
||||
error('need to compile create_ptrs.cpp');
|
||||
end
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
// automatically generated by wrap
|
||||
#include <wrap/matlab.h>
|
||||
#include <folder/path/to/Test.h>
|
||||
using namespace geometry;
|
||||
typedef boost::shared_ptr<Test> Shared;
|
||||
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||
{
|
||||
checkArguments("print",nargout,nargin-1,0);
|
||||
Shared obj = unwrap_shared_ptr<Test>(in[0], "Test");
|
||||
obj->print();
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
% result = obj.print()
|
||||
function result = print(obj)
|
||||
error('need to compile print.cpp');
|
||||
end
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
// automatically generated by wrap
|
||||
#include <wrap/matlab.h>
|
||||
#include <folder/path/to/Test.h>
|
||||
using namespace geometry;
|
||||
typedef boost::shared_ptr<Point2> SharedPoint2;
|
||||
typedef boost::shared_ptr<Test> Shared;
|
||||
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||
{
|
||||
checkArguments("return_Point2Ptr",nargout,nargin-1,1);
|
||||
Shared obj = unwrap_shared_ptr<Test>(in[0], "Test");
|
||||
bool value = unwrap< bool >(in[1]);
|
||||
SharedPoint2 result = obj->return_Point2Ptr(value);
|
||||
SharedPoint2* ret = new SharedPoint2(result);
|
||||
out[0] = wrap_collect_shared_ptr(ret,"Point2");
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
% result = obj.return_Point2Ptr(value)
|
||||
function result = return_Point2Ptr(obj,value)
|
||||
error('need to compile return_Point2Ptr.cpp');
|
||||
end
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
// automatically generated by wrap
|
||||
#include <wrap/matlab.h>
|
||||
#include <folder/path/to/Test.h>
|
||||
using namespace geometry;
|
||||
typedef boost::shared_ptr<Test> SharedTest;
|
||||
typedef boost::shared_ptr<Test> Shared;
|
||||
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||
{
|
||||
checkArguments("return_Test",nargout,nargin-1,1);
|
||||
Shared obj = unwrap_shared_ptr<Test>(in[0], "Test");
|
||||
boost::shared_ptr<Test> value = unwrap_shared_ptr< Test >(in[1], "Test");
|
||||
Test result = obj->return_Test(value);
|
||||
SharedTest* ret = new SharedTest(new Test(result));
|
||||
out[0] = wrap_collect_shared_ptr(ret,"Test");
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
% result = obj.return_Test(value)
|
||||
function result = return_Test(obj,value)
|
||||
error('need to compile return_Test.cpp');
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue