Пример #1
0
    def update(self, measured_pos_array, desired_pos_array):
        if hasattr(self, 'desired_pos_array'):
            # update target velocities
            for i in range(3):
                self.desired_vel_array[i] = (
                    desired_pos_array[i] -
                    self.desired_pos_array[i]) / global_time.getDelta()
        else:
            self.desired_vel_array = array([0, 0, 0])
        self.desired_pos_array = desired_pos_array
        actuator_commands = []
        if not (len(self.desired_pos_array) == self.amount_of_joints ==
                len(measured_pos_array)):
            logger.error(
                "LimbController.update: position array sizes mismatched!",
                measured_pos_array=measured_pos_array,
                desired_pos_array=self.desired_pos_array)
            raise ValueError(
                "LimbController.update: position array sizes mismatched!")
        for i in range(len(self.pid_controllers)):
            actuator_command = self.pid_controllers[i].update(
                self.desired_pos_array[i], measured_pos_array[i])

            # JWHONG COMPENSATION FOR EXTEND VS RETRACT SURFACE AREA HACK
            # JWHONG DEADBAND HACK
            if actuator_command > 0:
                actuator_command += self.dearray[i]
            elif actuator_command < 0:
                actuator_command *= self.proparray[i]
                actuator_command -= self.drarray[i]
            actuator_commands.append(actuator_command)
        self.length_rate_commands = actuator_commands
Пример #2
0
 def setSensorReadings(self, yaw, hip_pitch, knee_pitch, shock_depth):
     self.joint_angles = array([yaw, hip_pitch, knee_pitch])
     
     #throw errors if measured joint angles are NaN, out of bounds, etc
     for angle, soft_min, soft_max in zip(self.joint_angles, self.SOFT_MINS, self.SOFT_MAXES):
         if math.isnan(angle):
             logger.error("LegModel.setSensorReadings: NaN where aN expected!",
                         angle=angle,
                         angle_index=self.joint_angles.searchsorted(angle),
                         yaw=yaw,
                         hip_pitch=hip_pitch,
                         knee_pitch=knee_pitch,
                         shock_depth=shock_depth,
                         bad_value="angle")
             raise ValueError("LegModel: Measured angle cannot be NaN.")
             
         if (soft_min > angle) or (angle > soft_max):
             logger.error("LegModel: Measured position outside of soft range!",
                     angle=angle,
                     angle_index=self.joint_angles.searchsorted(angle),
                     yaw=yaw,
                     hip_pitch=hip_pitch,
                     knee_pitch=knee_pitch,
                     shock_depth=shock_depth,
                     soft_min=soft_min,
                     soft_max=soft_max,
                     bad_value="angle")
             print soft_min
             print soft_max
             print angle
             raise ValueError("LegModel: Measured angle out of soft range!")
     self.shock_depth = shock_depth
     self.joint_velocities = self.jv_filter.update(self.joint_angles)        
Пример #3
0
    def update(self, measured_pos_array, desired_pos_array):
        if hasattr(self, 'desired_pos_array'):
            # update target velocities
            for i in range(3):
                self.desired_vel_array[i] = (desired_pos_array[i] - self.desired_pos_array[i]) / global_time.getDelta()
        else:
            self.desired_vel_array = array([0, 0, 0])
        self.desired_pos_array = desired_pos_array
        actuator_commands = []
        if not (len(self.desired_pos_array) == self.amount_of_joints == len(measured_pos_array)):
            logger.error("LimbController.update: position array sizes mismatched!",
                         measured_pos_array=measured_pos_array,
                         desired_pos_array=self.desired_pos_array)
            raise ValueError("LimbController.update: position array sizes mismatched!")
        for i in range(len(self.pid_controllers)):
            actuator_command = self.pid_controllers[i].update(self.desired_pos_array[i],
                                                              measured_pos_array[i])

            # JWHONG COMPENSATION FOR EXTEND VS RETRACT SURFACE AREA HACK
            # JWHONG DEADBAND HACK
            if actuator_command > 0:
                actuator_command += self.dearray[i]
            elif actuator_command < 0:
                actuator_command *= self.proparray[i]
                actuator_command -= self.drarray[i]
            actuator_commands.append(actuator_command)
        self.length_rate_commands = actuator_commands
Пример #4
0
 def updateDelta(self, delta):
     if delta <= 0.0 and self.time != 0.0:
         logger.error("TimeSource.updateDelta: Reversed time error!",
                      initial_time=self.initial_time,
                      initial_delta=self.initial_delta,
                      current_time=self.time,
                      bad_value=delta)
         raise ValueError("TimeSource.updateDelta(): time must be increasing")
     self.delta = delta
     self.time += delta
Пример #5
0
 def updateTime(self, time):
     if time <= self.time and self.time != 0.0:
         logger.error("TimeSource.updateTime: Reversed time error!",
                      initial_time=self.initial_time,
                      initial_delta=self.initial_delta,
                      current_time=self.time,
                      bad_value=time)
         raise ValueError("TimeSource.updateTime(): time must be increasing.\nLast time: %f\nNew time:  %d"%(self.time,time))
     self.delta = time - self.time
     self.time = time
Пример #6
0
    def attributeChanged(self, item):
        if not self.isFillAttributeTree and self.selected_item:
            try:
                # check value chaned
                if item.oldValue == item.text(1):
                    return
                item.oldValue = item.text(1)
                index = item.index
                # check array type, then combine components
                parent = item.parent()
                if type(parent
                        ) == QtGui.QTreeWidgetItem and parent.dataType in (
                            tuple, list, numpy.ndarray):
                    attributeName = parent.text(0)
                    value = []
                    for i in range(parent.childCount()):
                        child = parent.child(i)
                        value.append(child.dataType(child.text(1)))
                    # numpy array
                    if parent.dataType == numpy.ndarray:
                        value = numpy.array(value)
                    # list or tuple
                    else:
                        value = parent.dataType(value)
                else:
                    attributeName = item.text(0)
                    if item.dataType == bool:
                        value = item.dataType(item.text(1) == "True")
                    else:
                        value = item.dataType(item.text(1))

                selectedItems = []
                command = None
                if self.selected_item_categoty == 'Object':
                    command = COMMAND.SET_OBJECT_ATTRIBUTE
                    selectedItems = self.objectList.selectedItems()

                elif self.selected_item_categoty == 'Resource':
                    command = COMMAND.SET_RESOURCE_ATTRIBUTE
                    selectedItems = self.resourceListWidget.selectedItems()

                for selectedItem in selectedItems:
                    selected_item_name = selectedItem.text(0)
                    selected_item_type = selectedItem.text(1)
                    # send changed data
                    self.appCmdQueue.put(
                        command, (selected_item_name, selected_item_type,
                                  attributeName, value, index))

            except:
                logger.error(traceback.format_exc())
                # failed to convert string to dataType, so restore to old value
                item.setText(1, item.oldValue)
Пример #7
0
 def updateGainConstants(self, kparray, kiarray, kdarray, kffarray, kfaarray):
     self.kp  = kparray
     self.ki  = kiarray
     self.kd  = kdarray
     self.kff = kffarray
     self.kfa = kfaarray
     
     if (len(self.kp) != len(self.ki) or len(self.ki) != len(self.kd)):
         logger.error("LimbController.init: Gain array sizes mismatched!",
                      kparray=self.kp,
                      kiarray=self.ki,
                      kdarray=self.kd)
         raise ValueError("LimbController.init: Gain array sizes mismatched!")
     
     for controller, kp, ki, kd, kff, kfa in zip(self.pid_controllers, self.kp, self.ki, self.kd, self.kff, self.kfa):
         controller.updateGainConstants(kp, ki, kd, kff, kfa)
Пример #8
0
 def isErrorInBounds(self, error, measured_pos):
     """tests whether or not the error signal is within reasonable range
     not checking for NaN, since both desired and measured position
     are tested for that
     """
     
     #makes sure the error is bounded by a single leg rotation
     error = error%(2*math.pi)
     error_min = -math.pi/2
     error_max = math.pi/2
     
     #is error within available soft range?
     if error>(measured_pos-error_min) or error>(error_max-measured_pos):
         logger.error("LimbController.isErrorInBounds: error out of soft bounds.",
                     error=error,
                     measured_pos=measured_pos)
         raise ValueError("Error signal points to a position out of soft bounds.")
     return error
Пример #9
0
 def update(self, measured_pos_array, desired_pos_array):
     if hasattr(self, "desired_pos_array"):
         # update target velocities
         for i in range(3):
             self.desired_vel_array[i] = (desired_pos_array[i] - self.desired_pos_array[i]) / global_time.getDelta()
     else:
         self.desired_vel_array = array([0, 0, 0])
     self.desired_pos_array = desired_pos_array
     actuator_commands = []
     if len(self.desired_pos_array) != self.amount_of_joints or len(measured_pos_array) != self.amount_of_joints:
         logger.error(
             "LimbController.update: position array sizes mismatched!",
             measured_pos_array=measured_pos_array,
             desired_pos_array=self.desired_pos_array,
         )
         raise ValueError("LimbController.update:" + " position array sizes mismatched!")
     for i in range(len(self.pid_controllers)):
         actuator_command = self.pid_controllers[i].update(self.desired_pos_array[i], measured_pos_array[i])
         actuator_commands.append(actuator_command)
     self.length_rate_commands = actuator_commands
Пример #10
0
    def updateGainConstants(self, kparray, kiarray, kdarray, kffarray,
                            kfaarray):
        self.kp = kparray
        self.ki = kiarray
        self.kd = kdarray
        self.kff = kffarray
        self.kfa = kfaarray

        if (len(self.kp) != len(self.ki) or len(self.ki) != len(self.kd)):
            logger.error("LimbController.init: Gain array sizes mismatched!",
                         kparray=self.kp,
                         kiarray=self.ki,
                         kdarray=self.kd)
            raise ValueError(
                "LimbController.init: Gain array sizes mismatched!")

        for controller, kp, ki, kd, kff, kfa in zip(self.pid_controllers,
                                                    self.kp, self.ki, self.kd,
                                                    self.kff, self.kfa):
            controller.updateGainConstants(kp, ki, kd, kff, kfa)
Пример #11
0
 def boundDesiredPosition(self,desired_pos):
     #caps desired position to soft movement range
     if math.isnan(desired_pos):
         logger.error("LimbController.boundDesiredPosition: NaN where aN expected!",
                     desired_pos=desired_pos,
                     bad_value="desired_pos")
         raise ValueError("LimbController: desired_pos cannot be NaN.")
     
     command_min=-20
     command_max=20
     
     if desired_pos<command_min or desired_pos>command_max:
         logger.error("LimbController.boundDesiredPosition:"+
                     " desired position out of bounds!",
                     desired_pos=desired_pos,
                     command_min=command_min,
                     command_max=command_max,
                     bad_value="desired_pos")
         raise ValueError("LimbController.boundDesiredPosition:"+
                 " desired position out of soft bounds")
     
     bounded_pos=saturate(desired_pos,command_min,command_max)
     return bounded_pos
Пример #12
0
    def update(self, desired_pos, measured_pos):
        delta_time = time_sources.global_time.getDelta()
        
        # bound the desired position
        desired_pos = self.boundDesiredPosition(desired_pos)

        desired_vel = (desired_pos - self.prev_desired_pos)/delta_time

        error = desired_pos - measured_pos

        self.peak_detector.update(error)
        
        if self.peak_detector.hasConverged():
            if self.peak_detector.isUnstable():
                warningstring=("LimbController: Maximum error for the"+
                        " desired point has increased for %d seconds,"+
                        " but is within converged range.  Might be unstable." %
                        self.peak_detector.getResolveTime() )
                logger.warning(warningstring,
                        desired_pos=desired_pos,
                        measured_pos=measured_pos,
                        error=error, 
                        bad_value=error)
            elif self.peak_detector.isLimitCycle():
                warningstring=("LimbController: Maximum error for the"+
                        " desired point has increased once or more for %d seconds,"+
                        " but is within converged range.  Might be unstable." %
                        self.peak_detector.getResolveTime() )
                logger.warning(warningstring,
                        desired_pos=desired_pos,
                        measured_pos=measured_pos,
                        error=error,
                        bad_value=error)
        else:
            if self.peak_detector.isUnstable():
                errorstring=("LimbController: Maximum error for the desired point"+ 
                        "has increased for %d seconds.  System potentially unstable." %
                        self.peak_detector.getResolveTime() )
                logger.error(errorstring,
                        desired_pos=desired_pos,
                        measured_pos=measured_pos,
                        error=error,
                        bad_value=error)
                raise ValueError(errorstring)
            elif self.peak_detector.isLimitCycle():
                errorstring=("LimbController: Controller has not converged"+ 
                "over %d seconds.  System potentially in a limit cycle." %
                self.peak_detector.getResolveTime() )
                logger.error(errorstring,
                        desired_pos=desired_pos,
                        measured_pos=measured_pos,
                        error=error,
                        bad_value=error)
                raise ValueError(errorstring)
        
        self.integral_error_accumulator += self.ki * error * delta_time
        derivative_error = self.d_lowpass.update((error - self.prev_error) / delta_time)

        velocity_error = desired_vel - derivative_error

        self.prev_error = error
        self.prev_desired_pos = desired_pos
        
        actuator_command = self.kp * error + self.integral_error_accumulator + self.kd * derivative_error + self.kff*desired_vel + self.kfa*velocity_error
        actuator_command = self.boundActuatorCommand(actuator_command, measured_pos)
        
        return actuator_command