def METHOD_NAME(self,R,ori=None):
    """Sets the orientation of the camera to the so3 element R. 
    If ori is provided, it is an orientation list (e.g., ['x','y','z'])
    that tells the function how to interpret the columns of R in terms of
    the right, down, and fwd axes of the camera.  Its default value is 
    None.
    """
    import math
    #Rdes*oR*[right,down,fwd] = R_euler(rot)*o*[right,down,fwd]
    if ori is not None:
        o = orientation_matrix(*self.ori)
        oR = orientation_matrix(*ori)
        R = so3.mul(R,so3.mul(so3.inv(oR),o))
    #Ry = so3.rotation([0,1,0],self.rot[0])
    #Rx = so3.rotation([1,0,0],self.rot[1])
    #Rz = so3.rotation([0,0,1],self.rot[2])
    #set self.rot to fulfill constraint R = Rz*Rx*Ry
    #     [cz -sz 0][1  0   0][cy  0 sy]   [cz -szcx  szsx][cy  0 sy]
    # R = [sz  cz 0][0 cx -sx][0   1  0] = [sz  czcx -czsx][0   1 0 ]
    #     [0   0  1][0 sx  cx][-sy 0 cy]   [0    sx     cx][-sy 0 cy]
    #    [czcy-szsxsy   -szcx  czsy+szsxcy ]
    #  = [szcy+czsxsy    czcx  szsy-czsxcy ]
    #    [-cxsy           sx   cxcy        ]
    m = so3.matrix(R)
    cx = math.sqrt(m[0][1]**2 + m[1][1]**2)
    #assume cx is positive (pitch in range [-pi/2,pi/2])
    sx = m[2][1]
    self.rot[1] = math.atan2(sx,cx)
    if abs(cx) > 1e-5:
        sz = -m[0][1]
        cz = m[1][1]
        sy = -m[2][0]
        cy = m[2][2]
        self.rot[2] = math.atan2(sz,cz)
        self.rot[0] = math.atan2(sy,cy)
    else:
        #near vertical, have redundancy, have cx=0,sx = +/-1, set Ry=0 (so cy=1, sy=0)
        self.rot[0] = 0
        cz = m[0][0]
        sz = m[1][0]
        self.rot[2] = math.atan2(sz,cz)