// ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- void ChPitmanArm::Initialize(std::shared_ptr<ChBodyAuxRef> chassis, const ChVector<>& location, const ChQuaternion<>& rotation) { m_position = ChCoordsys<>(location, rotation); // Chassis orientation (expressed in absolute frame) // Recall that the suspension reference frame is aligned with the chassis. ChQuaternion<> chassisRot = chassis->GetFrame_REF_to_abs().GetRot(); // Express the steering reference frame in the absolute coordinate system. ChFrame<> steering_to_abs(location, rotation); steering_to_abs.ConcatenatePreTransformation(chassis->GetFrame_REF_to_abs()); // Transform all points and directions to absolute frame. std::vector<ChVector<>> points(NUM_POINTS); std::vector<ChVector<>> dirs(NUM_DIRS); for (int i = 0; i < NUM_POINTS; i++) { ChVector<> rel_pos = getLocation(static_cast<PointId>(i)); points[i] = steering_to_abs.TransformPointLocalToParent(rel_pos); } for (int i = 0; i < NUM_DIRS; i++) { ChVector<> rel_dir = getDirection(static_cast<DirectionId>(i)); dirs[i] = steering_to_abs.TransformDirectionLocalToParent(rel_dir); } // Unit vectors for orientation matrices. ChVector<> u; ChVector<> v; ChVector<> w; ChMatrix33<> rot; // Create and initialize the steering link body m_link = std::shared_ptr<ChBody>(chassis->GetSystem()->NewBody()); m_link->SetNameString(m_name + "_link"); m_link->SetPos(points[STEERINGLINK]); m_link->SetRot(steering_to_abs.GetRot()); m_link->SetMass(getSteeringLinkMass()); if (m_vehicle_frame_inertia) { ChMatrix33<> inertia = TransformInertiaMatrix(getSteeringLinkInertiaMoments(), getSteeringLinkInertiaProducts(), chassisRot, steering_to_abs.GetRot()); m_link->SetInertia(inertia); } else { m_link->SetInertiaXX(getSteeringLinkInertiaMoments()); m_link->SetInertiaXY(getSteeringLinkInertiaProducts()); } chassis->GetSystem()->AddBody(m_link); m_pP = m_link->TransformPointParentToLocal(points[UNIV]); m_pI = m_link->TransformPointParentToLocal(points[REVSPH_S]); m_pTP = m_link->TransformPointParentToLocal(points[TIEROD_PA]); m_pTI = m_link->TransformPointParentToLocal(points[TIEROD_IA]); // Create and initialize the Pitman arm body m_arm = std::shared_ptr<ChBody>(chassis->GetSystem()->NewBody()); m_arm->SetNameString(m_name + "_arm"); m_arm->SetPos(points[PITMANARM]); m_arm->SetRot(steering_to_abs.GetRot()); m_arm->SetMass(getPitmanArmMass()); if (m_vehicle_frame_inertia) { ChMatrix33<> inertia = TransformInertiaMatrix(getPitmanArmInertiaMoments(), getPitmanArmInertiaProducts(), chassisRot, steering_to_abs.GetRot()); m_arm->SetInertia(inertia); } else { m_arm->SetInertiaXX(getPitmanArmInertiaMoments()); m_arm->SetInertiaXY(getPitmanArmInertiaProducts()); } chassis->GetSystem()->AddBody(m_arm); // Cache points for arm visualization (expressed in the arm frame) m_pC = m_arm->TransformPointParentToLocal(points[REV]); m_pL = m_arm->TransformPointParentToLocal(points[UNIV]); // Create and initialize the revolute joint between chassis and Pitman arm. // Note that this is modeled as a ChLinkEngine to allow driving it with // imposed rotation (steering input). // The z direction of the joint orientation matrix is dirs[REV_AXIS], assumed // to be a unit vector. u = points[PITMANARM] - points[REV]; v = Vcross(dirs[REV_AXIS], u); v.Normalize(); u = Vcross(v, dirs[REV_AXIS]); rot.Set_A_axis(u, v, dirs[REV_AXIS]); m_revolute = std::make_shared<ChLinkMotorRotationAngle>(); m_revolute->SetNameString(m_name + "_revolute"); m_revolute->Initialize(chassis, m_arm, ChFrame<>(points[REV], rot.Get_A_quaternion())); auto motor_fun = std::make_shared<ChFunction_Setpoint>(); m_revolute->SetAngleFunction(motor_fun); chassis->GetSystem()->AddLink(m_revolute); // Create and initialize the universal joint between the Pitman arm and steering link. // The x and y directions of the joint orientation matrix are given by // dirs[UNIV_AXIS_ARM] and dirs[UNIV_AXIS_LINK], assumed to be unit vectors // and orthogonal. w = Vcross(dirs[UNIV_AXIS_ARM], dirs[UNIV_AXIS_LINK]); rot.Set_A_axis(dirs[UNIV_AXIS_ARM], dirs[UNIV_AXIS_LINK], w); m_universal = std::make_shared<ChLinkUniversal>(); m_universal->SetNameString(m_name + "_universal"); m_universal->Initialize(m_arm, m_link, ChFrame<>(points[UNIV], rot.Get_A_quaternion())); chassis->GetSystem()->AddLink(m_universal); // Create and initialize the revolute-spherical joint (massless idler arm). // The length of the idler arm is the distance between the two hardpoints. // The z direction of the revolute joint orientation matrix is // dirs[REVSPH_AXIS], assumed to be a unit vector. double distance = (points[REVSPH_S] - points[REVSPH_R]).Length(); u = points[REVSPH_S] - points[REVSPH_R]; v = Vcross(dirs[REVSPH_AXIS], u); v.Normalize(); u = Vcross(v, dirs[REVSPH_AXIS]); rot.Set_A_axis(u, v, dirs[REVSPH_AXIS]); m_revsph = std::make_shared<ChLinkRevoluteSpherical>(); m_revsph->SetNameString(m_name + "_revsph"); m_revsph->Initialize(chassis, m_link, ChCoordsys<>(points[REVSPH_R], rot.Get_A_quaternion()), distance); chassis->GetSystem()->AddLink(m_revsph); }
TDEIcon TDEIconTheme::iconPath(const TQString& name, int size, TDEIcon::MatchType match) const { TDEIcon icon; TQString path; int delta = -1000, dw; TDEIconThemeDir *dir; dw = 1000; // shut up, gcc TQPtrListIterator<TDEIconThemeDir> dirs(mDirs); for ( ; dirs.current(); ++dirs) { dir = dirs.current(); if (match == TDEIcon::MatchExact) { if ((dir->type() == TDEIcon::Fixed) && (dir->size() != size)) continue; if ((dir->type() == TDEIcon::Scalable) && ((size < dir->minSize()) || (size > dir->maxSize()))) continue; if ((dir->type() == TDEIcon::Threshold) && (abs(dir->size()-size) > dir->threshold())) continue; } else { // dw < 0 means need to scale up to get an icon of the requested size if (dir->type() == TDEIcon::Fixed) { dw = dir->size() - size; } else if (dir->type() == TDEIcon::Scalable) { if (size < dir->minSize()) dw = dir->minSize() - size; else if (size > dir->maxSize()) dw = dir->maxSize() - size; else dw = 0; } else if (dir->type() == TDEIcon::Threshold) { if (size < dir->size() - dir->threshold()) dw = dir->size() - dir->threshold() - size; else if (size > dir->size() + dir->threshold()) dw = dir->size() + dir->threshold() - size; else dw = 0; } /* Skip this if we've found a closer one, unless it's a downscale, and we only had upscales befores. This is to avoid scaling up unless we have to, since that looks very ugly */ if (/*(abs(dw) >= abs(delta)) ||*/ (delta > 0 && dw < 0)) continue; } path = dir->iconPath(name); if (path.isEmpty()) continue; icon.path = path; icon.size = dir->size(); icon.type = dir->type(); icon.threshold = dir->threshold(); icon.context = dir->context(); // if we got in MatchExact that far, we find no better if (match == TDEIcon::MatchExact) return icon; else { delta = dw; if (delta==0) return icon; // We won't find a better match anyway } } return icon; }
pn::string_view default_factory_scenario_path() { static pn::string s = pn::format("{0}/{1}", dirs().scenarios, kFactoryScenarioIdentifier); return s; }