Method to return: 1) The structure of the jacobian (if "values" is nullptr) 2) The values of the jacobian (if "values" is not nullptr)
420 {
421 CHECK_EQ(n, num_of_variables_);
422 CHECK_EQ(m, num_of_constraints_);
423
424 if (values == nullptr) {
425 int nz_index = 0;
426
427 int variable_offset = num_of_points_ * 5;
428 for (int i = 0; i + 1 < num_of_points_; ++i) {
429 int variable_index = i * 5;
430
431
432 iRow[nz_index] = i * 2;
433 jCol[nz_index] = variable_index + 0;
434 ++nz_index;
435
436
437 iRow[nz_index] = i * 2;
438 jCol[nz_index] = variable_index + 1;
439 ++nz_index;
440
441
442 iRow[nz_index] = i * 2;
443 jCol[nz_index] = variable_index + 2;
444 ++nz_index;
445
446
447 iRow[nz_index] = i * 2;
448 jCol[nz_index] = variable_index + 3;
449 ++nz_index;
450
451
452 iRow[nz_index] = i * 2;
453 jCol[nz_index] = variable_index + 5;
454 ++nz_index;
455
456
457 iRow[nz_index] = i * 2;
458 jCol[nz_index] = variable_index + 6;
459 ++nz_index;
460
461
462 iRow[nz_index] = i * 2;
463 jCol[nz_index] = variable_index + 7;
464 ++nz_index;
465
466
467 iRow[nz_index] = i * 2;
468 jCol[nz_index] = variable_index + 8;
469 ++nz_index;
470
471
472 iRow[nz_index] = i * 2;
473 jCol[nz_index] = variable_offset + i;
474 ++nz_index;
475
476
477 iRow[nz_index] = i * 2 + 1;
478 jCol[nz_index] = variable_index + 0;
479 ++nz_index;
480
481
482 iRow[nz_index] = i * 2 + 1;
483 jCol[nz_index] = variable_index + 1;
484 ++nz_index;
485
486
487 iRow[nz_index] = i * 2 + 1;
488 jCol[nz_index] = variable_index + 2;
489 ++nz_index;
490
491
492 iRow[nz_index] = i * 2 + 1;
493 jCol[nz_index] = variable_index + 4;
494 ++nz_index;
495
496
497 iRow[nz_index] = i * 2 + 1;
498 jCol[nz_index] = variable_index + 5;
499 ++nz_index;
500
501
502 iRow[nz_index] = i * 2 + 1;
503 jCol[nz_index] = variable_index + 6;
504 ++nz_index;
505
506
507 iRow[nz_index] = i * 2 + 1;
508 jCol[nz_index] = variable_index + 7;
509 ++nz_index;
510
511
512 iRow[nz_index] = i * 2 + 1;
513 jCol[nz_index] = variable_index + 9;
514 ++nz_index;
515
516
517 iRow[nz_index] = i * 2 + 1;
518 jCol[nz_index] = variable_offset + i;
519 ++nz_index;
520 }
521
522 int constraint_offset = 2 * (num_of_points_ - 1);
523 for (int i = 0; i < num_of_points_; ++i) {
524 iRow[nz_index] = constraint_offset + i;
525 jCol[nz_index] = i * 5 + 3;
526 ++nz_index;
527
528 iRow[nz_index] = constraint_offset + i;
529 jCol[nz_index] = i * 5 + 4;
530 ++nz_index;
531 }
532
533 CHECK_EQ(nz_index, nele_jac);
534 } else {
535 if (new_x) {
536 update_piecewise_spiral_paths(x, n);
537 }
538
539 std::fill(values, values + nele_jac, 0.0);
540
541 int nz_index = 0;
542
543 for (int i = 0; i + 1 < num_of_points_; ++i) {
544 int index0 = i * 5;
545 int index1 = (i + 1) * 5;
546
547 auto& spiral_curve = piecewise_paths_[i];
548 double delta_s = spiral_curve.ParamLength();
549
550 double x_diff = x[index1 + 3] - x[index0 + 3] -
551 spiral_curve.ComputeCartesianDeviationX(delta_s);
552 double y_diff = x[index1 + 4] - x[index0 + 4] -
553 spiral_curve.ComputeCartesianDeviationY(delta_s);
554
555 auto pos_theta0 = spiral_curve.DeriveCartesianDeviation(THETA0);
556 auto pos_kappa0 = spiral_curve.DeriveCartesianDeviation(KAPPA0);
557 auto pos_dkappa0 = spiral_curve.DeriveCartesianDeviation(DKAPPA0);
558
559 auto pos_theta1 = spiral_curve.DeriveCartesianDeviation(THETA1);
560 auto pos_kappa1 = spiral_curve.DeriveCartesianDeviation(KAPPA1);
561 auto pos_dkappa1 = spiral_curve.DeriveCartesianDeviation(DKAPPA1);
562
563 auto pos_delta_s = spiral_curve.DeriveCartesianDeviation(DELTA_S);
564
565
566
567 values[nz_index] += 2.0 * x_diff * (-pos_theta0.first);
568 ++nz_index;
569
570
571 values[nz_index] += 2.0 * x_diff * (-pos_kappa0.first);
572 ++nz_index;
573
574
575 values[nz_index] += 2.0 * x_diff * (-pos_dkappa0.first);
576 ++nz_index;
577
578
579 values[nz_index] += 2.0 * x_diff * (-1.0);
580 ++nz_index;
581
582
583 values[nz_index] += 2.0 * x_diff * (-pos_theta1.first);
584 ++nz_index;
585
586
587 values[nz_index] += 2.0 * x_diff * (-pos_kappa1.first);
588 ++nz_index;
589
590
591 values[nz_index] += 2.0 * x_diff * (-pos_dkappa1.first);
592 ++nz_index;
593
594
595 values[nz_index] += 2.0 * x_diff;
596 ++nz_index;
597
598
599 values[nz_index] += 2.0 * x_diff * (-pos_delta_s.first);
600 ++nz_index;
601
602
603
604 values[nz_index] += 2.0 * y_diff * (-pos_theta0.second);
605 ++nz_index;
606
607
608 values[nz_index] += 2.0 * y_diff * (-pos_kappa0.second);
609 ++nz_index;
610
611
612 values[nz_index] += 2.0 * y_diff * (-pos_dkappa0.second);
613 ++nz_index;
614
615
616 values[nz_index] += 2.0 * y_diff * (-1.0);
617 ++nz_index;
618
619
620 values[nz_index] += 2.0 * y_diff * (-pos_theta1.second);
621 ++nz_index;
622
623
624 values[nz_index] += 2.0 * y_diff * (-pos_kappa1.second);
625 ++nz_index;
626
627
628 values[nz_index] += 2.0 * y_diff * (-pos_dkappa1.second);
629 ++nz_index;
630
631
632 values[nz_index] += 2.0 * y_diff;
633 ++nz_index;
634
635
636 values[nz_index] += 2.0 * y_diff * (-pos_delta_s.second);
637 ++nz_index;
638 }
639
640 for (int i = 0; i < num_of_points_; ++i) {
641 values[nz_index] = 2.0 * (x[i * 5 + 3] - init_points_[i].x());
642 ++nz_index;
643
644 values[nz_index] = 2.0 * (x[i * 5 + 4] - init_points_[i].y());
645 ++nz_index;
646 }
647
648 CHECK_EQ(nz_index, nele_jac);
649 }
650 return true;
651}