Poppy and safety

I would like to make an experiment with a part of the Poppy torso.
For this experiment, the robot will have to perform different actions autonomously, one at a time.
Those actions will be executed as joint commands (sent via a primitive), and will be decided without any knowledge about poppy’s kinematic or its environment.
In order to protect both the robot and its environment, I’m looking for the best way (happy medium between safety and minimum modification of the actions executed) to protect the robot.
The robot should be able to perform its actions without any human intervention.

I thought I could use the present_load attribut of the motor and simply freeze the motion of a joint when it gets higher than a fixed threshold. Is this a good start ? Or should I also fix a torque limit for all motors ?

Both solutions will produce the same result, with a preference for the first one because it is directly in the motor firmware.

The difficulty is to estimate the maximum load you will need which depend of the speed of the motor. You can try to make an “intelligent” protection which fix the load threeshold with the present speed of each motor.

The difficulty is to estimate the maximum load you will need which depend of the speed of the motor. You can try to make an “intelligent” protection which fix the load threeshold with the present speed of each motor.

You’re talking about the actual speed of the motor, or its maximum speed? Do you think I should also limit directly the maximum speed of the joints? Because if it goes at full speed and hit a desk or itself, won’t it break itself? Would it work at high velocity?

To be clearer, I want a module that will both react if the robot is forcing on an immobile object (or itself) for too much time to prevent overheating (could be reactive, will happen at nearly zero speed) and prevent the robot from breaking itself instantly by colliding too strongly with an immobile object (that’s why I thought I could set a maximum torque or speed to limit the robot too).

I’m talking to the speed of the motor. A fast moment in the air will require a high torque (an you will see a high present_load).
Btw, I posted an issue related to what you are looking for on pypot, to write an efficient software protection ; it is something which is lacking in the platform.

For a steady motion, if the robot is forcing during a few seconds on an immobile object, to which value do you estimate the maximum load I should set?

I don’t know if some advance has been made on this topic.
I developed a module for my experiment, which was only here to signal if one of the used joints is overloaded.
Here it is:

class SafetyModule(LoopPrimitive):
“”“Module checking safety constraints for the robot.”“”

def __init__(self, robot, freq, safety_constraints, max_t):
    LoopPrimitive.__init__(self, robot, freq)
    self.safety_constraints = safety_constraints
    self.over_heating = {}        
    self.reset()
    self.safe = True
    self.max_t = max_t
def reset(self):
    """Setup safety measures."""
    self.safe = True
    self.t_unsafe = ptime.time()
    for m in self.safety_constraints.keys():
        motor = getattr(self.robot, m)
        # Constraining maximum speed to prevent dangerous collision
        motor.moving_speed = self.safety_constraints[m]['max_speed']
        self.over_heating[m] = [0, False, False]  # Last over load time and if overloaded at last frame
def update(self):
    """Override the update method to apply safety measures."""
    self.apply_safety_commands()
def apply_safety_commands(self):
    """Apply safety measures: freeze joint when forcing for too much time."""
    for m in self.safety_constraints.keys():
        motor = getattr(self.robot, m)
        motor.moving_speed = self.safety_constraints[m]['max_speed']
        # Check load to prevent overheating of motor
        if self.over_heating[m][2]:  # Joint unsafe
            self.safe = False
            if (ptime.time() - self.t_unsafe) > self.max_t:
                motor.compliant = True
        elif math.fabs(motor.present_load) > self.safety_constraints[m]['max_load']:  # Joint overloaded
            if not self.over_heating[m][1]:
                self.over_heating[m][0] = ptime.time()
                self.over_heating[m][1] = True
            elif self.over_heating[m][1] and (ptime.time() - self.over_heating[m][0]) >  \
                    self.safety_constraints[m]['max_time']:
                self.over_heating[m][2] = True 
                self.t_unsafe = ptime.time()                   
        else:
            self.over_heating[m][1] = False

The values of speed limit, max load and of time overload are chosen joint by joint.
The max_t variable was just here to ensure that if any joint is overloaded for too much time, it will be set compliant and not force any longer.
In case the other modules controlling the robot don’t take the safe attribut into account.

In my experiment, I reset the safety module after any motion attempt.