@@ -462,7 +462,7 @@ def quat_normalize(q):
462462 Parameters
463463 ----------
464464 q : numpy array
465- Quaternion [qx, qy, qz, qw ] (scalar last, Hamilton convention )
465+ Quaternion [qw, qx, qy, qz] (scalar first )
466466
467467 Returns
468468 -------
@@ -471,36 +471,36 @@ def quat_normalize(q):
471471 """
472472 mag = np .linalg .norm (q )
473473 if mag < np .finfo (float ).eps :
474- return np .array ([0 .0 , 0.0 , 0.0 , 1 .0 ])
474+ return np .array ([1 .0 , 0.0 , 0.0 , 0 .0 ])
475475 return q / mag
476476
477477
478478def quat_multiply (q1 , q2 ):
479479 """Multiply two quaternions using Hamilton convention.
480480
481- Computes q1 * q2 in scalar-last format [qx, qy, qz, qw ].
481+ Computes q1 * q2 in scalar-first format [qw, qx, qy, qz].
482482
483483 Parameters
484484 ----------
485485 q1 : numpy array
486- First quaternion [qx, qy, qz, qw ]
486+ First quaternion [qw, qx, qy, qz]
487487 q2 : numpy array
488- Second quaternion [qx, qy, qz, qw ]
488+ Second quaternion [qw, qx, qy, qz]
489489
490490 Returns
491491 -------
492492 numpy array
493493 Product quaternion q1 * q2
494494 """
495- qx1 , qy1 , qz1 , qw1 = q1
496- qx2 , qy2 , qz2 , qw2 = q2
495+ qw1 , qx1 , qy1 , qz1 = q1
496+ qw2 , qx2 , qy2 , qz2 = q2
497497
498498 return np .array (
499499 [
500+ qw1 * qw2 - qx1 * qx2 - qy1 * qy2 - qz1 * qz2 ,
500501 qw1 * qx2 + qx1 * qw2 + qy1 * qz2 - qz1 * qy2 ,
501502 qw1 * qy2 - qx1 * qz2 + qy1 * qw2 + qz1 * qx2 ,
502503 qw1 * qz2 + qx1 * qy2 - qy1 * qx2 + qz1 * qw2 ,
503- qw1 * qw2 - qx1 * qx2 - qy1 * qy2 - qz1 * qz2 ,
504504 ]
505505 )
506506
@@ -511,14 +511,14 @@ def quat_conjugate(q):
511511 Parameters
512512 ----------
513513 q : numpy array
514- Quaternion [qx, qy, qz, qw ]
514+ Quaternion [qw, qx, qy, qz]
515515
516516 Returns
517517 -------
518518 numpy array
519- Conjugate quaternion [-qx, -qy, -qz, qw ]
519+ Conjugate quaternion [qw, -qx, -qy, -qz]
520520 """
521- return np .array ([- q [0 ], - q [1 ], - q [2 ], q [3 ]])
521+ return np .array ([q [0 ], - q [1 ], - q [2 ], - q [3 ]])
522522
523523
524524def quat_inverse (q ):
@@ -529,7 +529,7 @@ def quat_inverse(q):
529529 Parameters
530530 ----------
531531 q : numpy array
532- Quaternion [qx, qy, qz, qw ]
532+ Quaternion [qw, qx, qy, qz]
533533
534534 Returns
535535 -------
@@ -550,7 +550,7 @@ def quat_rotate_vector(q, v):
550550 Parameters
551551 ----------
552552 q : numpy array
553- Quaternion [qx, qy, qz, qw ]
553+ Quaternion [qw, qx, qy, qz]
554554 v : numpy array
555555 3D vector to rotate
556556
@@ -559,37 +559,51 @@ def quat_rotate_vector(q, v):
559559 numpy array
560560 Rotated 3D vector
561561 """
562- # Convert vector to pure quaternion [vx, vy, vz, 0 ]
563- v_quat = np .array ([v [0 ], v [1 ], v [2 ], 0.0 ])
562+ # Convert vector to pure quaternion [0, vx, vy, vz]
563+ v_quat = np .array ([0.0 , v [0 ], v [1 ], v [2 ]])
564564
565565 # Perform rotation: q * v * q_conj
566566 q_conj = quat_conjugate (q )
567567 result = quat_multiply (quat_multiply (q , v_quat ), q_conj )
568568
569- return result [0 : 3 ]
569+ return result [1 : 4 ]
570570
571571
572572def quat_to_dcm (q ):
573573 """Convert quaternion to direction cosine matrix (DCM).
574574
575+ Implements equation (6.79) from the textbook.
576+
575577 Parameters
576578 ----------
577579 q : numpy array
578- Quaternion [qx, qy, qz, qw] (scalar last, Hamilton convention)
580+ Quaternion [qw, qx, qy, qz]
579581
580582 Returns
581583 -------
582584 numpy array
583585 3x3 DCM for rotation from reference frame to body frame
584586 """
585- qx , qy , qz , qw = q
587+ qw , qx , qy , qz = q
586588
587- # DCM from quaternion
589+ # DCM from quaternion (equation 6.79)
588590 dcm = np .array (
589591 [
590- [1 - 2 * (qy ** 2 + qz ** 2 ), 2 * (qx * qy + qw * qz ), 2 * (qx * qz - qw * qy )],
591- [2 * (qx * qy - qw * qz ), 1 - 2 * (qx ** 2 + qz ** 2 ), 2 * (qy * qz + qw * qx )],
592- [2 * (qx * qz + qw * qy ), 2 * (qy * qz - qw * qx ), 1 - 2 * (qx ** 2 + qy ** 2 )],
592+ [
593+ qw ** 2 + qx ** 2 - qy ** 2 - qz ** 2 ,
594+ 2 * (qx * qy + qw * qz ),
595+ 2 * (qx * qz - qw * qy ),
596+ ],
597+ [
598+ 2 * (qx * qy - qw * qz ),
599+ qw ** 2 - qx ** 2 + qy ** 2 - qz ** 2 ,
600+ 2 * (qy * qz + qw * qx ),
601+ ],
602+ [
603+ 2 * (qx * qz + qw * qy ),
604+ 2 * (qy * qz - qw * qx ),
605+ qw ** 2 - qx ** 2 - qy ** 2 + qz ** 2 ,
606+ ],
593607 ]
594608 )
595609 return dcm
@@ -608,7 +622,7 @@ def dcm_to_quat(dcm):
608622 Returns
609623 -------
610624 numpy array
611- Quaternion [qx, qy, qz, qw] (scalar last)
625+ Quaternion [qw, qx, qy, qz]
612626 """
613627 trace = np .trace (dcm )
614628
@@ -637,7 +651,7 @@ def dcm_to_quat(dcm):
637651 qy = (dcm [1 , 2 ] + dcm [2 , 1 ]) / s
638652 qz = 0.25 * s
639653
640- return np .array ([qx , qy , qz , qw ])
654+ return np .array ([qw , qx , qy , qz ])
641655
642656
643657def quat_to_euler (q ):
@@ -646,7 +660,7 @@ def quat_to_euler(q):
646660 Parameters
647661 ----------
648662 q : numpy array
649- Quaternion [qx, qy, qz, qw] (scalar last)
663+ Quaternion [qw, qx, qy, qz]
650664
651665 Returns
652666 -------
@@ -657,7 +671,7 @@ def quat_to_euler(q):
657671 yaw : float
658672 Yaw angle in radians (rotation about z-axis)
659673 """
660- qx , qy , qz , qw = q
674+ qw , qx , qy , qz = q
661675
662676 # Roll (x-axis rotation)
663677 sinr_cosp = 2 * (qw * qx + qy * qz )
@@ -694,7 +708,7 @@ def euler_to_quat(roll, pitch, yaw):
694708 Returns
695709 -------
696710 numpy array
697- Quaternion [qx, qy, qz, qw] (scalar last)
711+ Quaternion [qw, qx, qy, qz]
698712 """
699713 cy = np .cos (yaw * 0.5 )
700714 sy = np .sin (yaw * 0.5 )
@@ -708,7 +722,7 @@ def euler_to_quat(roll, pitch, yaw):
708722 qy = cr * sp * cy + sr * cp * sy
709723 qz = cr * cp * sy - sr * sp * cy
710724
711- return np .array ([qx , qy , qz , qw ])
725+ return np .array ([qw , qx , qy , qz ])
712726
713727
714728def quat_slerp (q1 , q2 , t ):
@@ -717,9 +731,9 @@ def quat_slerp(q1, q2, t):
717731 Parameters
718732 ----------
719733 q1 : numpy array
720- Start quaternion [qx, qy, qz, qw ]
734+ Start quaternion [qw, qx, qy, qz]
721735 q2 : numpy array
722- End quaternion [qx, qy, qz, qw ]
736+ End quaternion [qw, qx, qy, qz]
723737 t : float
724738 Interpolation parameter in [0, 1]
725739
0 commit comments