Basically the rundown here is I’m replicating the kinematic system of the Canada Arm which operates on the principle of adjusting joint angles to position the end effector at a specific Vector3 value.
I have it working when the arm is operating from a level base as such: https://gyazo.com/8dbe298712a459bfec14b4c6e5784c7e
However when the base is rotated as displayed in the following gif, the arm is offset from the actual point it is meant to be following.
https://gyazo.com/7c018f46cf0baae323e0cfd01c4de93b
I’m not the best with inverse kinematics and this is really my first experiment with the concept. Any ideas how to simply this function or correct any calculation errors to prevent this undesired effect?
The function for the entire arm is listed below:
function updatejoints()
–//Shoulder Rotation
local differencez = script.Parent.ShoulderBase.CFrame:PointToObjectSpace(script.Parent.WristPos.Position)
joints.ShoulderRotation.C0 = CFrame.Angles(0,0,-(math.rad(90) - math.atan2(differencez.Z,differencez.X)))
--//Vertical Computation
local adjustment = CFrame.new(script.Parent.ShoulderBase2.Position, script.Parent.WristPos.Position)
script.Parent.ShoulderBase2.CFrame = adjustment
local adjustangle = ((math.rad(script.Parent.ShoulderBase2.Orientation.X)))
--//Shoulder Pitch
local armlength = ((script.Parent.ShoulderBase.Position - script.Parent.WristPos.Position).Magnitude)
local lowerarmlength = ((script.Parent.ShoulderBase.Position - script.Parent.UpperArm.Elbow.Base.Position).Magnitude)
local upperarmlength = ((script.Parent.UpperArm.Elbow.Base.Position - script.Parent.Wrist2.Base.Position).Magnitude)
local rad = ((lowerarmlength^2+armlength^2-upperarmlength^2)/(2*(lowerarmlength*armlength)))
local shoulderangle = math.acos(rad)
script.Parent.Joints.ShoulderPitch.C0 = CFrame.Angles(0,0,(shoulderangle+adjustangle))
--//Elbow (calculates opposite and then subtracts both from 180 to find elbow)
local rad2 = ((armlength^2+upperarmlength^2-lowerarmlength^2)/(2*(armlength*upperarmlength)))
local oppositeshoulderangle = math.acos(rad2)
local elbowangle = math.rad(180-math.deg(shoulderangle)-math.deg(oppositeshoulderangle))
script.Parent.Joints.Elbow.C0 = CFrame.Angles(0,0,math.rad(180)+elbowangle)
end