I spent some time fiddling with configurable joints as I found documentation to be only marginally useful in fully understanding how they are designed to work. I still have some doubts, but I wrote down all I know about setting up configurable joint. Hope it helps!
Start with a simple setup and do some experiments until you are comfortable with it. Here is how to get started.
Create an empty gameobject, name it “controller”, and add rigidbody component to it. This represents the controller’s center of mass as a point mass in world space. Assign it mass. You can set “use gravity” and “is kinematic” as needed. Add the mesh(es), collider(s) to child object(s), rotated and positioned as needed. To make it easier, adjust your mesh(es) to make sure the center (of mass) for controller is at local origin (pivot).
Create another empty gameobject, name it “baton” and add rigidbody component to it. Assign it mass. You can enable “use gravity” if you wish. Obviously, “is kinematic” is unset. This represents the baton’s center of mass as a point mass in world space. Assume transform.forward represents the orientation of baton. Add mesh(es), collider(s) to child object(s), rotated and positioned as needed. To make it easier, adjust your mesh(es) to make sure the center (of mass) for baton is at local origin (pivot). NOTE: Baton should not be parented to controller.
Position and orient the baton in world space as you want it near the controller to represent initial/rest/neutral state. Add a Configurable Joint to it and assign controller as connected rigidbody. NOTE: If baton has ‘use gravity’ set and controller is not kinematic then make sure the controller mass is at least 3 times the baton’s mass. The forces applied by joint are affected by this ratio. To verify this, set joint anchor to (0,0,0) and all constraints to locked, enter play-mode and verify baton stays at its initial position. If not, adjust controller’s mass higher until this is satisfied.
The joint’s connected anchor represents the joint’s hinge/pivot/origin in connected body’s local space. Primary Axis is it’s X axis; Secondary Axis is it’s Y axis and Z axis is auto computed orthogonal to X,Y. The target position, velocity, rotation and angular velocity are all relative to initial state and interpreted according to joint’s origin, axes. Based on how you want the baton to move and rotate, you should configure the constraints and assign values to limits, drive forces etc. Documentation explains this part well.
NOTE:
(a) If connected body moves then the connected anchor in world space will change accordingly.
(b) Unity uses left hand rule for rotations.
(c) Target Rotation is interpreted as rotation towards, so apply Quaternion.Inverse() to the rotation expected. Ex. to rotate joint by Euler angles (x,y,z) then:
joint.targetRotation = Quaternion.Inverse(Quaternion.Euler(new Vector3(x,y,z)));
(d) For Target Position, Velocity and Rotation, the selected drive’s Position Spring and Damper must have values. Adjust Damper to be slightly lower value than Spring, as needed.
(e) For Target Angular Velocity, the selected drive’s Position Spring must be 0. Damper and Maximum Force must have same values. For unknown reason, when slerp drive is chosen, the angular velocity is inversely interpreted relative to axes.