.:: Bots United ::.

.:: Bots United ::. (http://forums.bots-united.com/index.php)
-   General Bot Coding (http://forums.bots-united.com/forumdisplay.php?f=24)
-   -   Recast / Detour (http://forums.bots-united.com/showthread.php?t=9985)

Neoptolemus 01-09-2015 14:13

Re: Recast / Detour
 
Quote:

Originally Posted by Immortal_BLG (Post 66285)
I think this is because RunPlayerMove receives view angles instead of move angles, which should be oriented same as red line (upwards)...

To traverse ladder:
1) pEdict->v.movetype == MOVETYPE_FLY
2) bot move angles which receives to RunPlayerMove should direct at top of ladder
3) bot forwardSpeed != 0.0
So from this point I think that you have missed something from this...

Sorry for bad english...


Hi Immortal_BLG, thanks for jumping in.

I believe I have met these requirements, however I'll detail the code I'm using to see if you can spot the mistake (don't worry, it's not much code).

My BotThink function looks like this:

Code:

void BotThink(bot_t *pBot)
{
        edict_t *pEdict = pBot->pEdict;


        pEdict->v.flags |= FL_THIRDPARTYBOT;
        pEdict->v.button = 0;

        if (pBot->name[0] == 0)  // name filled in yet?
                strcpy(pBot->name, STRING(pBot->pEdict->v.netname));

        if (pBot->not_started) {
                BotStartGame(pBot);
        }

        // If the bot does not have a path size
        if (pBot->pathSize == 0) {
                // Pick a random point on the navmesh as a destination
                GetRandomPoint(pBot->targetDest);
                // Create the path
                FindPathToPoint(pBot, pBot->targetDest, pBot->currentPath, &pBot->pathSize);
                // Point 0 is usually right at the bot's current position, so jump ahead
                pBot->currentPathPoint = 1;
        }
        else {
                // Determines the bot's forward and side speed
                NextMove(pBot);
        }

        // Updates the bot's view frustum, updates the list of currently visible players and makes the bot look at their current waypoint
        UpdateView(pBot);

        // Adjust msec to command time interval
        byte adjustedmsec = ThrottledMsec(pBot);

        // save the command time
        pBot->f_previous_command_time = gpGlobals->time;

        // This is the ONLY call to pfnRunPlayerMove
        g_engfuncs.pfnRunPlayerMove(pEdict, pEdict->v.v_angle, pBot->y_move_speed,
                pBot->x_move_speed, 0, pEdict->v.button, 0, adjustedmsec);

}

The NextMove function is pretty big as it does a lot of checking of the path and whether the bot is stuck or not, but its ONLY function is to populate pBot->y_move_speed and pBot->x_move_speed. It basically takes the direction the bot needs to move in, uses VecToAngles to work out the orientation in relation to the bot's current rotation and then has an if statement that says "if the bot needs to move diagonally-right then set y_move_speed to maxspeed and x_move_speed to maxspeed", or "if the bot needs to move backwards then set y_move_speed to -maxspeed and x_move_speed to 0" and so on.

The UpdateView function does a bunch of stuff related to the bot's vision, and also makes the bot look its current waypoint:

Code:

void UpdateView(bot_t* pBot) {
        int visibleCount = 0;

        // Updates the view frustum based on the bot's position and v_angle
        UpdateViewFrustrum(pBot);

        memset(pBot->visiblePlayers, 0, sizeof(float) * 32);

        // nextDest is the waypoint the bot is currently moving to
        Vector lookDest = pBot->nextDest.location;

        // Make the bot rotate instantly to look at lookDest
        LookAt(pBot, lookDest);

        // Update list of currently visible players
        for (int i = 0; i < 32; i++) {
                if (clients[i] != NULL) {
                        if (CheckPlayerVisiblity(pBot, clients[i])) {
                                pBot->visiblePlayers[visibleCount++] = clients[i];
                        }
                }
        }

        // Call BotSeePlayer for every visible player each frame. Currently does nothing
        for (int i = 0; i < visibleCount; i++) {
                BotSeePlayer(pBot, pBot->visiblePlayers[i]);
        }
}


and finally the LookAt code is listed here:

Code:

void LookAt(bot_t* pBot, Vector target) {
        edict_t *pEdict = pBot->pEdict;

        Vector viewPos = pBot->pEdict->v.origin + pBot->pEdict->v.view_ofs;
        Vector dir = target - viewPos;
        Vector bot_angles = UTIL_VecToAngles(dir) -pEdict->v.punchangle;

        pEdict->v.idealpitch = bot_angles.x;
        pEdict->v.ideal_yaw = bot_angles.y;
        ClampAngle(pEdict->v.idealpitch);
        ClampAngle(pEdict->v.ideal_yaw);

        pEdict->v.v_angle.x = pEdict->v.idealpitch;
        pEdict->v.v_angle.y = pEdict->v.ideal_yaw;


        pEdict->v.angles.x = pEdict->v.v_angle.x * (1.f / 3.f);
        pEdict->v.angles.y = pEdict->v.v_angle.y;
        pEdict->v.angles.z = pEdict->v.v_angle.z = 0;
}


So every frame, the bot determines which direction it is heading in (i.e. whether it is moving forwards/backwards and strafing left/right) and updates the v_angle and angles to face its current waypoint.

If I view the bot in first person mode as spectator, I can see its looking at the top of the ladder, and I have traces to confirm it is definitely MOVETYPE_FLY, and that it is currently trying to move forwards (the yellow line in the earlier screenshot indicates that y_movement_speed is maxspeed and x_movement_speed is 0 basically).

Not sure what I'm missing here.

The Storm 03-09-2015 12:49

Re: Recast / Detour
 
Did you tried my suggestion to set the *upmove* argument to max speed when the bot hits the ladder? :)

Also I as I see this is a custom map. Could you try to some of the default ones like cs_assault?

Neoptolemus 03-09-2015 13:29

Re: Recast / Detour
 
Quote:

Originally Posted by The Storm (Post 66288)
Did you tried my suggestion to set the *upmove* argument to max speed when the bot hits the ladder? :)

Also I as I see this is a custom map. Could you try to some of the default ones like cs_assault?

Sorry, forgot to mention that I did try the upmove argument but didn't work :( It kind of made the bot walk funny though, at like 2/3 speed.

I'll try a standard map when I get a chance :)

Immortal_BLG 03-09-2015 15:16

Re: Recast / Detour
 
You need to invert the pitch of move angles
Code:

void LookAt(bot_t* pBot, Vector target) {
        edict_t *pEdict = pBot->pEdict;

        Vector viewPos = pBot->pEdict->v.origin + pBot->pEdict->v.view_ofs;
        Vector dir = target - viewPos;
        Vector bot_angles = UTIL_VecToAngles(dir) -pEdict->v.punchangle;

        pEdict->v.idealpitch = bot_angles.x;
        pEdict->v.ideal_yaw = bot_angles.y;
        ClampAngle(pEdict->v.idealpitch);
        ClampAngle(pEdict->v.ideal_yaw);

        pEdict->v.v_angle.x = pEdict->v.idealpitch;
        pEdict->v.v_angle.y = pEdict->v.ideal_yaw;


        pEdict->v.angles.x = pEdict->v.v_angle.x * -(1.f / 3.f); // Adjust the body angle pitch to point the gun correctly. (Invert for engine)
        pEdict->v.angles.y = pEdict->v.v_angle.y;
        pEdict->v.angles.z = pEdict->v.v_angle.z = 0;
}


Neoptolemus 03-09-2015 20:33

Re: Recast / Detour
 
This is really weird.

To rule out the possibility that the bot is looking in the wrong direction, I have am now forcing the bot look directly upwards all the time (v.origin + Vector(0,0,100)) and the bot is still rooted to the floor when touching a ladder.

I had assumed that pEdict->v.v_angles were the view angles, and pEdict->v.angles were the movement angles. However, when I implement your fix for the code, Immortal, the bot looks the wrong way (i.e. he looks at his feet, not upwards). This is both in first and third person. To me this suggests his movement and view angles are both being modified even though the code doesn't do this.

I have tried every possible combination of inputs into pfnRunPlayerMove, including both v.angles and v.v_angle in the second parameter, using the inversion in LookAt and not using it, and setting the upmove parameter to maxspeed.

I really don't get this at all :-(

EDIT: This also happens on official maps, and even if the bot accidentally touches a ladder while moving elsewhere. In other words, they're trying to move AWAY from the ladder, but by accidentally touching the ladder they become completely frozen and unable to move until they die or I restart the round. Seriously, what the hell?

The Storm 04-09-2015 00:25

Re: Recast / Detour
 
Well you derivate from HPB_bot which works well with ladders. It seems like while refactoring you forgot something?

I see this stuff in all HPB_bot derivates:
Code:

v_direction =
        pBot->dest_origin - (pEdict->v.origin +
                            (pEdict->v.velocity *
                              pBot->fTimeFrameInterval));
    Vector vecDirectionNormal = v_direction.Normalize();
    Vector vecDirection = vecDirectionNormal;
    vecDirectionNormal.z = 0.0;

    Vector vecMoveAngles = UTIL_VecToAngles(v_direction);
    vecMoveAngles.x = -vecMoveAngles.x;
    vecMoveAngles.z = 0;
    UTIL_ClampVector(&vecMoveAngles);

Where after additional check if the bot is going up or down a ladder the following code is executed
Code:

if(pBot->bOnLadder || pBot->bInWater)
                {
                        Vector vecViewPos = pEdict->v.origin + pEdict->v.view_ofs;
                       
                        // Check if we need to go forward or back
                        int iAngle = BotInFieldOfView( pBot, pBot->dest_origin - vecViewPos );
                        // Press the correct buttons
                        if(iAngle > 90)
                                pEdict->v.button |= IN_BACK;
                        else
                                pEdict->v.button |= IN_FORWARD;
                        if(pBot->bOnLadder)
                        {
                                // Ladders need view angles pointing up/down
                                if(pBot->ladder_dir == LADDER_UP)
                                {
                                        if(pEdict->v.button & IN_FORWARD)
                                                pEdict->v.v_angle.x = -60;
                                        else
                                                pEdict->v.v_angle.x = 60;
                                }
                                else
                                {
                                        if(pEdict->v.button & IN_FORWARD)
                                                pEdict->v.v_angle.x = 60;
                                        else
                                                pEdict->v.v_angle.x = -60;
                                }
                                pEdict->v.angles.x = -pEdict->v.v_angle.x / 3;
                                vecMoveAngles.x = pEdict->v.v_angle.x;
                        }
                        else
                        {
                                if(vecMoveAngles.x > 60.0)
                                        pEdict->v.button |= IN_DUCK;
                                else if(vecMoveAngles.x < -60.0)
                                        pEdict->v.button |= IN_JUMP;
                        }
                }

And then seems like the the vecAngles variable is only used
Code:

g_engfuncs.pfnRunPlayerMove( pEdict, vecMoveAngles, pBot->f_move_speed,
                pBot->f_sidemove_speed, 0, pEdict->v.button, 0, pBot->msecval);

I really didn't know what exactly is the problem with your code, I don't know the HL engine so well but I guess that it must be something very small that is missing. Keep on trying different variant and check the older code that you had based yours.

SamPlay 04-09-2015 00:47

Re: Recast / Detour
 
hi,
1. I think forwardmove,.., upmove are not in map coordinates but rather in "local" coordinates, with forward= dir. of wished move, ie dir. of look; climbing a ladder requires a positive value for forward speed and upmove=0.
2. bot will not climb if IN_FORWARD button is not set ( a speed!=0 is not enough)
hope this helps.

Immortal_BLG 04-09-2015 01:39

Re: Recast / Detour
 
Yes I forgot to write, you should combine fixed LookAt() function with giving fixed v.angles to RunPlayerMove.
If you already try it, so I don't know what can I advise to check next...
But if you say, that bot tries to move in opposite direction (away from ladder), then something wrong with bot move direction pitch...

Neoptolemus 04-09-2015 21:22

Re: Recast / Detour
 
Quote:

Originally Posted by SamPlay (Post 66293)
hi,
1. I think forwardmove,.., upmove are not in map coordinates but rather in "local" coordinates, with forward= dir. of wished move, ie dir. of look; climbing a ladder requires a positive value for forward speed and upmove=0.
2. bot will not climb if IN_FORWARD button is not set ( a speed!=0 is not enough)
hope this helps.

This was the answer in the end. I changed my nextmove function to also set IN_FORWARD/IN_BACK/IN_MOVELEFT/IN_MOVERIGHT and the bot now climbs the ladder. Great!

The view angles are still messed up though, even though the bot is looking upwards, they climb very slowly as though they're looking dead ahead. If I manually set the bot's angles myself they climb just like a human, so my lookat function is dodgy.

As you guys have suggested, I'll go back through the original HPB bot code to figure it out.

Progress!

Neoptolemus 06-09-2015 00:00

Re: Recast / Detour
 
A screenshot in action, showing the bot getting onto the roof of the warehouse in cs_assault.

https://dl.dropboxusercontent.com/u/...t_Climbing.png

I basically just copied the bot's looking code from the original HPB Bot (the code used to shoot at tripmines). It seems like all is now well, except that the ladder climbing is still not perfect. The bot usually pauses for a second or two at the foot of the ladder before beginning ascent, and still climbs significantly slower than a human, but at least they're doing it reliably now.


All times are GMT +2. The time now is 09:49.

Powered by vBulletin® Version 3.8.2
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.