stage.h
Go to the documentation of this file.00001 #ifndef STG_H 00002 #define STG_H 00003 /* 00004 * Stage : a multi-robot simulator. 00005 * 00006 * Copyright (C) 2001-2004 Richard Vaughan, Andrew Howard and Brian 00007 * Gerkey for the Player/Stage Project 00008 * http://playerstage.sourceforge.net 00009 * 00010 * This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. 00014 * 00015 * This program is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 * GNU General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU General Public License 00021 * along with this program; if not, write to the Free Software 00022 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00023 * 00024 */ 00025 00026 /* File: stage.h 00027 * Desc: External header file for the Stage library 00028 * Authors: Richard Vaughan vaughan@sfu.ca 00029 * Andrew Howard ahowards@usc.edu 00030 * Brian Gerkey gerkey@stanford.edu 00031 * Date: 1 June 2003 00032 * CVS: $Id: stage.h,v 1.158 2005/08/11 19:56:54 rtv Exp $ 00033 */ 00034 00035 00043 #include <stdlib.h> 00044 #include <stdio.h> 00045 #include <sys/socket.h> 00046 #include <netdb.h> 00047 #include <string.h> 00048 #include <unistd.h> 00049 #include <stdint.h> // for portable int types eg. uint32_t 00050 #include <sys/types.h> 00051 #include <sys/time.h> 00052 #include <assert.h> 00053 #include <pthread.h> 00054 #include <semaphore.h> 00055 00056 #include <glib.h> // we use GLib's data structures extensively 00057 #include <rtk.h> // and graphics stuff pulled from Andrew Howard's RTK2 library 00058 00059 #ifdef __cplusplus 00060 extern "C" { 00061 #endif 00062 00063 #include "config.h" 00064 #include "replace.h" 00065 00104 // TODO - fix this up 00105 #define FiducialNone 0 00106 00107 00108 // Basic self-describing measurement types. All packets with real 00109 // measurements are specified in these terms so changing types here 00110 // should work throughout the code If you change these, be sure to 00111 // change the byte-ordering macros below accordingly. 00112 00114 typedef int stg_id_t; 00115 00117 typedef double stg_meters_t; 00118 00120 typedef double stg_radians_t; 00121 00123 typedef unsigned long stg_msec_t; 00124 00126 typedef double stg_kg_t; // Kilograms (mass) 00127 00129 typedef double stg_joules_t; 00130 00132 typedef double stg_watts_t; 00133 00135 typedef int stg_bool_t; 00136 00137 //typedef double stg_friction_t; 00138 00140 typedef uint32_t stg_color_t; 00141 00144 typedef int stg_obstacle_return_t; 00145 00148 typedef int stg_blob_return_t; 00149 00151 typedef int stg_fiducial_return_t; 00152 00153 typedef int stg_ranger_return_t; 00154 00155 typedef enum { STG_GRIP_NO = 0, STG_GRIP_YES } stg_gripper_return_t; 00156 00159 typedef struct 00160 { 00161 stg_meters_t x, y; 00162 } stg_size_t; 00163 00167 typedef struct 00168 { 00169 stg_meters_t x, y, a; 00170 } stg_pose_t; 00171 00174 typedef stg_pose_t stg_velocity_t; 00175 00179 typedef struct 00180 { 00181 stg_pose_t pose; 00182 stg_size_t size; 00183 } stg_geom_t; 00184 00186 typedef struct 00187 { 00188 double min; //< smallest value in range 00189 double max; //< largest value in range 00190 } stg_bounds_t; 00191 00193 typedef struct 00194 { 00195 stg_bounds_t range; //< min and max range of sensor 00196 stg_radians_t angle; //< width of viewing angle of sensor 00197 } stg_fov_t; 00198 00199 00200 // PRETTY PRINTING ------------------------------------------------- 00201 00208 void stg_print_geom( stg_geom_t* geom ); 00209 00211 void stg_err( const char* err ); 00212 00215 // ENERGY -------------------------------------------------------------- 00216 00218 typedef struct 00219 { 00221 stg_joules_t stored; 00222 00224 stg_joules_t capacity; 00225 00227 stg_joules_t input_joules; 00228 00230 stg_joules_t output_joules; 00231 00233 stg_watts_t input_watts; 00234 00236 stg_watts_t output_watts; 00237 00239 stg_bool_t charging; 00240 00242 stg_meters_t range; 00243 } stg_energy_data_t; 00244 00246 typedef struct 00247 { 00249 stg_joules_t capacity; 00250 00252 stg_watts_t give; 00253 00256 stg_watts_t take; 00257 00259 stg_meters_t probe_range; 00260 } stg_energy_config_t; 00261 00262 // there is currently no energy command packet 00263 00264 // BLINKENLIGHT ------------------------------------------------------- 00265 00266 //typedef struct 00267 //{ 00268 //int enable; 00269 //stg_msec_t period; 00270 //} stg_blinkenlight_t; 00271 00272 // GRIPPER ------------------------------------------------------------ 00273 00274 // Possible Gripper return values 00275 //typedef enum 00276 //{ 00277 // GripperDisabled = 0, 00278 // GripperEnabled 00279 //} stg_gripper_return_t; 00280 00281 // GUIFEATURES ------------------------------------------------------- 00282 00283 // Movement masks for figures 00284 #define STG_MOVE_TRANS (1 << 0) 00285 #define STG_MOVE_ROT (1 << 1) 00286 #define STG_MOVE_SCALE (1 << 2) 00287 00288 typedef int stg_movemask_t; 00289 00290 /* typedef struct */ 00291 /* { */ 00292 /* uint8_t show_data; */ 00293 /* uint8_t show_cfg; */ 00294 /* uint8_t show_cmd; */ 00295 00296 /* uint8_t nose; */ 00297 /* uint8_t grid; */ 00298 /* //uint8_t boundary; */ 00299 /* uint8_t outline; */ 00300 /* stg_movemask_t movemask; */ 00301 /* } stg_guifeatures_t; */ 00302 00303 00304 // LASER ------------------------------------------------------------ 00305 00307 typedef enum 00308 { 00309 LaserTransparent, 00310 LaserVisible, 00311 LaserBright 00312 } stg_laser_return_t; 00313 00314 00317 stg_msec_t stg_timenow( void ); 00318 00324 int stg_init( int argc, char** argv ); 00325 00326 00328 int stg_quit_test( void ); 00329 00332 void stg_quit_request( void ); 00333 00334 00335 // UTILITY STUFF ---------------------------------------------------- 00336 00345 const char* stg_version_string( void ); 00346 00351 stg_color_t stg_lookup_color(const char *name); 00352 00355 void stg_pose_sum( stg_pose_t* result, stg_pose_t* p1, stg_pose_t* p2 ); 00356 00357 // POINTS --------------------------------------------------------- 00358 00365 typedef struct 00366 { 00367 stg_meters_t x, y; 00368 } stg_point_t; 00369 00372 stg_point_t* stg_points_create( size_t count ); 00373 00375 void stg_points_destroy( stg_point_t* pts ); 00376 00380 // POLYGONS --------------------------------------------------------- 00381 00389 typedef struct 00390 { 00392 GArray* points; 00393 00395 stg_bool_t filled; 00396 00398 stg_color_t color; 00399 } stg_polygon_t; 00400 00401 00403 stg_polygon_t* stg_polygons_create( int count ); 00404 00406 void stg_polygons_destroy( stg_polygon_t* p, size_t count ); 00407 00410 stg_polygon_t* stg_unit_polygon_create( void ); 00411 00415 void stg_polygon_set_points( stg_polygon_t* poly, stg_point_t* pts, size_t count ); 00418 void stg_polygon_append_points( stg_polygon_t* poly, stg_point_t* pts, size_t count ); 00419 00422 void stg_polygons_normalize( stg_polygon_t* polys, int num, 00423 double width, double height ); 00424 00426 void stg_polygon_print( stg_polygon_t* poly ); 00427 00429 void stg_polygons_print( stg_polygon_t* polys, unsigned int count ); 00430 00435 stg_polygon_t* stg_polygons_from_image_file( const char* filename, 00436 size_t* poly_count ); 00437 00440 // end util documentation group 00444 // end property typedefs ------------------------------------------------- 00445 00446 00447 // forward declare struct types from player_internal.h 00448 struct _stg_model; 00449 struct _stg_matrix; 00450 struct _gui_window; 00451 struct _stg_world; 00452 00455 typedef struct _stg_world stg_world_t; 00456 00457 00463 typedef struct _stg_model stg_model_t; // defined in stage_internal.h 00464 00465 // MODEL -------------------------------------------------------- 00466 00467 // group the docs of all the model types 00473 #define STG_PROPNAME_MAX 128 00474 00475 00476 00477 00478 00483 typedef int (*stg_property_callback_t)(stg_model_t* mod, char* propname, void* data, size_t len, void* userdata ); 00484 00485 00492 typedef int(*stg_model_initializer_t)(stg_model_t*); 00493 00494 00497 typedef struct 00498 { 00499 stg_property_callback_t callback; 00500 void* arg; 00501 } stg_cbarg_t; 00502 00504 stg_model_t* stg_model_create( stg_world_t* world, 00505 stg_model_t* parent, 00506 stg_id_t id, 00507 char* token, 00508 stg_model_initializer_t initializer ); 00509 00511 void stg_model_destroy( stg_model_t* mod ); 00512 00514 void stg_model_get_global_pose( stg_model_t* mod, stg_pose_t* pose ); 00515 00517 //void stg_model_get_global_velocity( stg_model_t* mod, stg_velocity_t* gvel ); 00518 00519 /* set the velocity of a model in the global coordinate system */ 00520 //void stg_model_set_global_velocity( stg_model_t* mod, stg_velocity_t* gvel ); 00521 00523 void stg_model_subscribe( stg_model_t* mod ); 00524 00526 void stg_model_unsubscribe( stg_model_t* mod ); 00527 00529 void stg_model_load( stg_model_t* mod ); 00530 00532 void stg_model_save( stg_model_t* mod ); 00533 00535 //const char* stg_model_type_string( stg_model_type_t type ); 00536 00537 // SET properties - use these to set props, don't set them directly 00538 00540 int stg_model_set_global_pose( stg_model_t* mod, stg_pose_t* gpose ); 00541 00543 int stg_model_set_velocity( stg_model_t* mod, stg_velocity_t* vel ); 00544 00545 // TODO? 00548 //void stg_model_lock( stg_model_t* mod ); 00549 00551 //void stg_model_unlock( stg_model_t* mod ); 00552 00554 int stg_model_set_parent( stg_model_t* mod, stg_model_t* newparent); 00555 00556 void stg_model_get_geom( stg_model_t* mod, stg_geom_t* dest ); 00557 void stg_model_get_velocity( stg_model_t* mod, stg_velocity_t* dest ); 00558 00559 void stg_model_set_property( stg_model_t* mod, 00560 const char* prop, 00561 void* data, 00562 size_t len ); 00563 00566 void* stg_model_get_property( stg_model_t* mod, 00567 const char* prop, 00568 size_t* len ); 00569 00572 void* stg_model_get_property_fixed( stg_model_t* mod, 00573 const char* name, 00574 size_t size ); 00575 00576 void stg_model_property_refresh( stg_model_t* mod, const char* propname ); 00577 00578 00581 stg_polygon_t* stg_model_get_polygons( stg_model_t* mod, size_t* poly_count ); 00582 void stg_model_set_polygons( stg_model_t* mod, 00583 stg_polygon_t* polys, 00584 size_t poly_count ); 00585 00586 // get a copy of the property data - caller must free it 00587 //int stg_model_copy_property_data( stg_model_t* mod, const char* prop, 00588 // void** data ); 00589 00590 int stg_model_add_property_callback( stg_model_t* mod, const char* prop, 00591 stg_property_callback_t, void* user ); 00592 00593 int stg_model_remove_property_callback( stg_model_t* mod, const char* prop, 00594 stg_property_callback_t ); 00595 00596 int stg_model_remove_property_callbacks( stg_model_t* mod, const char* prop ); 00597 00600 void stg_model_print( stg_model_t* mod ); 00601 00604 int stg_model_is_antecedent( stg_model_t* mod, stg_model_t* testmod ); 00605 00608 int stg_model_is_descendent( stg_model_t* mod, stg_model_t* testmod ); 00609 00613 int stg_model_is_related( stg_model_t* mod1, stg_model_t* mod2 ); 00614 00616 stg_model_t* stg_model_root( stg_model_t* mod ); 00617 00619 GPtrArray* stg_model_array_from_tree( stg_model_t* root ); 00620 00622 int stg_model_startup( stg_model_t* mod ); 00623 00625 int stg_model_shutdown( stg_model_t* mod ); 00626 00629 int stg_model_update( stg_model_t* model ); 00630 00634 void stg_model_global_to_local( stg_model_t* mod, stg_pose_t* pose ); 00635 00639 void stg_model_local_to_global( stg_model_t* mod, stg_pose_t* pose ); 00640 00641 00645 void stg_model_add_property_toggles( stg_model_t* mod, 00646 const char* propname, 00647 stg_property_callback_t callback_on, 00648 void* arg_on, 00649 stg_property_callback_t callback_off, 00650 void* arg_off, 00651 const char* label, 00652 int enabled ); 00653 00654 int stg_model_fig_clear_cb( stg_model_t* mod, void* data, size_t len, 00655 void* userp ); 00656 // end model doc group 00658 00659 // WORLD -------------------------------------------------------- 00660 00671 stg_world_t* stg_world_create( stg_id_t id, 00672 const char* token, 00673 int sim_interval, 00674 int real_interval, 00675 double ppm, 00676 double width, 00677 double height ); 00678 00682 stg_world_t* stg_world_create_from_file( const char* worldfile_path ); 00683 00686 void stg_world_destroy( stg_world_t* world ); 00687 00690 void stg_world_stop( stg_world_t* world ); 00691 00694 void stg_world_start( stg_world_t* world ); 00695 00702 int stg_world_update( stg_world_t* world, int sleepflag ); 00703 00705 void stg_world_load( stg_world_t* mod ); 00706 00708 void stg_world_save( stg_world_t* mod ); 00709 00712 void stg_world_print( stg_world_t* world ); 00713 00716 void stg_world_set_interval_real( stg_world_t* world, unsigned int val ); 00717 00721 void stg_world_set_interval_sim( stg_world_t* world, unsigned int val ); 00722 00725 stg_model_t* stg_world_get_model( stg_world_t* world, stg_id_t mid ); 00726 00728 stg_model_t* stg_world_model_name_lookup( stg_world_t* world, const char* name ); 00729 00730 00731 00735 void stg_world_add_property_callback( stg_world_t* world, 00736 char* propname, 00737 stg_property_callback_t callback, void* 00738 userdata ); 00739 00744 void stg_world_remove_property_callback( stg_world_t* world, 00745 char* propname, 00746 stg_property_callback_t callback ); 00747 00751 // BLOBFINDER MODEL -------------------------------------------------------- 00752 00757 #define STG_BLOB_CHANNELS_MAX 16 00758 00761 typedef struct 00762 { 00763 int channel_count; // 0 to STG_BLOBFINDER_CHANNELS_MAX 00764 stg_color_t channels[STG_BLOB_CHANNELS_MAX]; 00765 int scan_width; 00766 int scan_height; 00767 stg_meters_t range_max; 00768 stg_radians_t pan, tilt, zoom; 00769 } stg_blobfinder_config_t; 00770 00773 typedef struct 00774 { 00775 int channel; 00776 stg_color_t color; 00777 int xpos, ypos; // all values are in pixels 00778 //int width, height; 00779 int left, top, right, bottom; 00780 int area; 00781 stg_meters_t range; 00782 } stg_blobfinder_blob_t; 00783 00786 stg_model_t* stg_blobfinder_create( stg_world_t* world, 00787 stg_model_t* parent, 00788 stg_id_t id, 00789 char* token ); 00792 // LASER MODEL -------------------------------------------------------- 00793 00800 typedef struct 00801 { 00802 uint32_t range; 00803 char reflectance; 00804 } stg_laser_sample_t; 00805 00808 typedef struct 00809 { 00810 stg_radians_t fov; 00811 stg_meters_t range_max; 00812 stg_meters_t range_min; 00813 00816 int samples; 00817 } stg_laser_config_t; 00818 00821 void stg_print_laser_config( stg_laser_config_t* slc ); 00822 00825 stg_model_t* stg_laser_create( stg_world_t* world, 00826 stg_model_t* parent, 00827 stg_id_t id, 00828 char* token ); 00829 00832 size_t stg_model_get_data_laser( stg_model_t* mod, 00833 stg_laser_sample_t* data, 00834 size_t max_samples ); 00837 // GRIPPER MODEL -------------------------------------------------------- 00838 00843 typedef enum { 00844 STG_GRIPPER_PADDLE_OPEN = 0, // default state 00845 STG_GRIPPER_PADDLE_CLOSED, 00846 STG_GRIPPER_PADDLE_OPENING, 00847 STG_GRIPPER_PADDLE_CLOSING, 00848 } stg_gripper_paddle_state_t; 00849 00850 typedef enum { 00851 STG_GRIPPER_LIFT_DOWN = 0, // default state 00852 STG_GRIPPER_LIFT_UP, 00853 STG_GRIPPER_LIFT_UPPING, // verbed these to match the paddle state 00854 STG_GRIPPER_LIFT_DOWNING, 00855 } stg_gripper_lift_state_t; 00856 00857 typedef enum { 00858 STG_GRIPPER_CMD_NOP = 0, // default state 00859 STG_GRIPPER_CMD_OPEN, 00860 STG_GRIPPER_CMD_CLOSE, 00861 STG_GRIPPER_CMD_UP, 00862 STG_GRIPPER_CMD_DOWN 00863 } stg_gripper_cmd_type_t; 00864 00867 typedef struct 00868 { 00869 stg_size_t paddle_size; 00870 00871 stg_gripper_paddle_state_t paddles; 00872 stg_gripper_lift_state_t lift; 00873 00874 double paddle_position; 00875 double lift_position; 00876 00877 stg_meters_t inner_break_beam_inset; 00878 stg_meters_t outer_break_beam_inset; 00879 stg_bool_t paddles_stalled; // true iff some solid object stopped 00880 // the paddles closing or opening 00881 00882 GSList *grip_stack; 00883 int grip_stack_size; 00884 00885 } stg_gripper_config_t; 00886 00889 typedef struct 00890 { 00891 stg_gripper_cmd_type_t cmd; 00892 int arg; 00893 } stg_gripper_cmd_t; 00894 00895 00898 typedef struct 00899 { 00900 stg_gripper_paddle_state_t paddles; 00901 stg_gripper_lift_state_t lift; 00902 00903 double paddle_position; 00904 double lift_position; 00905 00906 stg_bool_t inner_break_beam; 00907 stg_bool_t outer_break_beam; 00908 00909 stg_bool_t left_paddle_contact[3]; 00910 stg_bool_t right_paddle_contact[3]; 00911 00912 stg_bool_t paddles_stalled; // true iff some solid object stopped 00913 // the paddles closing or opening 00914 00915 int stack_count; 00916 00917 } stg_gripper_data_t; 00918 00919 00922 void stg_print_gripper_config( stg_gripper_config_t* slc ); 00923 00926 stg_model_t* stg_gripper_create( stg_world_t* world, 00927 stg_model_t* parent, 00928 stg_id_t id, 00929 char* token ); 00932 // FIDUCIAL MODEL -------------------------------------------------------- 00933 00940 typedef struct 00941 { 00942 stg_meters_t max_range_anon; 00943 stg_meters_t max_range_id; 00944 stg_meters_t min_range; 00945 stg_radians_t fov; // field of view 00946 stg_radians_t heading; // center of field of view 00947 00948 } stg_fiducial_config_t; 00949 00952 typedef struct 00953 { 00954 stg_meters_t range; // range to the target 00955 stg_radians_t bearing; // bearing to the target 00956 stg_pose_t geom; // size and relative angle of the target 00957 int id; // the identifier of the target, or -1 if none can be detected. 00958 00959 } stg_fiducial_t; 00960 00963 stg_model_t* stg_fiducial_create( stg_world_t* world, 00964 stg_model_t* parent, 00965 stg_id_t id, 00966 char* token ); 00969 // RANGER MODEL -------------------------------------------------------- 00970 00976 typedef struct 00977 { 00978 stg_pose_t pose; 00979 stg_size_t size; 00980 stg_bounds_t bounds_range; 00981 stg_radians_t fov; 00982 } stg_ranger_config_t; 00983 00984 typedef struct 00985 { 00986 stg_meters_t range; 00987 //double error; // TODO 00988 } stg_ranger_sample_t; 00989 00992 stg_model_t* stg_ranger_create( stg_world_t* world, 00993 stg_model_t* parent, 00994 stg_id_t id, 00995 char* token ); 00998 // POSITION MODEL -------------------------------------------------------- 00999 01004 //#define STG_MM_POSITION_RESETODOM 77 01005 01006 typedef enum 01007 { STG_POSITION_CONTROL_VELOCITY, STG_POSITION_CONTROL_POSITION } 01008 stg_position_control_mode_t; 01009 01010 #define STG_POSITION_CONTROL_DEFAULT STG_POSITION_CONTROL_VELOCITY 01011 01012 typedef enum 01013 { STG_POSITION_LOCALIZATION_GPS, STG_POSITION_LOCALIZATION_ODOM } 01014 stg_position_localization_mode_t; 01015 01016 #define STG_POSITION_LOCALIZATION_DEFAULT STG_POSITION_LOCALIZATION_GPS 01017 01019 typedef enum 01020 { STG_POSITION_DRIVE_DIFFERENTIAL, STG_POSITION_DRIVE_OMNI } 01021 stg_position_drive_mode_t; 01022 01023 #define STG_POSITION_DRIVE_DEFAULT STG_POSITION_DRIVE_DIFFERENTIAL 01024 01026 typedef struct 01027 { 01028 stg_meters_t x,y,a; 01029 stg_position_control_mode_t mode; 01030 } stg_position_cmd_t; 01031 01033 typedef struct 01034 { 01035 stg_pose_t pose; 01036 stg_pose_t pose_error; 01037 stg_pose_t origin; 01038 stg_velocity_t velocity; 01039 stg_velocity_t integration_error; 01040 stg_bool_t stall; 01041 stg_position_localization_mode_t localization; 01042 } stg_position_data_t; 01043 01045 typedef int stg_position_stall_t; 01046 01048 stg_model_t* stg_position_create( stg_world_t* world, stg_model_t* parent, stg_id_t id, char* token ); 01049 01051 void stg_model_position_set_odom( stg_model_t* mod, stg_pose_t* odom ); 01052 01055 // end the group of all models 01060 // MACROS ------------------------------------------------------ 01061 // Some useful macros 01062 01063 01064 01081 #define PRECISION 100000.0 01082 01084 #define EQ(A,B) ((lrint(A*PRECISION))==(lrint(B*PRECISION))) 01085 01087 #define LT(A,B) ((lrint(A*PRECISION))<(lrint(B*PRECISION))) 01088 01090 #define GT(A,B) ((lrint(A*PRECISION))>(lrint(B*PRECISION))) 01091 01093 #define GTE(A,B) ((lrint(A*PRECISION))>=(lrint(B*PRECISION))) 01094 01096 #define LTE(A,B) ((lrint(A*PRECISION))<=(lrint(B*PRECISION))) 01097 01100 #ifndef TRUE 01101 #define TRUE 1 01102 #endif 01103 01104 #ifndef FALSE 01105 #define FALSE 0 01106 #endif 01107 01108 #define MILLION 1e6 01109 #define BILLION 1e9 01110 01111 #ifndef M_PI 01112 #define M_PI 3.14159265358979323846 01113 #endif 01114 01115 #ifndef TWOPI 01116 #define TWOPI (2.0*M_PI) 01117 #endif 01118 01119 #ifndef RTOD 01120 01121 #define RTOD(r) ((r) * 180.0 / M_PI) 01122 #endif 01123 01124 #ifndef DTOR 01125 01126 #define DTOR(d) ((d) * M_PI / 180.0) 01127 #endif 01128 01129 #ifndef NORMALIZE 01130 01131 #define NORMALIZE(z) atan2(sin(z), cos(z)) 01132 #endif 01133 01134 01135 #ifdef __cplusplus 01136 } 01137 #endif 01138 01139 // end documentation group libstage 01142 #endif
Generated on Thu Aug 11 13:08:10 2005 for Stage by 1.4.0