Conversation
| // TODO: deprecate the following function: draw(visualSensor, sceneGraph, | ||
| // flags); | ||
| // draw the scene graph with the visual sensor provided by user | ||
| void draw(sensor::VisualSensor& visualSensor, |
There was a problem hiding this comment.
My opinion: This function is really obsolete and thus should be removed.
Use the new one directly.
Note that the RenderCamera flags (such as FrustumCulling) are not needed since such info is included in the sim.
| @@ -38,11 +40,22 @@ class Renderer { | |||
| scene::SceneGraph& sceneGraph, | |||
There was a problem hiding this comment.
This one can be kept since it provides a way to render the scene graph without the sensor.
| renderer->draw(*this, sim.getActiveSemanticSceneGraph(), flags); | ||
| draw(sim.getActiveSemanticSceneGraph(), flags); | ||
| if (&sim.getActiveSemanticSceneGraph() != &sim.getActiveSceneGraph()) { | ||
| flags |= gfx::RenderCamera::Flag::ObjectsOnly; | ||
| renderer->draw(*this, sim.getActiveSceneGraph(), flags); |
There was a problem hiding this comment.
I believe this is a bug in our current master. Just no one hit it so far.
this CameraSensor cannot be in 2 different SG at the same time.
There was a problem hiding this comment.
Update:
Oh, I believe it became a bug recently when we deprecated the defaultRenderCamera in each SG. Before we used it to render the corresponding SG. So using the sensor from another SG to render was not a problem since it set its absolute transformation to the defaultRenderCamera of the current SG...
| if (twoSceneGraphs) { | ||
| // *assume* the sensor is always in the regular scene graph. | ||
| // backup first | ||
| Mn::Matrix4 relativeTransform = node().transformation(); | ||
| Mn::Matrix4 absTransform = node().absoluteTransformation(); | ||
| scene::SceneNode* p = static_cast<scene::SceneNode*>(node().parent()); | ||
| // take the sensor from the current regular scene graph and connect it to | ||
| // the root node of semantic scene graph, set the *correct* transformation | ||
| node().setParent(&sim.getActiveSemanticSceneGraph().getRootNode()); | ||
| node().setTransformation(absTransform); | ||
| draw(sim.getActiveSemanticSceneGraph(), flags); | ||
| // after drawing, put the node back to the regular scene graph. | ||
| // MUST use the setParent function! Otherwise the sensorSuite in the node | ||
| // will be wrong!!! | ||
| node().setParent(p); | ||
| node().setTransformation(relativeTransform); | ||
| } else { | ||
| draw(sim.getActiveSemanticSceneGraph(), flags); | ||
| } |
There was a problem hiding this comment.
@Skylion007 : I just updated the code as I replicated the logic here, and did it in the correct way with setParent().
| } | ||
|
|
||
| if (twoSceneGraphs) { | ||
| flags |= gfx::RenderCamera::Flag::ObjectsOnly; |
There was a problem hiding this comment.
BTW, this cludge we are doing is going to hurt our FPS a lot in scenes without the semantic mesh, but only added objects (such as synthetic datasets.) One thing on the agenda is to find a better way to resolve this long term so we don't have to do this double pass all the time. @aclegg3 I think you mentioned something about this during our last meeting?
There was a problem hiding this comment.
This can of course be saved for a different PR, just wanted to bring it up.
There was a problem hiding this comment.
🤔 I'm not sure that this is the case. Here if we only have a single scene graph we'll just render it with semantic ids, if we have 2 scene-graphs (e.g. a specific separate semantic asset) then we render that asset and then a pass over dynamic objects. I don't see the overhead you are worried about. Am I missing something?
There was a problem hiding this comment.
@aclegg3 : It means the absolute transformation for all nodes will be computed twice (one per each SG) if I remember it correctly.
| [](Renderer& self, sensor::VisualSensor& visualSensor, | ||
| scene::SceneGraph& sceneGraph, RenderCamera::Flag flags) { | ||
| self.draw(visualSensor, sceneGraph, RenderCamera::Flags{flags}); | ||
| scene::SceneGraph& sceneGraph, RenderCamera::Flags flags) { |
|
|
||
| public: | ||
| ESP_SMART_POINTERS(ManagedContainer<T, Access>); | ||
| ESP_SMART_POINTERS(ManagedContainer<T, Access>) |
There was a problem hiding this comment.
this ";" gives us a lot of compiling warnings. Get rid of it in this PR as well.
| if (twoSceneGraphs) { | ||
| // *assume* the sensor is always in the regular scene graph. | ||
| // backup first | ||
| Mn::Matrix4 relativeTransform = node().transformation(); |
There was a problem hiding this comment.
Perhaps this should be abstracted out if possible. Disappointing that this hack is necessary, but it is required for every VisualSensor, right?
There was a problem hiding this comment.
That can also be saved for a later PR though.
There was a problem hiding this comment.
Yes, a bit code duplication here. I did not figure out a good way to extract it so far. Like I said in the description, different visual sensors has it is own rendering logic. Read this two pieces of code. They are a bit different.
There was a problem hiding this comment.
Allow me to think about it.
This is problem that we need to solve.
Otherwise it will become a big problem as more sensors are coming in the future.
@mosra @aclegg3 @erikwijmans any ideas here?
There was a problem hiding this comment.
I am thinking the ways to address this. It must be solved before committing this diff in.
| moveSemanticSensorToSemanticSceneGraph(sim); | ||
| cubeMap_->renderToTexture(*cubeMapCamera_, | ||
| sim.getActiveSemanticSceneGraph(), flags); | ||
| moveSemanticSensorBackToRegularSceneGraph(sim); |
There was a problem hiding this comment.
@Skylion007 : I reduced the code duplication by extracting 2 helper functions applied here.
The challenge is that the code looks like a "sandwich". The "bread" is the same but the "food" in between varies.
|
Similar to render_enter / exit semantics though, right? It would need to
be split between two functions. Also could be done with a functional
programming lambda interface, although not as cleanly.
…On Mon, Apr 5, 2021 at 9:58 PM bigbike ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In src/esp/sensor/FisheyeSensor.cpp
<#1159 (comment)>
:
> // generate the cubemap texture
- cubeMap_->renderToTexture(*cubeMapCamera_, sim.getActiveSceneGraph(), flags);
+ if (fisheyeSensorSpec_->sensorType == SensorType::Semantic) {
+ bool twoSceneGraphs =
+ (&sim.getActiveSemanticSceneGraph() != &sim.getActiveSceneGraph());
+
+ if (twoSceneGraphs) {
+ moveSemanticSensorToSemanticSceneGraph(sim);
+ cubeMap_->renderToTexture(*cubeMapCamera_,
+ sim.getActiveSemanticSceneGraph(), flags);
+ moveSemanticSensorBackToRegularSceneGraph(sim);
@Skylion007 <https://github.com/Skylion007> : I reduced the code
duplication by extracting 2 helper functions applied here.
The challenge is that the code looks like a "sandwich". The "bread" is the
same but the "food" in between varies.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1159 (review)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAPVMXYTQYRXR2OM7GVJHULTHJTEDANCNFSM42K66TIA>
.
|
| target_link_libraries( | ||
| sensor | ||
| PUBLIC core gfx scene | ||
| PRIVATE sim |
There was a problem hiding this comment.
It was set (in different ways) to help me better understand why the CI fails.
It is a sad story. I was taking PTO on Mon. but I spent whole day trying to solve the CI failure, which is still there.
I found the ResourceMangerTest cannot be compiled. It complains libsensor.a is missing some definitions from here and there, even though it does not need anything from sensor.
| void CameraSensor::draw(scene::SceneGraph& sceneGraph, | ||
| gfx::RenderCamera::Flags flags) { | ||
| for (auto& it : sceneGraph.getDrawableGroups()) { | ||
| // TODO: remove || true |
There was a problem hiding this comment.
This TODO is getting carried around more and more places, are we ever going to actually do it?
There was a problem hiding this comment.
I believe the purpose is to build a filter function on drawables, which can be useful in the material editing.
There was a problem hiding this comment.
Yeah, the it.second.prepareForDraw(*renderCamera_) part of the if statement seems fine and I can see a use for that returning false and something not getting drawn, my concern is that we are simply ignoring the return value of that function via the || true. If we ever do want to do something with that function, we have a bunch of || true's that will make that harder.
I don't know the history of the || true (I think it's been there forever and thus likely a debugging thing that never got removed), but it currently does nothing since the only implementation for prepareForDraw just returns true.
| return semanticScene_; | ||
| } | ||
|
|
||
| bool semanticSceneExists() { return (semanticScene_ != nullptr); } |
There was a problem hiding this comment.
| bool semanticSceneExists() { return (semanticScene_ != nullptr); } | |
| bool semanticSceneExists() const { return (semanticScene_ != nullptr); } |
| return; | ||
| } | ||
|
|
||
| node().setParent(semanticSensorParentNodeBackup_); |
There was a problem hiding this comment.
Can you add an assert that the pointer is not null and the optional is not empty and then null/empty them after?
| (&sim.getActiveSemanticSceneGraph() != &sim.getActiveSceneGraph()); | ||
|
|
||
| if (twoSceneGraphs) { | ||
| moveSemanticSensorToSemanticSceneGraph(sim); |
There was a problem hiding this comment.
This seems a bit risky as it's easy to forget to call the moveSemanticSensorBackToRegularSceneGraph function. Worth considering RAII here.
There was a problem hiding this comment.
Can you elaborate a bit how you are going to do RAII here?
if people forgets to call this function moveSemanticSensorBackToRegularSceneGraph, she will know immediately as in the following (L145), she needs it to draw the "objects". If the above function is not called, the program will hit an assertion in Magnum (camera is not in the same SG) and quit.
There was a problem hiding this comment.
Just a helper class that calls moveSemanticSensorToSemanticSceneGraph in its constructor and moveSemanticSensorBackToRegularSceneGraph in its destructor.
|
@bigbike Merging from master should solve the CI issues caused by doc building |
|
Okay weird, only 1 test is running. |
| # the codebase has a deep architectural problem that needs solving -- lib dependency cycles !!!! | ||
| # the following is just a "crutch", a temporary remedy here. | ||
| # https://cmake.org/cmake/help/latest/prop_tgt/LINK_INTERFACE_MULTIPLICITY.html | ||
| set_target_properties(sensor PROPERTIES LINK_INTERFACE_MULTIPLICITY 3) |
There was a problem hiding this comment.
Previously the CI tests kept failing. Tried many ways to fix it but failed.
With the help from @mosra, we found the root cause -- lib dependency cycles. It is really a big problem in our current system. Here we applied a short-term solution to temporarily mitigate it.
| VisualSensorSpec::ptr visualSensorSpec_ = | ||
| std::dynamic_pointer_cast<VisualSensorSpec>(spec_); | ||
|
|
||
| class MoveSemanticSensorNodeHelper { |
There was a problem hiding this comment.
@erikwijmans :
The RAII proposed by you is actually a good idea. Thank you.
Take a look at the implementation. See if it is what you expected.
There was a problem hiding this comment.
Yeah, this looks nice. Left one question about implementation
| "sensor is attached to the root node, and thus cannot be moved.", ); | ||
|
|
||
| // check if the sensor is already in this semantic scene graph | ||
| if (node.scene() == sim.getActiveSemanticSceneGraph().getRootNode().scene()) { |
There was a problem hiding this comment.
I think this case will always cause a crash? Since the destructor will always hit CORRADE_INTERNAL_ASSERT(semanticSensorParentNodeBackup_);
There was a problem hiding this comment.
Well, the basic assumption is that at the very beginning, the semantic sensor is attached to the regular scene graph, not the semantic scene graph. Your comment makes me think if it is always true.
If this is true, then you do not need to worry about it here.
There was a problem hiding this comment.
If there are NO two scene graphs, e.g., only the semantic scene graph, then user should never ever use MoveSemanticSensorNodeHelper at all.
There was a problem hiding this comment.
Should this be an assert then? Right now it looks like a feature where this won't move the sensor if it doesn't need to. However, the destructor assumes that if the sensor isn't part of the active scene graph, then the constructor moved it to the semantic scene graph and will try to move it back. This will cause a crash however.
| // SensorType is Depth or any other type | ||
| renderer->draw(*this, sim.getActiveSceneGraph(), flags); | ||
| // SensorType is Color, Depth or any other type | ||
| draw(sim.getActiveSceneGraph(), flags); |
There was a problem hiding this comment.
@erikwijmans :
If there is only one scene graph, we assume it is the regular scene graph.
Is there a chance that we will only have semantic scene graph?
also cc: @aclegg3
There was a problem hiding this comment.
If we only have a one scene graph we'll use it for both RGB and SEMANTIC and all object will be on the correct scene graph for both renders.
There was a problem hiding this comment.
I see. Thanks @aclegg3. Very clear. In this case, getActiveSceneGraph and getActiveSemanticSceneGraph will return the same SG. So we are good here.
|
Dear reviewers, If you do not have more concerns, I am going to merge it in this afternoon. Thanks. |
mosra
left a comment
There was a problem hiding this comment.
Just a random comment that doesn't affect the approval status.
| ) | ||
|
|
||
| # ATTENTION developers !!!!!!!!!!!!!!!!!!!! | ||
| # the codebase has a deep architectural problem that needs solving -- lib dependency cycles !!!! |
There was a problem hiding this comment.
I like the amount of exclamation marks here. 👍
| CORRADE_INTERNAL_ASSERT(activeSceneID_ >= 0 && | ||
| activeSceneID_ < sceneID_.size()); |
There was a problem hiding this comment.
Code golf, if you want:
| CORRADE_INTERNAL_ASSERT(activeSceneID_ >= 0 && | |
| activeSceneID_ < sceneID_.size()); | |
| CORRADE_INTERNAL_ASSERT(std::size_t(activeSceneID_) < sceneID_.size()); |
Same below. Not sure about the type, also you might probably have different coding style rules for the cast.
|
Looks good. Let's merge this in. |

Motivation and Context
This diff is trying to address the following issues:
draw_observationinSensor(python) has the same code logic as thedrawObservation()in theCameraSensorclass (C++). It is a type of code duplication.Rendererclass (C++). AndSensorclass (both in C++ and python) depended on it. The correct dependency should be: Each sensor type implements the actually rendering logic (because different sensors (Pinhole, Fisheye etc.) have different, specific logic), andRendererdepends on the sensors.How Has This Been Tested
Types of changes
Checklist