AutonomousVehicleControlBeginnersGuide
Python sample codes and documents about Autonomous vehicle control algorithm. This project can be used as a technical guide book to study the algorithms and the software architectures for beginners.
翻訳待ち
No updates detected yet. GitHub releases will appear here.
Loading the full README. The saved excerpt is shown below.
App web para crear el hábito de la lectura mediante gamificación. El usuario elige qué días de la semana se compromete a leer y cuida un refugio de perritos. Cada día comprometido que no lee, un perrito se va. Cada sesión de lectura los trae de vuelta, con una curva de recompensa que crece cuanto más larga es la sesión. La idea es que el castigo cree urgencia y la curva ascendente cree el «un bloque más» que alarga la sesión — y que recuperarse siempre sea más rápido que caer.Read the full README ↗
App web para crear el hábito de la lectura mediante gamificación.
El usuario elige qué días de la semana se compromete a leer y cuida un refugio de perritos. Cada día comprometido que no lee, un perrito se va. Cada sesión de lectura los trae de vuelta, con una curva de recompensa que crece cuanto más larga es la sesión.
La idea es que el castigo cree urgencia y la curva ascendente cree el «un bloque más» que alarga la sesión — y que recuperarse siempre sea más rápido que caer.
Todos los números viven en src/lib/game/config.ts,
que es la única fuente de verdad del balance. Si una cifra aparece en otro
sitio, es un error.
Los objetivos de cronómetro (Lectura, Inglés, Estudio) se resuelven midiendo minutos. Salud se resuelve con un sí o un no desde su tarjeta: no tiene cronómetro, no tiene meta en minutos y no responder no cuesta nada.
| Cronómetro | Salud (binario) | |
|---|---|---|
| Cómo se cumple el día | minutos sobre el umbral | botón "No" |
| Qué suma | la curva del tipo | 1 perrito |
| Qué resta | día programado bajo el umbral | botón "Sí" |
| Si no haces nada | pierdes un perrito | nada |
Se calcula sobre los minutos del día, no por sesión: tres sesiones de 7 minutos no valen 0. Cada tipo de objetivo tiene su curva, porque no piden el mismo esfuerzo.
Lectura — umbral 10 min, bloques de 5, ascendente:
| Minutos en el día | 10 | 15 | 20 | 25 | 30 o más |
|---|---|---|---|---|---|
| Perritos | 1 | 2 | 4 | 7 | 11 |
| Gana el bloque | +1 | +1 | +2 | +3 | +4 |
Diez minutos son un hábito que hay que arrancar, así que la curva paga el "un bloque más". A partir de 30 minutos no crece.
Inglés y Estudio — umbral 30 min, bloques de 15, lineal y sin tope:
| Minutos en el día | 29 | 30 | 45 | 60 | 75 | 90 |
|---|---|---|---|---|---|---|
| Perritos | 0 | 1 | 2 | 3 | 4 | 5 |
Media hora ya es una sesión seria: aquí la dificultad está en llegar al umbral, no en estirarlo.
Si el refugio está lleno, los perritos extra pasan a adoptados (marcador histórico) y cada 10 adopciones amplían el aforo en 1, hasta 21.
El umbral de cada curva es también su mínimo de supervivencia: un día comprometido que cierra sin ganar perritos cuesta 1. Salud queda fuera de esto: sus perritos solo se mueven con un clic explícito. Son el mismo número a propósito, para que no puedan contradecirse — con 29 minutos de inglés se pierde un perrito y con 30 no.
Hay dos frenos deliberados:
ceil(7 × 0.6) = 5, así que fallar los siete
días deja el refugio en 2, no en 0.Una sola sesión de 20 minutos de lectura repone cuatro días fallados.
No hay cron. Los días cerrados se liquidan de forma perezosa la próxima vez
que el usuario entra a la app (syncOnVisit). El día en curso nunca se juzga:
siempre se puede salvar.
Cada objetivo tiene un interruptor en su acordeón de /ajustes. En pausa deja de
penalizar, y nada más: conserva sus días comprometidos, su refugio, su racha y su
historial, y lo que se practique sigue dando perritos.
| Pausar | Vaciar los días | Archivar | |
|---|---|---|---|
| ¿Penaliza? | no | no | no |
| ¿Conserva los días configurados? | sí | no, hay que volver a escribirlos | sí |
| ¿Sigue a la vista? | sí, marcado «En pausa» | sí | no, pasa a «Archivados» |
El motor resuelve un día pausado con la misma acción que un día libre, así que no
hubo que inventar reglas nuevas: reconcile deja de llamar a miss. Como
lastReconciledDay avanza igual durante la pausa, al reanudar no queda nada
pendiente que cobrar hacia atrás; /api/goals/[goalId] reconcilia antes de
cambiar la bandera para que eso se cumpla en los dos sentidos.
| Capa | Elección | Por qué |
|---|---|---|
| Framework | Astro 7 (output: 'server') | Islas: React solo donde hay interacción |
| UI | React 19 + Tailwind 4 | |
| Base de datos | MongoDB, driver nativo | Better Auth necesita un Db nativo; mongoose implicaría un segundo pool en serverless |
| Auth | Better Auth + @better-auth/mongo-adapter | Correo + contraseña, sin verificación ni 2FA |
| Gráficas | Recharts | 95 KB gzip, cargado solo en /progreso |
| Despliegue | Vercel |
Requiere Node 24 (engines.node: "24.x"), la misma versión con la que Vercel
construye y ejecuta las funciones. Con otra, npm install avisa EBADENGINE pero
el proyecto funciona.
cp .env.example .env # rellena los valores, SIN comillas
npm install
npm run db:init # crea los 7 índices de MongoDB
npm run dev # http://localhost:4321
⚠️ Los valores del
.envvan sin comillas. El panel de Vercel no limpia lo que pegas: unas comillas dentro del valor hacen quenew URL()lance «Invalid URL» (tumba el build y la autenticación) y que el driver no reconozca el esquemamongodb+srv://. La única excepción es un valor con#o espacios, que sí necesita comillas en el.envlocal, porque dotenv trataría el#como comentario; el código las quita al leer.
This is the beginning of the README. Read the rest at the original. Read the full README ↗