Difference between revisions of "Pf calb table py"

From DIDEAS Wiki
Jump to: navigation, search
m
m
 
(11 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
{{pf_top_nav}}
 
{{pf_top_nav}}
=new=
 
  
==parse robot source code==
 
This method parses the robot source.
 
*Build a data structure for all complex data types
 
*Look for special macros that will help map data types, global variable names, and variable ID for query
 
  
 +
=files to modify=
 +
*add eeprom address to eeprom_memmap.h
 +
**could be else where, but helps us to keep track of what is being used where
 +
*add macros to pyshared.c that list the global ram address, and or EEPROM address and virtual variable name
 +
*to global.c, declare the global     
 +
*to global.h, define the global typedef
 +
**latter two (global) files are optional, but help keep everything in one place
 +
 +
=example=
 +
==eeprom_memmap.h==
 
<pre>
 
<pre>
#define RAM_ADDRESS_MACRO(type, variable_name)  (&variable_name),((void*)sizeof(type))
+
#define PERSISTENT_DATA_C1_EEPROM_BASE_ADDRESS 0x1500
#define EEPROM_ADDRESS_MACRO(type, ee_address)  ((void*)ee_address),((void*)sizeof(type))
+
#define PERSISTENT_DATA_C2_EEPROM_BASE_ADDRESS 0x1580
#define RAM_EEPROM_ADDRESS_MACRO(type, variable_name, ee_address)  (&variable_name),((void*)ee_address),((void*)sizeof(type))
+
</pre>
  
 +
==pyshared.c==
 +
<pre>
 +
...
 +
const SHARED_OBJECT_T SHARED_OBJECT[] = {
 +
...
 +
  SHARED_RAM_OBJ_M(PERSISTENT_DATA_T, persistent_data_c1),                // use commas at EOL
 +
  SHARED_RAM_OBJ_M(PERSISTENT_DATA_T, persistent_data_c2),
 +
  SHARED_EE_OBJ_M (PERSISTENT_DATA_T, EE_persistent_data_c1, PERSISTENT_DATA_C1_EEPROM_BASE_ADDRESS),
 +
  SHARED_EE_OBJ_M (PERSISTENT_DATA_T, EE_persistent_data_c2, PERSISTENT_DATA_C2_EEPROM_BASE_ADDRESS),
 +
...
 +
} ;
 +
</pre>
 +
==global.h==
 +
<pre>
 +
typedef struct {
 +
  // preamble that should appear at the start of all shared objects - use the same field names
 +
  UINT32_T pytable_crc;        // this is the standard header, use CRC8 for now.
 +
  UINT16_T pytable_version;
 +
  UINT16_T pytable_length;
 +
  UINT32_T pytable_magic;      // "hash" for this typedef from the file pygen_shared_object_hash_codes.h
  
 +
  //////////////////
 +
  // use table data to follow.  only use 'primitive' C types
 +
  UINT32_T count;
 +
} PERSISTENT_DATA_T;
  
float robot_param_calb;
+
extern PERSISTENT_DATA_T persistent_data_c1;  
float sensors;
+
extern PERSISTENT_DATA_T persistent_data_c2;  
 +
</pre>
  
const void * SHARED_OBJECT_ADDRESSES[] = {
+
==global.c==
  RAM_EEPROM_ADDRESS_MACRO(SC_PARAM_T, robot_param_calb, EEPROM_SC_PARAM_ADDR),                         
+
<pre>
  RAM_ADDRESS_MACRO(SENSORS_PARAM_T, sensors),
+
PERSISTENT_DATA_T persistent_data_c1;
  EEPROM_ADDRESS_MACRO(MC_PARAM_T, EEPROM_MC_PARAM_ADDR),
+
PERSISTENT_DATA_T persistent_data_c2;  
  EEPROM_ADDRESS_MACRO(IMU_PARAM_T, EEPROM_IMU_PARAM_ADDR),
 
} ;
 
  
 +
void init_global(void) {
 +
...
 +
ZERO_OBJ(persistent_data_c1);
 +
ZERO_OBJ(persistent_data_c2);
 +
...
 +
}
 
</pre>
 
</pre>
  
Note: a table may only exist in RAM or EEPROM, or exist in both.
+
=how to load / save=
 +
A general purpose solution does not yet exist. However common_files/eeprom_table.c and the following are an example:
  
 +
<pre>
 +
ERRCODE_T persistent_load() {
 +
  ERRCODE_T ecode;
 +
  MEMORY_ADDRESS_T mem;
 +
  PERSISTENT_DATA_T local_stack_obj;
 +
  UINT16_T table_size = sizeof(  PERSISTENT_DATA_T);
  
==Create a table image==
+
  mem.type = MEMORY_TYPE_TO_USE_FOR_TABLE_STORAGE;
Need a python module that given a table type, and a set of keys and values will create a robot 'table' memory image.
+
  mem.address = PERSISTENT_DATA_C1_EEPROM_BASE_ADDRESS;
*the module should return a list of keys that were specified
 
*the module should return a list of unknown keys that were specified
 
example:
 
  create_table_image('SC_PARAM_T', calb_dict);
 
  
==get address of specified table type==
+
  // copy EEPROM table into local storage until it is validated
*Query the robot to look up the RAM or EEPROM address of the table by table ID.
+
  ecode = eeprom_table_read( (TABLE_HEADER_T *)&local_stack_obj, table_size, &mem, PERSISTENT_DATA_T_HASH);
  
==write a table to EEPROM on robot==
+
// PERSISTENT_DATA_T_HASH comes from pygen_shared_object_hash_codes.h and is 32 bits of the MD5 HASH of the typedef source code. 
*Given a table id and table image, write the table to the EEPROM
 
  
==read a table from RAM or EEPROM==
+
  if (ecode) return ecode; // invalid table
  
==save table to text file==
+
  // if there were no errors and thus the table is valid, then copy into the walking_param state structure
 +
  ecode = memcpy((UINT8_T *)&persistent_data_c1, (UINT8_T *)&local_stack_obj, table_size);
  
==parse text file, build key:value list==
+
   return ecode;
The file will contain comments and key value pairs separated by a wide range of delimiters.  There are a few special key names that python will use to match the text file to elements of the source code:
+
}
 
 
<pre>
 
# comments about the source of the file
 
 
 
# key, value pairs that will be used to identify the table in the firmware source code
 
DATA_STRUCTURE_NAME = CALB_PARAM_T
 
GLOBAL_VARIABLE_NAME = robot_param_calb
 
FIRMWARE_VERSION_REQUIRED = 1.00, 2.00
 
 
 
# start of key value pairs that will be written to EEPROM, RAM
 
spring_stiffness_push = 1000   # newton meters per radian
 
spring_stiffness_pull = 500  # newton meters per radian
 
  
 
</pre>
 
</pre>
  
<pre>
+
=access=
typedef struct {
+
*Use "robo_config.py" to read / write these tables.
  float spring_stiffness_push;
+
*robo_config.py -p <serial port> -l
  float spring_stiffness_push;
+
*will list all the tables in the robot
  int16 joint_ankle_resolution;
 
} CALB_PARAM_T;
 
 
 
CALB_PARAM_T robot_param_calb;
 
  
  
=old=
+
=imu calibration table docs=
Calibration tables live in a file called calb_table.py.
+
TBC
  
The table is formatted as a python dictionary of dictionarys.  The first dictionary uses a key equal to the robot code name. Eg "S01", "WB2", etc.
 
  
The 2nd dictionary level is has two keys 'name' and 'value_list'.  Value list is a list of numbers that represent the calibration coefficients.  See the following example:
+
Example KVF with calibration data:
  
== example calibration table entry ==
 
 
<pre>
 
<pre>
calb_table_x201['S01'] = {'name' : 'DS_S01_2009_05_01',
+
[EE_imu_model_calibrationTable]
          'value_list' : [
 
  
                    9999.0, 9.9, -9.9,  # motor current offset sin params : offset, amplitude , phase
+
serial_number        = 33
                    9999.0, 9.9, 9.9,
 
                   
 
                    -421.59, -14.17,    # pyramid
 
                   
 
                    13000.0, -544, -2293,  # hall sensor max plantar,zero, 8deg dors
 
  
                    -0.04, 0.03,  # hall segment boundary (seg a to b, seg b to c)
+
accXgain            =  4.839633e-003
 +
accYgain            =  4.630313e-003
 +
accZgain            =  4.735434e-003
  
                    -7912.4000, -2384.5000, -282.9800, -2.8549,  # hall fit poly seg a
+
accXoffset          = -1.684186e+002
                    -26904.0000, -287.6500, -93.0930,  0.0227,  # seg b
+
accYoffset          = 5.055467e+002
                    -1324.7000, 818.5000, -189.2800,  0.7572,    # seg c
+
accZoffset          = -5.931334e+002
                   
+
 
                    623.0,        # k3 nM per radian
+
gyroXgain            =  7.628163e-004
                    462.0, 1407,    # series spring
+
gyroYgain            =  7.753409e-004
                    ] } ;
+
gyroZgain            = 6.809857e-004
</pre>
 
  
 +
gyroXoffset          = -1.153796e+003
 +
gyroYoffset          = -1.272726e+003
 +
gyroZoffset          = -4.543681e+002
  
==names of coefficients in the value list==
+
USMacc4acc[9]        = 9.999594e-001 -1.322563e-002  5.033391e-003  8.940409e-003  9.986601e-001  4.106794e-002  1.119896e-003 -5.003061e-002  9.991437e-001
<pre>
 
v_x201_keys=[
 
    'phase_a_offset, phase_a_amplitude, phase_a_phase',
 
    'phase_b_offset, phase_b_amplitude, phase_b_phase',
 
    'pyramid_m','pyramid_b',
 
   
 
    'hall_seg_ab_boundary',    'hall_seg_bc_boundary',
 
  
    'hall_max_plantar', 'hall_zero', 'hall_max_dors',
+
USMacc4gyro[9]      =  0 0 0  0 0 0  0 0 0
  
    'hall_poly_fit_seg_a0', 'hall_poly_fit_seg_a1', 'hall_poly_fit_seg_a2', 'hall_poly_fit_seg_a3',
+
USMgyro4acc[9]      = 0.000000e+000 0.000000e+000 0.000000e+000 0.000000e+000 0.000000e+000 0.000000e+000 0.000000e+000 0.000000e+000 0.000000e+000
    'hall_poly_fit_seg_b0', 'hall_poly_fit_seg_b1', 'hall_poly_fit_seg_b2', 'hall_poly_fit_seg_b3',
 
    'hall_poly_fit_seg_c0', 'hall_poly_fit_seg_c1', 'hall_poly_fit_seg_c2', 'hall_poly_fit_seg_c3',
 
  
    'k3_const_nmpr',
+
USMgyro4gyro[9]     =  9.993670e-001 -2.109546e-002  2.492205e-002 -1.123791e-002  9.991589e-001  1.420475e-002  3.375426e-002  3.516471e-002  9.995885e-001
    'k2_pull_nmpr', 'k2_push_nmpr'
 
    ];
 
 
</pre>
 
</pre>

Latest revision as of 04:09, 17 December 2010

PF Users Navigation:

Edit


files to modify

  • add eeprom address to eeprom_memmap.h
    • could be else where, but helps us to keep track of what is being used where
  • add macros to pyshared.c that list the global ram address, and or EEPROM address and virtual variable name
  • to global.c, declare the global
  • to global.h, define the global typedef
    • latter two (global) files are optional, but help keep everything in one place

example

eeprom_memmap.h

#define PERSISTENT_DATA_C1_EEPROM_BASE_ADDRESS 0x1500
#define PERSISTENT_DATA_C2_EEPROM_BASE_ADDRESS 0x1580

pyshared.c

...
const SHARED_OBJECT_T SHARED_OBJECT[] = {
...
  SHARED_RAM_OBJ_M(PERSISTENT_DATA_T, persistent_data_c1),                 // use commas at EOL
  SHARED_RAM_OBJ_M(PERSISTENT_DATA_T, persistent_data_c2),
  SHARED_EE_OBJ_M (PERSISTENT_DATA_T, EE_persistent_data_c1, PERSISTENT_DATA_C1_EEPROM_BASE_ADDRESS),
  SHARED_EE_OBJ_M (PERSISTENT_DATA_T, EE_persistent_data_c2, PERSISTENT_DATA_C2_EEPROM_BASE_ADDRESS),
...
} ;

global.h

typedef struct {
   // preamble that should appear at the start of all shared objects - use the same field names
  UINT32_T pytable_crc;         // this is the standard header, use CRC8 for now.
  UINT16_T pytable_version;
  UINT16_T pytable_length;
  UINT32_T pytable_magic;       // "hash" for this typedef from the file pygen_shared_object_hash_codes.h

  //////////////////
  // use table data to follow.  only use 'primitive' C types
  UINT32_T count;
} PERSISTENT_DATA_T;

extern PERSISTENT_DATA_T persistent_data_c1; 
extern PERSISTENT_DATA_T persistent_data_c2; 

global.c

PERSISTENT_DATA_T persistent_data_c1; 
PERSISTENT_DATA_T persistent_data_c2; 

void init_global(void) {
 ...
 ZERO_OBJ(persistent_data_c1);
 ZERO_OBJ(persistent_data_c2);
 ...
}

how to load / save

A general purpose solution does not yet exist. However common_files/eeprom_table.c and the following are an example:

ERRCODE_T persistent_load() {
  ERRCODE_T ecode;
  MEMORY_ADDRESS_T mem;
  PERSISTENT_DATA_T local_stack_obj;
  UINT16_T table_size = sizeof(  PERSISTENT_DATA_T);

  mem.type = MEMORY_TYPE_TO_USE_FOR_TABLE_STORAGE;
  mem.address = PERSISTENT_DATA_C1_EEPROM_BASE_ADDRESS;

  // copy EEPROM table into local storage until it is validated
  ecode = eeprom_table_read( (TABLE_HEADER_T *)&local_stack_obj, table_size, &mem, PERSISTENT_DATA_T_HASH);

// PERSISTENT_DATA_T_HASH comes from pygen_shared_object_hash_codes.h and is 32 bits of the MD5 HASH of the typedef source code.  

  if (ecode) return ecode; // invalid table

  // if there were no errors and thus the table is valid, then copy into the walking_param state structure
  ecode = memcpy((UINT8_T *)&persistent_data_c1, (UINT8_T *)&local_stack_obj, table_size);

  return ecode;
}

access

  • Use "robo_config.py" to read / write these tables.
  • robo_config.py -p <serial port> -l
  • will list all the tables in the robot


imu calibration table docs

TBC


Example KVF with calibration data:

[EE_imu_model_calibrationTable]

serial_number        = 33

accXgain             =  4.839633e-003
accYgain             =  4.630313e-003
accZgain             =  4.735434e-003

accXoffset           = -1.684186e+002
accYoffset           =  5.055467e+002
accZoffset           = -5.931334e+002

gyroXgain            =  7.628163e-004
gyroYgain            =  7.753409e-004
gyroZgain            =  6.809857e-004

gyroXoffset          = -1.153796e+003
gyroYoffset          = -1.272726e+003
gyroZoffset          = -4.543681e+002

USMacc4acc[9]        =  9.999594e-001 -1.322563e-002  5.033391e-003  8.940409e-003  9.986601e-001  4.106794e-002  1.119896e-003 -5.003061e-002  9.991437e-001 

USMacc4gyro[9]       =  0 0 0   0 0 0   0 0 0 

USMgyro4acc[9]       =  0.000000e+000  0.000000e+000  0.000000e+000  0.000000e+000  0.000000e+000  0.000000e+000  0.000000e+000  0.000000e+000  0.000000e+000 

USMgyro4gyro[9]      =  9.993670e-001 -2.109546e-002  2.492205e-002 -1.123791e-002  9.991589e-001  1.420475e-002  3.375426e-002  3.516471e-002  9.995885e-001