Amerio.Stephane Posted April 23, 2025 Posted April 23, 2025 Hello, We need to simulate the capability of some sensors to autonomously track a point. Usually, the simulation is responsible for the position and orientation of an entity, but in this specific case we need the orientation to be computed on the IG side (to simulate the fact that the sensor is autonomous and remove this burden from the simulation). So my idea would be simply to force-update at runtime the orientation of an entity with a specific component. But... what would be the impact here (overriding the orientation): any issue on the interpolation side you can see? what would the CIGI PositionResponse to a PositionRequest really be? the actual orientation I changed, or the one passed to EntityControl? and where would be the best place in the code to do my override: update? async? swap? do you know any other, better way to do this? Thanks!
cash-metall Posted April 24, 2025 Posted April 24, 2025 Hello! Yes, you can move your entity on the IG side. And track its position via CIGI. for example, lets create a simple component class AutonomusIGEnity: public Unigine::ComponentBase { public: COMPONENT_DEFINE(AutonomusIGEnity, Unigine::ComponentBase); COMPONENT_INIT(init); COMPONENT_UPDATE(update); COMPONENT_SHUTDOWN(shutdown); private: void init() { entity = Plugins::IG::Manager::get()->findEntity(node); // looking wich entity is owner for this node if (!entity) return; entity->setInterpolation(false); // disable interpolation, cause we will move it manualy } void update() { if (!entity) return; Math::dvec3 world_pos = Math::Vec3(sin(Game::getTime())* 100, cos(Game::getTime())* 100, cos(Game::getTime()) * 5 + 10) ; // calculate some how new entity position in world coordinates entity->setPositionOffset(Plugins::IG::Manager::get()->getConverter()->ENUtoIG(world_pos)); // send this coordinates to entity } void shutdown() { Plugins::IG::Manager::get()->removeEntity(entity->getID()); } Plugins::IG::Entity * entity = nullptr; }; REGISTER_COMPONENT(AutonomusIGEnity); after that you need to assign this component inside entity nodereference or just to any predefined entity in the scene: lets start IG and HEMU to check that entity is moving: send the Position Request packet for 777 entity: for some reason HEMU doesn't want to show Position Response messages in Capture window, but it works! Lets check it via WireShark: Please keep me update if you have any issues with this solution. Thanks!
Amerio.Stephane Posted April 24, 2025 Author Posted April 24, 2025 Thanks for the sample code and the validation with Wireshark!!! Our world use case is a bit more complex, though, as the entity (sensor) position itself will be controlled by CIGI (or DIS), but not it's orientation (which we want to override). In the code above, you simply override everything. Hence my question on "where" to do the orientation override, as I suspected that maybe there would be cases where doing so in the update() would lead to jitter, as we must keep the interpolation active (emitter's frequency is lower than IG's)
cash-metall Posted April 24, 2025 Posted April 24, 2025 Maybe I misunderstood the question: You want to use the position from the host with interpolation, but define the rotation on the IG side? And have the PositionResponse return the rotation that was calculated on the IG side?
cash-metall Posted April 24, 2025 Posted April 24, 2025 in this case you need to modify rotation directly on Node in any place after Plugins Update class AutonomusIGEnity: public Unigine::ComponentBase { public: COMPONENT_DEFINE(AutonomusIGEnity, Unigine::ComponentBase); COMPONENT_INIT(init); COMPONENT_UPDATE(update); COMPONENT_SHUTDOWN(shutdown); private: void init() { entity = Plugins::IG::Manager::get()->findEntity(node); if (!entity) return; } void update() { if (!entity) return; Math::vec3 new_rot = Math::vec3(Math::mod(Game::getTime() * 90, 360), 0, 0); //roll 90deg/sec entity->getNode()->setWorldRotation(Plugins::IG::Manager::get()->getConverter()->eulerIGToRotation(new_rot)); } void shutdown() { Plugins::IG::Manager::get()->removeEntity(entity->getID()); } Plugins::IG::Entity * entity = nullptr; }; REGISTER_COMPONENT(AutonomusIGEnity);
Amerio.Stephane Posted April 24, 2025 Author Posted April 24, 2025 Okay got it, so Component::update() is called after plugin update(), so it's safe to do the change here. Thanks for clarifications!
cash-metall Posted April 25, 2025 Posted April 25, 2025 component update or Engine::getEventEndWorldUpdate/Engine::getEventEndWorldPostUpdate but be careful - in the next frame the transformation will reset to the original due to interpolation. i.e. you need to set your own transformation in each frame. 1
Recommended Posts