Change font size
It is currently Sun Jul 22, 2018 3:26 pm

Forum rules


{L_IMAGE}



Post a new topicPost a reply Page 1 of 1   [ 2 posts ]
Author Message
 Post subject: ODE Aircraft Script
PostPosted: Fri Jun 10, 2011 2:04 am 
This is the flght script from the Tokyo University of Information Sciences Oar. I worked for me a few times last week with great success but often I find the plane self destroys when you sit in it..maybe avatar gravity has been changed since.. I had found taking off on a prim helped. I wonder if anybody can take a look at it? It certainly has a lot of free flight characteristics not seen before in Opensim. I'll leave a box of the ready made aircraft at Sarahs Creations at wright plaza for anybody that wants to experiment.



Note card to go in root prim
    #
    #
    #

    debug 0
    sim_num 5

    roll 1.4
    yaw 0.8
    up_pitch 1.0
    down_pitch 1.0

    maxSpeed 30
    maxHeight 100
    zeroHeight 27
    stallSpeed 5.0
    boundary 40

    accel 0.04
    up_rate 1.2
    enginePw 1.0
    cruise 0.0

    time_out 180
    red_time 60

{L_CODE}:
///////////////////////////////////////////////////////////
//
//

integer sim_num  = 10;

// Plane Parameter
float roll       = 1.0;
float up_pitch   = 1.0;
float down_pitch = 1.5;
float yaw        = 0.5;

float maxSpeed   = 30.0;
float accel      = 0.2;
float up_rate    = 1.0;
float stallSpeed = 5.0;
float enginePw   = 2.0;
float cruise     = 0.0;

//
integer debug_mode = FALSE;

//
integer time_out = 300;
integer red_time = 60;

//
float boundary_max = 2520.0;
float boundary_min = 50.0;
float boundary_err = 50.0;

float height_zero  = 20.0;
float height_max   = 100.0;
float height_min   = 0.0;
float height_err   = 0.0;

// System Parameter
float dfltdtime = 1.0;
float dtime = 0.0;


//
string  notecard_name = "plane.conf";
key     notecard_key  = NULL_KEY;
integer notecard_line = 0;

integer score_channel = 857;
integer meter_channel = 855;

key     driver = NULL_KEY;

////
float speed    = 0.0;
float acceler  = 0.0;
float height   = 0.0;
float waterlvl = 0.0;
float buoyancy = 0.0;
integer status = 0;




/////////////////////////////////////////////////////////////////////////
// Setting of Initail Parameter and Configuration Faile

init_params()
{
    waterlvl = llWater(ZERO_VECTOR);
    status   = 0;
    speed    = 0.0;
    acceler  = 0.0;
    height   = 0.0;
    buoyancy = 0.0;
}



normalize_params()
{
    if (boundary_err<maxSpeed) boundary_err = maxSpeed;
    boundary_min = boundary_err;
    boundary_max = 255.0*sim_num - boundary_err;
   
    if (debug_mode) {
        llSay(0, "Boundary Min is "+(string)boundary_min + " m");
        llSay(0, "Boundary Max is "+(string)boundary_max + " m");
        llSay(0, "Boundary Err is "+(string)boundary_err + " m");
    }
   
    llSay(score_channel, "RESET " + (string)driver);
    llSay(score_channel, "START " + (string)driver + " " + (string)time_out + " " + (string)red_time);
    llSay(meter_channel, "START " + (string)driver + " " + (string)maxSpeed + " "
                                                         + (string)stallSpeed + " " + (string)(height_max-height_err));
}



read_conf()
{
    llResetTime();

    notecard_line = 0;
    if (llGetInventoryType(notecard_name)==INVENTORY_NOTECARD) {
        notecard_key = llGetNotecardLine(notecard_name, 0);
    }
    else {
        normalize_params();
    }
}



// ノートカードの読み込み
parse_conf_file(string str, integer say)
{
    list   items = llParseString2List(str,["=", ",", " ", "\n"], []);
    string name  = llList2String(items,0);
    string value = llList2String(items,1);

    if (name == "debug") {
        integer flg = (integer)value;
        if (flg>0) {
            debug_mode = TRUE;
            llSay(0, "Debug Mode is ON");
        }
    }
    else if (name == "roll") {
        roll = (float)value;
        if (say) llSay(0, "Roll " + value);
    }
    else if (name == "up_pitch") {
        up_pitch = (float)value;
        if (say) llSay(0, "Up Pitch is " + value);
    }
    else if (name == "down_pitch") {
        down_pitch = (float)value;
        if (say) llSay(0, "Down Pitch is " + value);
    }
    else if (name == "yaw") {
        yaw = (float)value;
        if (say) llSay(0, "Yaw is " + value);
    }
    else if (name == "maxSpeed") {
        maxSpeed = (float)value;
        if (say) llSay(0, "Max Speed is " + value + " m/s");
    }
    else if (name == "maxHeight") {
        height_max = (float)value;
        if (say) llSay(0, "Max Height is " + value + " m");
    }
    else if (name == "zeroHeight") {
        height_zero = (float)value;
        if (say) llSay(0, "Zero Height is " + value + " m");
    }
    else if (name == "accel") {
        accel = (float)value;
        if (say) llSay(0, "Accel Speed is " + value);
    }
    else if (name == "up_rate") {
        up_rate = (float)value;
        if (say) llSay(0, "Up Rate is " + value);
    }
    else if (name == "stallSpeed") {
        stallSpeed = (float)value;
        if (say) llSay(0, "Stall Speed is " + value + " m/s");
    }
    else if (name == "enginePw") {
        enginePw = (float)value;
        if (say) llSay(0, "Engine Power is " + value);
    }
    else if (name == "cruise") {
        cruise = (float)value;
        if (say) llSay(0, "Cruise Rate is " + value);
    }
    else if (name == "sim_num") {
        sim_num = (integer)value;
        if (say) llSay(0, "Number of SIM is " + value);
    }
    else if (name == "boundary") {
        boundary_err = (float)value;
        if (say) llSay(0, "Boundary is " + value + " m");
    }
    else if (name == "time_out") {
        time_out = (integer)value;
        if (say) llSay(0, "Time Limit is " + value + " s");
    }
    else if (name == "red_time") {
        red_time = (integer)value;
        if (say) llSay(0, "Red Zone of Time is " + value + " s");
    }
   
    return;
}




/////////////////////////////////////////////////////////////////////////
// Setting of Physical Parameters

init_physical_param()
{
    llSetVehicleType(VEHICLE_TYPE_AIRPLANE);

    // 力を前方向へ直そうとする強さ
    llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_EFFICIENCY, 1.0);
    llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_TIMESCALE,  0.1);

    // 力のかかる方向に向こうとする強さ
    llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, 0.0);     // 0.0
    llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_TIMESCALE,  10.0);    // 1.0

    // 移動用モーターのタイムスケール
    llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_TIMESCALE, 1.0);            // 0.5     
    llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE, 0.2);      // 20

    // 方向転換用モーターのタイムスケール
    llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_TIMESCALE, 1.0);            // 0.5
    llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, 0.1);      // 3
   
    // 安定性とそのタイムスケール
    llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, 0.5);    // almost wobbly 0.25
    llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_TIMESCALE,  0.5);    // mediocre response 1.5


    llSetVehicleFloatParam(VEHICLE_BANKING_EFFICIENCY, 0.4);    // medium strength
    llSetVehicleFloatParam(VEHICLE_BANKING_TIMESCALE, 0.1);     // very responsive
    llSetVehicleFloatParam(VEHICLE_BANKING_MIX, 0.95);          // more banking when moving

    // very weak friction
    llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE,  <1000.0, 1000.0, 1000.0> );
    llSetVehicleVectorParam(VEHICLE_ANGULAR_FRICTION_TIMESCALE, <1000.0, 1000.0, 1000.0> );

    llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION, <0.0, 0.0, 0.0>);
    llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <0.0, 0.0, 0.0>);
    llSetVehicleFloatParam(VEHICLE_LINEAR_FRICTION_TIMESCALE,  1000.0);
    llSetVehicleFloatParam(VEHICLE_ANGULAR_FRICTION_TIMESCALE, 1000.0);

    dtime = dfltdtime;
    llSetTimerEvent(dtime);
}



reset_physical_param()
{
    llSetTimerEvent(0.0);
         
    // stop the motors
    llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION,  <0.0, 0.0, 0.0>);
    llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION, <0.0, 0.0, 0.0>);

    llSetVehicleFloatParam(VEHICLE_LINEAR_FRICTION_TIMESCALE,  0.0);
    llSetVehicleFloatParam(VEHICLE_ANGULAR_FRICTION_TIMESCALE, 0.0);
   
    llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_EFFICIENCY, 0.0);
    llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, 0.0);
   
    llSetVehicleType(VEHICLE_TYPE_NONE);
}





/////////////////////////////////////////////////////////////////////////
// Debug and HUD support

show_text(string str1, string str2)
{
    vector col = <0.1, 1.0, 1.0>;
   
    if (status==1)      col = <1.0, 1.0, 0.1>;
    else if (status==2) col = <1.0, 0.1, 0.1>;
   
    llSetText(str1 + " : " + str2 + "\n \n \n \n \n \n \n \n \n \n \n \n" , col, 2.0);
}



send_speed_meter(float speed, float height, integer st)
{
    llRegionSay(meter_channel, "DATA " + (string)driver + " " + (string)speed + " " + (string)height + " " + (string)st);
}




/////////////////////////////////////////////////////////////////////////
// Boundary and Over Run

normalize_pos()
{
    vector pos = llGetPos();
   
    if (pos.x<boundary_min)      pos.x = boundary_min + maxSpeed/5;
    else if (pos.x>boundary_max) pos.x = boundary_max - maxSpeed/5;

    if (pos.y<boundary_min)      pos.y = boundary_min + maxSpeed/5;
    else if (pos.y>boundary_max) pos.y = boundary_max - maxSpeed/5;
   
    llSetPos(pos);
}



check_over_run(vector pos)
{   
    if (pos.x<boundary_min || pos.x>boundary_max ||
        pos.y<boundary_min || pos.y>boundary_max ||
        pos.z<0.0          || pos.z>height_max*1.5)
    {
        llShout(0, "CRASHED!!!!");
        llDie();
    }
}



float get_ground_height(vector pos)
{
    //float ground = llGround(ZERO_VECTOR);
    //if (ground<waterlvl) ground = waterlvl;
    //float height = pos.z - ground;
    float height = pos.z - height_zero;
   
    return height;
}



integer get_status(vector pos)
{
    integer status = 0;
   
    if (pos.x<boundary_min+boundary_err || pos.x>boundary_max-boundary_err ||
        pos.y<boundary_min+boundary_err || pos.y>boundary_max-boundary_err || height>height_max*1.2)
    {
        status = 2;     // 境界地付近
        dtime = dfltdtime/10.;
    }
    else if (pos.x<boundary_min+boundary_err*2 || pos.x>boundary_max-boundary_err*2 ||
             pos.y<boundary_min+boundary_err*2 || pos.y>boundary_max-boundary_err*2 ||
             height>height_max-height_err)
    {
        status = 1;      // 強制失速状態
        dtime = dfltdtime/5.;
    }
   
    return status;
}




/////////////////////////////////////////////////////////////////////////
// Control Plane

calc_velocity(integer level)
{
    vector pos = llGetPos();
    check_over_run(pos);

    vector vel = llGetVel();
    speed = llSqrt(vel.x*vel.x+vel.y*vel.y);
   
    if (speed>=maxSpeed*2.0) {
        llShout(0, "Speed Over!!");
        //llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, -vel*llGetRot()/1000.);
        llApplyImpulse(-vel*llGetRot()/10., FALSE);
        vel   = llGetVel();
        speed = llSqrt(vel.x*vel.x+vel.y*vel.y);
    }
   
    float obuoyancy = buoyancy;    // 浮力
    height = get_ground_height(pos);
    dtime  = dfltdtime;
    status = get_status(pos);

       
    if (status==0) {
        if (speed>=stallSpeed) {
            buoyancy = 1.0;
        }
        else if (speed>=stallSpeed/2.) {
            buoyancy = 0.5;
        }
        else {
            buoyancy = 0.0;
        }
        if (obuoyancy!=buoyancy) llSetVehicleFloatParam(VEHICLE_BUOYANCY, buoyancy);
    }
    else {
        buoyancy = 0.5;
        if (obuoyancy!=buoyancy) llSetVehicleFloatParam(VEHICLE_BUOYANCY, buoyancy);

        if (status==2) {
            normalize_pos();
            pos = llGetPos();
        }

        if (status==2 || level==0) {
            vector motor = <0.0, down_pitch, 0.0>;
            vector updwn = <0.0, 0.0, -up_rate*speed*enginePw>;
           
            llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION, motor*llGetRot());
            llApplyImpulse(updwn*llGetRot(), FALSE);
        }
    }
   
   
    // 巡航
    if (level==0 && speed>stallSpeed && status==0) {
        vector updwn = <0.0, 0.0, up_rate*speed*enginePw*cruise>;
        if (speed < maxSpeed) acceler += accel*cruise;
        if (updwn.z!=0.0) llApplyImpulse(updwn*llGetRot(), FALSE);
        if (acceler>0.0)  llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <acceler, 0.0, 0.0>);
    }
   
    // Debug and HUD
    if (debug_mode) show_text((string)speed, (string)height);
    send_speed_meter(speed, height, status);
    return;
}




control_handle(integer level, integer edge)
{
    vector pos = llGetPos();
    height = get_ground_height(pos);
                       
    vector motor = <0.0, 0.0, 0.0>;
    vector updwn = <0.0, 0.0, 0.0>;

    if(level & (CONTROL_RIGHT|CONTROL_ROT_RIGHT))
    {
        motor.x += roll;
        motor.z -= yaw;
    }

    if(level & (CONTROL_LEFT|CONTROL_ROT_LEFT))
    {
        motor.x -= roll;
        motor.z += yaw;
    }

    if (level & CONTROL_FWD)
    {
        motor.y += down_pitch;
        updwn.z -= up_rate*speed;
        if (updwn.z>0.0) updwn.z = -up_rate*speed/5;
    }

    if (level & CONTROL_BACK)
    {
        motor.y -= up_pitch;
        updwn.z += up_rate*speed;
        if (updwn.z<0.0) updwn.z = up_rate*speed/2;
        updwn.z *= enginePw;
    }


    if (status==0)
    {       
        if (level & CONTROL_UP)
        {
            updwn.z += up_rate*speed;
            if (updwn.z<0.0) updwn.z = up_rate*speed;
            updwn.z *= enginePw;
            if (speed < maxSpeed) acceler += accel;
        }
           
        if (level & CONTROL_DOWN)
        {
            //if (speed>stallSpeed || height<2.0) {
                updwn.z -= up_rate*speed;
                if (updwn.z>0.0) updwn.z = -up_rate*speed/2;
                acceler -= accel;
                if (acceler < 0) acceler = 0;
            //}
        }
    }
   
    else if (status==1)
    {       
        if (level & CONTROL_UP)
        {
            if (speed < stallSpeed/2) acceler += accel/5;
            else {
                acceler -= accel/5;
                if (acceler < 0) acceler = 0;
            }
        }
       
        if (level & CONTROL_DOWN)
        {
           acceler -= accel;
           if (acceler<0.0) acceler = 0.0;
        }
    }
   
    else if (status==2)
    {       
        if (level & CONTROL_UP)
        {
            acceler += accel/2;
        }
       
        if (level & CONTROL_DOWN)     
        {
            acceler -= speed;
            if (acceler<0.0) acceler = 0.0;
        }
    }
     
    //
    if (updwn.z!=0.0) llApplyImpulse(updwn*llGetRot(), FALSE);
    llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION, motor*llGetRot());   
    if (acceler>0.0 || speed>0.0) {
        llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <acceler, 0.0, 0.0>);
    }
}





/////////////////////////////////////////////////////////////////////////
// default State

default
{
    // ノートカードが一行読まれる度に発生するイベント
    dataserver(key requested_key, string data)
    {
        if (requested_key == notecard_key ){
            notecard_key = NULL_KEY;
            if (data != EOF){
                parse_conf_file(data, debug_mode);
                notecard_line++;
                notecard_key = llGetNotecardLine(notecard_name, notecard_line);
            }
            else {
                normalize_params();
            }
        }
    }
   
   
   
    state_entry()
    {
        llSetSitText("Ride");
        llCollisionSound("", 0.0);
        llSitTarget(<0.9, 0.00, 0.20>, ZERO_ROTATION); 
        llSetStatus(STATUS_DIE_AT_EDGE, TRUE);
   
        init_params();
    }
   
   
   
    on_rez(integer param)
    {
        llResetScript();
    }



    timer()
    {
        llSetTimerEvent(0.0);
        calc_velocity(0);
        llSetTimerEvent(dtime);
    }
   
   

    changed(integer change)
    {
        if (change & CHANGED_LINK)
        {
            key agent = llAvatarOnSitTarget();
            if (agent!=NULL_KEY)
            {
                read_conf();
               
                driver = agent;
                llMessageLinked(LINK_ALL_CHILDREN, 1, "DRIVER", driver);
                llMessageLinked(LINK_ALL_CHILDREN, 2, "CORE", llGetKey());
               
                llSetStatus(STATUS_ROTATE_Z, FALSE);
                llSetStatus(STATUS_PHYSICS, TRUE);
                init_physical_param();
                llSetStatus(STATUS_ROTATE_Z, TRUE);
               
                llRequestPermissions(agent, PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS | PERMISSION_CONTROL_CAMERA);
                llSay(0, "Ride ON!!");
            }
            else
            {
                // STOP
                vector vel = llGetVel();
                speed = llSqrt(vel.x*vel.x+vel.y*vel.y);
                while(speed!=0.0) {
                    llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, -vel*llGetRot()/100.);
                    vector pos = llGetPos();
                    check_over_run(pos);
                    vel   = llGetVel();
                    speed = llSqrt(vel.x*vel.x+vel.y*vel.y);
                }
               
                llReleaseControls();
                init_params();
                reset_physical_param();
                llSetStatus(STATUS_PHYSICS, FALSE);
               
                llSay(score_channel, "STOP "  + (string)driver);
                llSay(meter_channel, "RESET " + (string)driver);
                llMessageLinked(LINK_ALL_CHILDREN, 9, "STOP", "");
               
                llSay(0, "Ride OFF!!");
                llResetScript();
            }
        }
    }



    run_time_permissions(integer perm)
    {
        if (perm!=0)
        {           
            llClearCameraParams();           
            llSetCameraParams([
                CAMERA_ACTIVE, 1,                       // 1 は有効, 0 は無効
                CAMERA_BEHINDNESS_ANGLE, 30.0,          // (0 ~ 180) 度
                CAMERA_BEHINDNESS_LAG, 0.0,             // (0 ~ 3) 秒
                CAMERA_DISTANCE, 8.0,                   // ( 0.5 ~ 10) メートル
                CAMERA_FOCUS_LAG, 0.0 ,                 // (0 ~ 3) 秒
                CAMERA_FOCUS_LOCKED, FALSE,             // (TRUE または FALSE)
                CAMERA_FOCUS_THRESHOLD, 0.0,            // (0 ~ 4) メートル
                CAMERA_PITCH, 10.0,                     // (-45 ~ 80) 度
                CAMERA_POSITION_LAG, 0.0,               // (0 ~ 3) 秒
                CAMERA_POSITION_LOCKED, FALSE,          // (TRUE または FALSE)
                CAMERA_POSITION_THRESHOLD, 0.0,         // (0 ~ 4) メートル
                CAMERA_FOCUS_OFFSET, <2.0, 0.0, 0.0>    // <-10,-10,-10> ~ <10,10,10> メートル
            ]);

            //
            integer anglControls = CONTROL_RIGHT | CONTROL_LEFT | CONTROL_ROT_RIGHT | CONTROL_ROT_LEFT | CONTROL_DOWN | CONTROL_UP;
            integer lineControls = CONTROL_FWD | CONTROL_BACK;
            llTakeControls(anglControls | lineControls, TRUE, FALSE);
        }
    }



    control(key id, integer level, integer edge)
    {
        llSetTimerEvent(0.0);
        calc_velocity(level);
        control_handle(level, edge);
        llSetTimerEvent(dtime);
    }
}



Top
  
 
 Post subject: Re: ODE Aircraft Script
PostPosted: Sat Nov 19, 2011 3:52 pm 

Joined: Sat Nov 19, 2011 4:29 am
Posts: 5
This is nifty.
I unplumbed all the bounds-checking stuff to stop it from llDie-ing (you could probably just comment out the calls to check_over_run) and glided around for a bit with only a couple of catastrophic aviation accidents.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post a new topicPost a reply Page 1 of 1   [ 2 posts ]


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
610nm Style by Daniel St. Jules of Gamexe.net