# Wiki

Clone wiki# PyiB2c / Creating a behavior from scratch

# Creating a behavior from scratch

The behavior module is the basic module inside an iB2c network. It inherits from the base class `BehaviorTemplateClass`

and it can be created using the `EmptyBehaviorClass`

. When the module is called:

- The activation variable is calculated.
- Function
`self.calc_activity()`

is called. - Function
`self.calc_transfer()`

is called. - Function
`self.calc_rating()`

is called. - Variables
`self.output`

,`self.activity`

,`self.rating`

are returned.

## Input and Output information

In order to make the network know what kind of variables the behavior is expecting, and to make the network architecture know its output, the variables "input_info" and "output_info" must be defined inside the module. Both variables are dictionaries with the following keys:

- Size: -
*np.array*- sizes of each variables. - Type: -
*np.array*- short description of the variable type. To be freely defined by the user. - Description: -
*list*- description of each variable.

Example (see `HeadToPointBehaviorClass`

):

self.input_info = {'Size': np.array([np.zeros([1]), PoseV1Class(), np.zeros([2]), np.zeros([1])]), 'Type': np.array(['Time', 'Pose', 'Position2D', 'CoefAlpha']), 'Description': ['Simulation time [s]', 'Pose of the agent', '2D position of the target', 'Coefficient [0, 1] of velocity reduction']} self.output_info = {'Size': np.array([np.zeros([2])]), 'Type': 'Velocity2D', 'Description': '2D Velocity Command'}

This behavior is expecting 4 variables as inputs. The first input has dimension 1, its a time variable, and it is the simulation time in seconds. The second variable variable is a `PoseV1Class`

class, which is a pose type: the pose of the agent.

## Transfer function

Given an array of variables as inputs, this function calculates the output variables. It must be defined inside `calc_transfer`

method.

Example (see `HeadToPointBehaviorClass`

):

def calc_transfer(self, inputs): # Get input variables t = inputs[0] pose = inputs[1] target_pos = inputs[2] alpha_v = inputs[3] # ------------------------------------------------------- # Calc output vector with the transfer function # ------------------------------------------------------- i_target = 0 r_a_t = [target_pos[i_target][0] - pose.X[0], target_pos[i_target][1] - pose.X[1]] psi_a_t = np.arctan2(r_a_t[0], r_a_t[1]) delta_psi = psi_a_t - pose.psi # Correction [-pi,+pi] self._delta_psi = np.arctan2(np.sin(delta_psi), np.cos(delta_psi)) # Calculation of the angular velocity w = self.P*self._delta_psi/np.pi delta_t = t - self._t self._t = t psi_c = pose.psi + delta_t * w # ------------------------------------------------------- v_c = np.zeros(2) v_c[0] = np.sin(psi_c) v_c[1] = np.cos(psi_c) v_c = alpha_v*self.v_n * v_c self.output[0] = v_c

## Activity and rating function

The activity and the rating variables are calculated.

Example (see `HeadToPointBehaviorClass`

):

def calc_activity(self): self.activity = self.activation def calc_rating(self): self.rating = 1 - np.abs(self._delta_psi) / np.pi

## Final step

Save the module inside the Behaviors folder and add the information to the behaviors_dictionary.xml file, for instance:

<?xml version="1.0"?> <data> <behavior name="HeadToPointBehavior"> <class_name>HeadToPointBehaviorClass</class_name> <module_name>HeadToPointBehaviorClasses</module_name> <activated>1</activated> </behavior> </data>

If flag <activated> is set to 0, it won't be considered.

Updated