Program Listing for File HuntCrossley.h#
↰ Return to documentation for file (include/Karana/Collision/HuntCrossley.h)
/*
* Copyright (c) 2024-2026 Karana Dynamics Pty Ltd. All rights reserved.
*
* NOTICE TO USER:
*
* This source code and/or documentation (the "Licensed Materials") is
* the confidential and proprietary information of Karana Dynamics Inc.
* Use of these Licensed Materials is governed by the terms and conditions
* of a separate software license agreement between Karana Dynamics and the
* Licensee ("License Agreement"). Unless expressly permitted under that
* agreement, any reproduction, modification, distribution, or disclosure
* of the Licensed Materials, in whole or in part, to any third party
* without the prior written consent of Karana Dynamics is strictly prohibited.
*
* THE LICENSED MATERIALS ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
* KARANA DYNAMICS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, AND
* FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL KARANA DYNAMICS BE LIABLE FOR ANY DAMAGES WHATSOEVER,
* INCLUDING BUT NOT LIMITED TO LOSS OF PROFITS, DATA, OR USE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, WHETHER IN CONTRACT, TORT,
* OR OTHERWISE ARISING OUT OF OR IN CONNECTION WITH THE LICENSED MATERIALS.
*
* U.S. Government End Users: The Licensed Materials are a "commercial item"
* as defined at 48 C.F.R. 2.101, and are provided to the U.S. Government
* only as a commercial end item under the terms of this license.
*
* Any use of the Licensed Materials in individual or commercial software must
* include, in the user documentation and internal source code comments,
* this Notice, Disclaimer, and U.S. Government Use Provision.
*/
/**
* @file
* @brief Hunt-Crossley contact force model.
*/
#pragma once
#include "Karana/Collision/ContactForce.h"
#include "Karana/Frame/ChainedFrameToFrame.h"
namespace Karana::Collision {
/**
* @class HuntCrossley
* @brief ContactForceBase implementation using a Hunt-Crossley model
*
* See \sref{collision_dynamics_sec} for more discussion on
* contact and collision dynamics.
*/
class HuntCrossley : public ContactForceBase {
public:
/// Use the constructor from ContactForceBase
using ContactForceBase::ContactForceBase;
/**
* @brief Create an instance of the HuntCrossley contact force model.
*
* @param name The name for the HuntCrossley instance.
* @return A ks_ptr to the newly created HuntCrossley contact force model.
*/
static kc::ks_ptr<HuntCrossley> create(std::string_view name);
/**
* @brief Compute the contact force for the associated contact.
*
* @param contact The contact to compute the force for.
* @param nd_1 The contact node on the first body.
* @param nd_2 The contact node on the second body.
* @returns The contact force.
*/
km::SpatialVector computeForce(const FrameContact &contact,
const kc::ks_ptr<kd::Node> &nd_1,
const kc::ks_ptr<kd::Node> &nd_2) final;
/**
* @class HuntCrossleyParams
* @brief Structure that holds the HuntCrossley contact force parameters.
*/
struct HuntCrossleyParams {
/// Normal penetration stiffness coefficient
double kp = km::notReadyNaN;
/// Normal penetration restitution/damping coefficient
double kc = km::notReadyNaN;
/// Exponent
double n = km::notReadyNaN;
/// Friction coefficient
double mu = km::notReadyNaN;
/**
* @brief Tolerance at which friction is linearly interpolated between the real value
* and 0.
*
* To avoid jittering for cases like rolling without friction, near zero, the friction
* force uses a linear interpolation between the full friction force and zero. This
* avoids rapid, large changes in the friction force as the velocity changes sign, and
* instead, smoothly, linearly interpolates between these large forces over a region of
* linear_region_tol * 2.
*/
double linear_region_tol = km::notReadyNaN;
};
/**
* @class HuntCrossleyScratch
* @brief Structure that holds the HuntCrossley scratch data
*/
struct HuntCrossleyScratch {
/// Normal penetration
double penetration = km::notReadyNaN;
/// contact linear velocity
km::Vec3 linvel;
/// contact force
km::Vec3 f;
};
/// Parameters used for the contact model.
HuntCrossleyParams params;
/// Scratch values
HuntCrossleyScratch scratch;
/**
* @brief Used to ensure the HuntCrossley contact force model is ready.
*
* @return true if the HuntCrossley is ready, false otherwise.
*/
bool isReady() const final;
std::string
dumpString(std::string_view prefix,
const Karana::Core::Base::DumpOptions *options = nullptr) const override;
private:
/** Return the magnitude of the normal force based on the
Hunt-Crossley model */
/**
* @brief Return the magnitude of the normal force based on the Hunt-Crossley model
*
* @param fext_dir The external force direction.
* @return The normal force from the Hunt-Crossley contact model.
*/
double _getHuntCrossleyNormalForce(const Karana::Math::Vec3 &fext_dir) const;
/**
* @brief Return the tangential force based on the Coulomb friction model.
*
* @param fext_dir The external force direction.
* @param normal_fmag The magnitude of the normal force.
*/
Karana::Math::Vec3 _getCoulombFrictionTangentForce(const Karana::Math::Vec3 &fext_dir,
double normal_fmag) const;
};
} // namespace Karana::Collision