From: <sv...@ww...> - 2004-12-13 08:48:56
|
Author: mkrose Date: 2004-12-13 00:48:48 -0800 (Mon, 13 Dec 2004) New Revision: 1375 Modified: trunk/CSP/CSPSim/CHANGES.current trunk/CSP/CSPSim/Include/Controller.h trunk/CSP/CSPSim/Source/Controller.cpp Log: Improve animations for control surfaces of remote vehicles by interpolating positions. Browse at: https://www.zerobar.net/viewcvs/viewcvs.cgi?view=rev&rev=1375 Modified: trunk/CSP/CSPSim/CHANGES.current =================================================================== --- trunk/CSP/CSPSim/CHANGES.current 2004-12-13 08:17:13 UTC (rev 1374) +++ trunk/CSP/CSPSim/CHANGES.current 2004-12-13 08:48:48 UTC (rev 1375) @@ -21,6 +21,9 @@ * Add vehicle acceleration to the bus, and display G-force on the screen. + * Improve animations for control surfaces of remote vehicles by + interpolating positions. + 2004-12-05: delta * Updated CSPSim.vcproj, added SimNet to the build, cleaned up source and header directories and added a custom build step on Modified: trunk/CSP/CSPSim/Include/Controller.h =================================================================== --- trunk/CSP/CSPSim/Include/Controller.h 2004-12-13 08:17:13 UTC (rev 1374) +++ trunk/CSP/CSPSim/Include/Controller.h 2004-12-13 08:48:48 UTC (rev 1375) @@ -35,19 +35,30 @@ namespace simnet { class NetworkMessage; } -class AnimationUpdate { +class RemoteAnimationUpdate { DataChannel<double>::CRef m_Channel; simdata::uint8 m_LastValue; public: - AnimationUpdate(): m_LastValue(0) { } + RemoteAnimationUpdate(): m_LastValue(0) { } void bind(DataChannel<double>::CRef const &channel) { m_Channel = channel; } bool update(); inline simdata::uint8 value() const { return m_LastValue; } inline static double convert(simdata::uint8 value); }; +class LocalAnimationUpdate { + DataChannel<double>::Ref m_Channel; + double m_Target; +public: + LocalAnimationUpdate(): m_Target(0) { } + void bind(DataChannel<double>::Ref const &channel) { m_Channel = channel; } + void setTarget(simdata::uint8 value); + void update(double dt); +}; + + /** Interface for controlling remote copies of an object. */ class RemoteController: public System { @@ -55,11 +66,11 @@ DataChannel<simdata::Vector3>::CRef b_Velocity; DataChannel<simdata::Vector3>::CRef b_AngularVelocity; DataChannel<simdata::Quat>::CRef b_Attitude; - AnimationUpdate m_GearExtension; - AnimationUpdate m_AileronDeflection; - AnimationUpdate m_ElevatorDeflection; - AnimationUpdate m_RudderDeflection; - AnimationUpdate m_AirbrakeDeflection; + RemoteAnimationUpdate m_GearExtension; + RemoteAnimationUpdate m_AileronDeflection; + RemoteAnimationUpdate m_ElevatorDeflection; + RemoteAnimationUpdate m_RudderDeflection; + RemoteAnimationUpdate m_AirbrakeDeflection; int m_UpdateDelay; protected: @@ -92,6 +103,12 @@ DataChannel<double>::Ref b_ElevatorDeflection; DataChannel<double>::Ref b_RudderDeflection; DataChannel<double>::Ref b_AirbrakeDeflection; + LocalAnimationUpdate m_GearExtension; + LocalAnimationUpdate m_AileronDeflection; + LocalAnimationUpdate m_ElevatorDeflection; + LocalAnimationUpdate m_RudderDeflection; + LocalAnimationUpdate m_AirbrakeDeflection; + // dynamic properties DataChannel<simdata::Vector3>::Ref b_Position; DataChannel<simdata::Vector3>::Ref b_Velocity; Modified: trunk/CSP/CSPSim/Source/Controller.cpp =================================================================== --- trunk/CSP/CSPSim/Source/Controller.cpp 2004-12-13 08:17:13 UTC (rev 1374) +++ trunk/CSP/CSPSim/Source/Controller.cpp 2004-12-13 08:48:48 UTC (rev 1375) @@ -55,7 +55,7 @@ m_AirbrakeDeflection.bind(bus->getChannel("ControlSurfaces.AirbrakeDeflection")); } -bool AnimationUpdate::update() { +bool RemoteAnimationUpdate::update() { if (m_Channel.valid()) { simdata::uint8 x = static_cast<simdata::uint8>(100.0 * m_Channel->value() + 128); if (x != m_LastValue) { @@ -66,9 +66,20 @@ return false; } -inline double AnimationUpdate::convert(simdata::uint8 x) { return 0.01 * (static_cast<double>(x) - 128.0); } +void LocalAnimationUpdate::setTarget(simdata::uint8 value) { + m_Target = 0.01 * (static_cast<double>(value) - 128.0); +} +void LocalAnimationUpdate::update(double dt) { + double value = m_Channel->value(); + if (value < m_Target - 0.001) { + m_Channel->value() = std::min(value + 1.0 * dt, m_Target); // ~60 deg/sec + } else if (value > m_Target + 0.001) { + m_Channel->value() = std::max(value - 1.0 * dt, m_Target); // ~60 deg/sec + } +} + simdata::Ref<simnet::NetworkMessage> RemoteController::getUpdate(simcore::TimeStamp current_timestamp, simdata::SimTime interval, int detail) { // TODO (in subclass) compare interval to current_timestamp - last_timestamp to decide if // we need to generate a new message. better, need to find a simple way to cache the @@ -160,6 +171,11 @@ b_Velocity = bus->getSharedChannel(bus::Kinetics::Velocity, true, true); b_AngularVelocity = bus->getSharedChannel(bus::Kinetics::AngularVelocity, true, true); b_Attitude = bus->getSharedChannel(bus::Kinetics::Attitude, true, true); + m_GearExtension.bind(b_GearExtension); + m_AileronDeflection.bind(b_AileronDeflection); + m_ElevatorDeflection.bind(b_ElevatorDeflection); + m_RudderDeflection.bind(b_RudderDeflection); + m_AirbrakeDeflection.bind(b_AirbrakeDeflection); } bool LocalController::sequentialUpdate(simcore::TimeStamp stamp, simcore::TimeStamp now, simdata::SimTime &dt) { @@ -201,16 +217,16 @@ setTargetPosition(update->position().Vector3() + m_TargetVelocity * dt); b_GearExtension->value() = (update->gear_up() ? 0.0 : 1.0); if (update->has_elevator_deflection()) { - b_ElevatorDeflection->value() = AnimationUpdate::convert(update->elevator_deflection()); + m_ElevatorDeflection.setTarget(update->elevator_deflection()); } if (update->has_airbrake_deflection()) { - b_AirbrakeDeflection->value() = AnimationUpdate::convert(update->airbrake_deflection()); + m_AirbrakeDeflection.setTarget(update->airbrake_deflection()); } if (update->has_aileron_deflection()) { - b_AileronDeflection->value() = AnimationUpdate::convert(update->aileron_deflection()); + m_AileronDeflection.setTarget(update->aileron_deflection()); } if (update->has_rudder_deflection()) { - b_RudderDeflection->value() = AnimationUpdate::convert(update->rudder_deflection()); + m_RudderDeflection.setTarget(update->rudder_deflection()); } } else { CSP_LOG(OBJECT, INFO, "non sequential update: msg=" << update->timestamp() << " local=" << now); @@ -242,6 +258,12 @@ if (f > 1.0) f = 1.0; b_Attitude->value().slerp(f, b_Attitude->value(), m_TargetAttitude); } + { + m_ElevatorDeflection.update(dt); + m_AirbrakeDeflection.update(dt); + m_AileronDeflection.update(dt); + m_RudderDeflection.update(dt); + } return 0.0; } |